C++ Boost實現(xiàn)異步端口掃描器詳解
端口掃描是一種用于識別目標系統(tǒng)上哪些網(wǎng)絡端口處于開放、關閉或監(jiān)聽狀態(tài)的網(wǎng)絡活動。在計算機網(wǎng)絡中,端口是一個虛擬的通信端點,用于在計算機之間傳輸數(shù)據(jù)。每個端口都關聯(lián)著特定類型的網(wǎng)絡服務或應用程序。端口掃描通常是網(wǎng)絡管理員、安全專業(yè)人員或黑客用來評估網(wǎng)絡安全的一種方法。通過掃描目標系統(tǒng)的端口,可以了解系統(tǒng)上哪些服務在運行、哪些端口是開放的,從而評估系統(tǒng)的安全性。
常見的端口掃描技術(shù)包括:
- TCP端口掃描: 通過發(fā)送TCP連接請求來確定目標系統(tǒng)上的端口是否開放。常見的TCP掃描包括全連接掃描(Connect Scan)、半開放掃描(SYN Scan)等。
- UDP端口掃描: 通過向目標系統(tǒng)發(fā)送UDP數(shù)據(jù)包,觀察是否收到相應來判斷UDP端口是否開放。UDP掃描較為復雜,因為UDP是一種無連接的協(xié)議,難以確定是否因為端口關閉而未響應。
- NULL、FIN和Xmas Tree掃描: 這些掃描技術(shù)利用TCP協(xié)議的特殊性質(zhì),嘗試向目標系統(tǒng)發(fā)送非法或異常的TCP數(shù)據(jù)包,觀察目標系統(tǒng)的響應。
- IDLE掃描: 利用一個第三方系統(tǒng)(通常是僵尸主機)發(fā)送探測包,通過觀察目標系統(tǒng)的響應來判斷端口狀態(tài)。這種掃描方法更難被目標系統(tǒng)檢測到。
本章我們將運用Boost框架實現(xiàn)一個基于TCP的掃描工具,TCP端口掃描是一種常見的網(wǎng)絡掃描技術(shù),通過發(fā)送TCP連接請求來確定目標系統(tǒng)上的端口是否開放,其本質(zhì)上是通過調(diào)用Socket
套接字中的connect()
嘗試連接對應的端口,如果該端口開放則連接將被建立,由此我們就可以得出該端口是存活的,利用這一特性我們就可以實現(xiàn)批量的端口探測功能。
生成C段地址
C段地址通常指的是IPv4地址中的子網(wǎng)地址,其中C表示了地址的網(wǎng)絡前綴的類別。IPv4地址按照其前綴的長度被分為A、B、C、D和E五個類別,每個類別用于不同規(guī)模的網(wǎng)絡。
在IPv4地址中,每個地址由32位二進制數(shù)字組成,通常以點分十進制(Dotted-Decimal Notation)的形式表示,例如,192.168.0.1。IPv4地址的前面的一部分被分配給網(wǎng)絡,而后面的部分則分配給主機。
- A類地址: 以0開頭,用于大型網(wǎng)絡,例如1.0.0.0到126.0.0.0。
- B類地址: 以10開頭,用于中型網(wǎng)絡,例如128.0.0.0到191.255.0.0。
- C類地址: 以110開頭,用于小型網(wǎng)絡,例如192.0.0.0到223.255.255.0。
因此,當我們說一個IPv4地址屬于C段地址時,通常指的是這個地址的前綴是C類地址的范圍,即以192.x.x.x
到223.x.x.x
的范圍。例如,192.168.1.1
是一個C段地址,因為它的前綴是192。在這樣的地址中,最后三個字節(jié)通常用于主機標識。
同樣我們在實現(xiàn)端口掃描之前需要生成一個C段地址中所有的主機IP,這里我們可以通過Boost庫中的字符串拼接功能來實現(xiàn)生成特定主機網(wǎng)段,具體實現(xiàn)細節(jié)如下所示;
例如192.168.1.1/100
則代表要枚舉出這個網(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 { // 以/,兩個下劃線作為切割符號,切割后放入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 這個范圍內(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
即可實現(xiàn)生成1-100
以內(nèi)的所有IP地址字符串,并將其存儲到address_ref
容器內(nèi),輸出效果如下圖所示;
端口字符串提取
接著我們還需要實現(xiàn)一個提取端口字符串的功能,例如當使用者傳入22,23,135,139
時,我們將其解析成獨立的整數(shù)類型,并將其存儲到std::vector<int>
容器內(nèi)保存,該功能的實現(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ù)可以很容易實現(xiàn)字符串的切割,運行后可看到字符串被解析成了獨立的整數(shù),如下圖所示;
異步端口探測
Boost.Asio是一個強大的C++庫,提供了異步I/O
和網(wǎng)絡編程的支持。本文將介紹如何使用Boost.Asio
實現(xiàn)異步連接,以及如何設置超時機制,確保連接在規(guī)定的時間內(nèi)建立。Asio是Boost
庫中的一個模塊,用于異步I/O
和網(wǎng)絡編程。它提供了一種靈活的方式來處理異步操作,使得程序能夠更高效地利用系統(tǒng)資源。Boost.Asio支持TCP、UDP、SSL
等協(xié)議,使得開發(fā)者能夠輕松實現(xiàn)異步網(wǎng)絡通信。
異步連接實現(xiàn)
在本文的代碼示例中,我們使用Boost.Asio
創(chuàng)建了一個AsyncConnect
類,用于執(zhí)行異步連接。這個類包含了異步連接的主要邏輯,其中使用了tcp::socket
和deadline_timer
來處理異步操作和超時。
#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; // 異步連接,當連接成功后將觸發(fā) connect_handle 函數(shù) socket_.async_connect(ep, boost::bind(&AsyncConnect::connect_handle, this, _1, boost::ref(connect_success))); // 設置一個定時器 million_seconds timer_.expires_from_now(boost::posix_time::milliseconds(million_seconds)); bool timeout = false; // 異步等待 如果超時則執(zhí)行 timer_handle timer_.async_wait(boost::bind(&AsyncConnect::timer_handle, this, _1, boost::ref(timeout))); do { // 等待異步操作完成 io_service_.run_one(); // 判斷如果timeout沒超時,或者是連接建立了,則不再等待 } 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; } } // 定時器超時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)建了一個AsyncConnect
對象,并使用它進行異步連接。這個例子中,我們嘗試連接到IP地址為"202.89.233.101"
,端口號為80
的服務器,并設置了連接超時時間為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),以及超時時間 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)建異步連接,并設置連接超時。異步連接的實現(xiàn)可以提高程序的性能和效率,特別適用于需要處理大量并發(fā)連接的網(wǎng)絡應用場景。Boost.Asio的靈活性使得開發(fā)者能夠更方便地處理異步I/O
操作,提高程序的健壯性和可維護性。
當代碼被運行時,則自動探測特定地址的特定端口是否開放,如果開放則返回如下圖所示;
端口掃描封裝
實現(xiàn)端口掃描
首先增加PortScan
函數(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),以及超時時間 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; }
運行上述代碼即可掃描特定的端口是否開放,輸出效果如下圖所示;
實現(xiàn)特定端口掃描
實現(xiàn)CalculationPort
函數(shù),用戶傳入一串字符串自動解析為端口號,并調(diào)用掃描功能對特定端口進行掃描。
#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)取出需要掃描的端口對目標進行掃描 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): 端口關閉" << std::endl; } } } std::system("pause"); return 0; }
運行上述代碼即可掃描地址192.168.1.1
下的80,443,445,135,139
端口開放狀態(tài),如下圖所示;
增加參數(shù)解析
Boost Program Options 是Boost庫中的一個模塊,用于處理程序的命令行選項。它提供了一個靈活的框架,使得開發(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"), "設置掃描端口") ("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>(); // 判斷是不是默認參數(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)取出需要掃描的端口對目標進行掃描 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): 端口關閉" << std::endl; } } } } } else { std::cout << "參數(shù)錯誤" << std::endl; } return 0; std::system("pause"); return 0; }
當有了命令解析功能,我們就可以向程序內(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; // 實現(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): 關閉" << 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"), "設置掃描端口") ("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>(); // 判斷是不是默認參數(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)取出需要掃描的端口對目標進行掃描 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ù)錯誤" << std::endl; } return 0; std::system("pause"); return 0; }
運行效果如下圖所示,通過使用多線程可提高程序的掃描效率。
完整掃描器代碼
#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; // 異步連接,當連接成功后將觸發(fā) connect_handle 函數(shù) socket_.async_connect(ep, boost::bind(&AsyncConnect::connect_handle, this, _1, boost::ref(connect_success))); // 設置一個定時器 million_seconds timer_.expires_from_now(boost::posix_time::milliseconds(million_seconds)); bool timeout = false; // 異步等待 如果超時則執(zhí)行 timer_handle timer_.async_wait(boost::bind(&AsyncConnect::timer_handle, this, _1, boost::ref(timeout))); do { // 等待異步操作完成 io_service_.run_one(); // 判斷如果timeout沒超時,或者是連接建立了,則不再等待 } 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; } } // 定時器超時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),以及超時時間 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 { // 以/,兩個下劃線作為切割符號,切割后放入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; } // 實現(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): 關閉" << std::endl; } } // 實現(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>(), "設置掃描C地址段 192.168.1.1/24") ("set_port,s", opt::value<std::string>(), "設置掃描端口 80,443,135,139") ("type,t", opt::value<std::string>(), "對特定主機 掃描 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)取出需要掃描的端口對目標進行掃描 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>(); // 計算出需要掃描的端口 std::vector<int> scan_port_list; bool scan_port_ref = CalculationPort(set_port, scan_port_list); // 計算出需要掃描的地址段 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) { // 分別取出每一個IP地址 for (int x = 0; x < scan_address_list.size(); x++) { boost::thread_group group; // 對每一個IP地址中的端口段進行掃描 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ù)錯誤" << std::endl; } return 0; }
至此,一個基于ASIO異步模型的,多線程端口掃描器就這么完成了,總結(jié)幫助手冊。
- 掃描全端口: lyscanner.exe --address 192.168.1.1 --type all
- 掃描整個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實現(xiàn)異步端口掃描器詳解的詳細內(nèi)容,更多關于C++ Boost端口掃描器的資料請關注腳本之家其它相關文章!
相關文章
C++實現(xiàn)LeetCode(168.求Excel表列名稱)
這篇文章主要介紹了C++實現(xiàn)LeetCode(168.求Excel表列名稱),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08C++中Overload,Override,Hide之間的區(qū)別
重載overload,這個概念是大家熟知的。在同一可訪問區(qū)內(nèi)被聲名的幾個具有不同參數(shù)列的(參數(shù)的類型、個數(shù)、順序不同)同名函數(shù),程序會根據(jù)不同的參數(shù)列來確定具體調(diào)用哪個函數(shù),這種機制就是重載2013-09-09

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

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