端口扫描是一种用于识别目标系统上哪些网络端口处于开放、关闭或监听状态的网络活动。在计算机网络中,端口是一个虚拟的通信端点,用于在计算机之间传输数据。每个端口都关联着特定类型的网络服务或应用程序。端口扫描通常是网络管理员、安全专业人员或黑客用来评估网络安全的一种方法。通过扫描目标系统的端口,可以了解系统上哪些服务在运行、哪些端口是开放的,从而评估系统的安全性。

常见的端口扫描技术包括:

  • TCP端口扫描: 通过发送TCP连接请求来确定目标系统上的端口是否开放。常见的TCP扫描包括全连接扫描(Connect Scan)、半开放扫描(SYN Scan)等。
  • UDP端口扫描: 通过向目标系统发送UDP数据包,观察是否收到相应来判断UDP端口是否开放。UDP扫描较为复杂,因为UDP是一种无连接的协议,难以确定是否因为端口关闭而未响应。
  • NULL、FIN和Xmas Tree扫描: 这些扫描技术利用TCP协议的特殊性质,尝试向目标系统发送非法或异常的TCP数据包,观察目标系统的响应。
  • IDLE扫描: 利用一个第三方系统(通常是僵尸主机)发送探测包,通过观察目标系统的响应来判断端口状态。这种扫描方法更难被目标系统检测到。

本章我们将运用Boost框架实现一个基于TCP的扫描工具,TCP端口扫描是一种常见的网络扫描技术,通过发送TCP连接请求来确定目标系统上的端口是否开放,其本质上是通过调用Socket套接字中的connect()尝试连接对应的端口,如果该端口开放则连接将被建立,由此我们就可以得出该端口是存活的,利用这一特性我们就可以实现批量的端口探测功能。

生成C段地址

C段地址通常指的是IPv4地址中的子网地址,其中C表示了地址的网络前缀的类别。IPv4地址按照其前缀的长度被分为A、B、C、D和E五个类别,每个类别用于不同规模的网络。

在IPv4地址中,每个地址由32位二进制数字组成,通常以点分十进制(Dotted-Decimal Notation)的形式表示,例如,192.168.0.1。IPv4地址的前面的一部分被分配给网络,而后面的部分则分配给主机。

  • A类地址: 以0开头,用于大型网络,例如1.0.0.0到126.0.0.0。
  • B类地址: 以10开头,用于中型网络,例如128.0.0.0到191.255.0.0。
  • C类地址: 以110开头,用于小型网络,例如192.0.0.0到223.255.255.0。

因此,当我们说一个IPv4地址属于C段地址时,通常指的是这个地址的前缀是C类地址的范围,即以192.x.x.x223.x.x.x的范围。例如,192.168.1.1是一个C段地址,因为它的前缀是192。在这样的地址中,最后三个字节通常用于主机标识。

同样我们在实现端口扫描之前需要生成一个C段地址中所有的主机IP,这里我们可以通过Boost库中的字符串拼接功能来实现生成特定主机网段,具体实现细节如下所示;

  • 例如192.168.1.1/100则代表要枚举出这个网段中所有的地址,并将其存储到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); // 将开始和结束地址取出来
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 这个范围内的地址表
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;
}

上述函数CalculationAddress通过传入范围192.168.1.1/100即可实现生成1-100以内的所有IP地址字符串,并将其存储到address_ref容器内,输出效果如下图所示;

端口字符串提取

接着我们还需要实现一个提取端口字符串的功能,例如当使用者传入22,23,135,139时,我们将其解析成独立的整数类型,并将其存储到std::vector<int>容器内保存,该功能的实现只需要使用boost::split函数切割并循环将数据放入到整数容器内即可,如下所示;

#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中的函数可以很容易实现字符串的切割,运行后可看到字符串被解析成了独立的整数,如下图所示;

异步端口探测

Boost.Asio是一个强大的C++库,提供了异步I/O和网络编程的支持。本文将介绍如何使用Boost.Asio实现异步连接,以及如何设置超时机制,确保连接在规定的时间内建立。Asio是Boost库中的一个模块,用于异步I/O和网络编程。它提供了一种灵活的方式来处理异步操作,使得程序能够更高效地利用系统资源。Boost.Asio支持TCP、UDP、SSL等协议,使得开发者能够轻松实现异步网络通信。

异步连接实现

在本文的代码示例中,我们使用Boost.Asio创建了一个AsyncConnect类,用于执行异步连接。这个类包含了异步连接的主要逻辑,其中使用了tcp::socketdeadline_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; // 异步连接,当连接成功后将触发 connect_handle 函数
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; // 异步等待 如果超时则执行 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_;
};

探测主函数

在主函数中,我们创建了一个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地址结构,以及超时时间
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创建异步连接,并设置连接超时。异步连接的实现可以提高程序的性能和效率,特别适用于需要处理大量并发连接的网络应用场景。Boost.Asio的灵活性使得开发者能够更方便地处理异步I/O操作,提高程序的健壮性和可维护性。

当代码被运行时,则自动探测特定地址的特定端口是否开放,如果开放则返回如下图所示;

端口扫描封装

实现端口扫描

首先增加PortScan函数该函数传入地址端口号以及超时时间,自动扫描端口开放状态,这里我们就以扫描192.168.1.1端口从78-100扫描后将结果输出到屏幕上。

// 封装端口扫描函数
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地址结构,以及超时时间
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 << " 状态: " << is_open << std::endl;
} std::system("pause");
return 0;
}

运行上述代码即可扫描特定的端口是否开放,输出效果如下图所示;

实现特定端口扫描

实现CalculationPort函数,用户传入一串字符串自动解析为端口号,并调用扫描功能对特定端口进行扫描。

#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)
{
// 循环取出需要扫描的端口对目标进行扫描
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] << " 扫描状态: 端口开放" << std::endl;
}
else
{
std::cout << "扫描地址: " << scan_address << " 扫描端口: " << scan_port_list[x] << " 扫描状态: 端口关闭" << std::endl;
}
}
}
std::system("pause");
return 0;
}

运行上述代码即可扫描地址192.168.1.1下的80,443,445,135,139端口开放状态,如下图所示;

增加参数解析

Boost Program Options 是Boost库中的一个模块,用于处理程序的命令行选项。它提供了一个灵活的框架,使得开发者能够轻松地解析和处理命令行参数。

#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); // 无参数直接返回
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>(); // 判断是不是默认参数
if (address == "127.0.0.1" || set_port == "none")
{
std::cout << des_cmd << std::endl;
}
else
{
// 执行扫描流程
std::vector<int> scan_port_list; bool scan_ref = CalculationPort(set_port, scan_port_list);
if (scan_ref == true)
{
// 循环取出需要扫描的端口对目标进行扫描
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] << " 扫描状态: 端口开放" << std::endl;
}
else
{
std::cout << "扫描地址: " << address << " 扫描端口: " << scan_port_list[x] << " 扫描状态: 端口关闭" << std::endl;
}
}
}
}
}
else
{
std::cout << "参数错误" << 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 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 << " 扫描状态: 开放" << std::endl;
}
else
{
std::cout << "扫描地址: " << address << " 扫描端口: " << port << " 扫描状态: 关闭" << 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); // 无参数直接返回
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>(); // 判断是不是默认参数
if (address == "127.0.0.1" || set_port == "none")
{
std::cout << des_cmd << std::endl;
}
else
{
// 执行扫描流程
std::vector<int> scan_port_list; bool scan_ref = CalculationPort(set_port, scan_port_list);
if (scan_ref == true)
{
boost::thread_group group;
// 循环取出需要扫描的端口对目标进行扫描
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 << "参数错误" << 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; // 异步连接,当连接成功后将触发 connect_handle 函数
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; // 异步等待 如果超时则执行 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_;
}; // 封装端口扫描函数
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地址结构,以及超时时间
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); // 将开始和结束地址取出来
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;
} // 实现多线程扫描
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 << " 扫描状态: 开放" << std::endl;
}
else
{
std::cout << "扫描地址: " << address << " 扫描端口: " << port << " 扫描状态: 关闭" << std::endl;
}
} // 实现全端口线程扫描
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 << " 扫描状态: 开放" << 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); // 无参数直接返回
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")
{
// 执行全端口扫描
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>(); // 执行特定端口扫描
std::vector<int> scan_port_list; bool scan_ref = CalculationPort(set_port, scan_port_list);
if (scan_ref == true)
{
boost::thread_group group;
// 循环取出需要扫描的端口对目标进行扫描
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 << "参数错误" << std::endl;
}
return 0;
}

至此,一个基于ASIO异步模型的,多线程端口扫描器就这么完成了,总结帮助手册。

  • 扫描全端口: 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 实现异步端口扫描器的更多相关文章

  1. 3. Port scanners (端口扫描器 4个)

    3. Port scanners (端口扫描器 4个) 愤怒的IP扫描器是一个小的开源Java应用程序,它执行主机发现(“ping扫描”)和端口扫描. 旧的2.x版本只有Windows,但是,新的3. ...

  2. Python3实现TCP端口扫描器

    本文来自 高海峰对 玄魂工作室 的投稿 作者:高海峰 QQ:543589796 在渗透测试的初步阶段通常我们都需要对攻击目标进行信息搜集,而端口扫描就是信息搜集中至关重要的一个步骤.通过端口扫描我们可 ...

  3. Python与Hack之window下运行带参数的Python脚本,实现一个简单的端口扫描器

    1.前提是:windows已经配置好Python的环境变量: 2.进入cmd命令行模式: **输入python命令,检测是否环境配置好:显示这样说明配置环境变量没问题 **用cd命令进入Python脚 ...

  4. 端口扫描器——ZenmapKail Linux渗透测

    3.3  端口扫描器——ZenmapKail Linux渗透测​ Zenmap(端口扫描器)是一个开放源代码的网络探测和安全审核的工具.它是Nmap安全扫描工具的图形界面前端,它可以支持跨平台.使用Z ...

  5. 达内培训:php在线端口扫描器

    达内培训:php在线端口扫描器 [来源] 达内    [编辑] 达内   [时间]2012-12-21 这个扫描器很简单.就是用了一个数组来定义端口的相关信息,原理就是用fsockopen函数连接,如 ...

  6. java编写一个端口扫描器

    好久没写java了,学的时候,也没学习网络编程这一块,无意中看到了一本书,于是小小复习一下java,写个端口扫描器,玩玩吧,网上这种小公具有的是,就是自己无聊写着玩玩. 源代码如下: 共两个类,比较简 ...

  7. 『Python』 多线程 端口扫描器

    0x 00 Before Coding 当端口打开时,向端口发送 TCP SYN 请求,会返回一个 ACK 响应: 当端口关闭,返回的是 RST 响应: 0x 01 Coding  可以用 socke ...

  8. mac/unix系统:C++实现一个端口扫描器

    在比较早以前,我用过S扫描器, 以及大名鼎鼎的nmap扫描器, 可以快速扫描某个主机开放的端口, 今天使用C实现这样一个软件, 编译环境为Mac, 系统版本10.11.6: #include < ...

  9. 【技术分享】手把手教你使用PowerShell内置的端口扫描器

    [技术分享]手把手教你使用PowerShell内置的端口扫描器 引言 想做端口扫描,NMAP是理想的选择,但是有时候NMAP并不可用.有的时候仅仅是想看一下某个端口是否开放.在这些情况下,PowerS ...

  10. python端口扫描器

    吃了个火鸡面后感觉到了怀疑人生!!!!!!!!!妈耶,在也不吃了.思路都给辣没了!!! python端口扫描器代码如下: #-*-coding:utf-8 from socket import * i ...

随机推荐

  1. selenium 开源UI测试工具

    简介 selenium是一个用于Web应用程序测试的工具.selenium测试直接运行于浏览器网页上,可以模拟用户操作网页.支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Fi ...

  2. JS 实现 HashMap

    HashMap代码(这种实现方式是错误的,错误原因:代码中_map._length变量是HashMap的所有实例共用的): /** * HashMap * 2021年09月09日 */ (functi ...

  3. #2066:一个人的旅行(Dijkstra算法入门题)

    一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  4. JSP | JSP 动作详解

    原作者为 RioTian@cnblogs, 本作品采用 CC 4.0 BY 进行许可,转载请注明出处. 本篇学习自:C语言中文网,部分内容转载仅供学习使用. \[QAQ \] JSP 动作利用 XML ...

  5. scroll-view横向滚动的问题

    最近在做一个小程序的项目,在写demo的时候,需要用到scroll-view来实现横向滚动的效果: 按照官方文档来写简直坑到家了,正确的写法如下: <scroll-view scroll-x=& ...

  6. vscode如何优雅的拥抱eslint

    https://www.toutiao.com/a6826129210260587019/?tt_from=weixin&utm_campaign=client_share&wxsha ...

  7. 黑池舞蹈节banner

  8. sipp3.6分支压测方案

    概述 SIP压测工具sipp,免费,开源,功能足够强大,配置灵活,优点多. 本文档介绍sipp工具的常用参数和测试脚本. 环境 centos7.9 sipp v3.6.2_rc1 常用参数 -sf 加 ...

  9. [转帖]Jmeter学习笔记(十)——元件的作用域和执行顺序

    https://www.cnblogs.com/pachongshangdexuebi/p/11582891.html jmeter是一个开源的性能测试工具,它可以通过鼠标拖拽来随意改变元件之间的顺序 ...

  10. Oracle 核心列信息查看与处理

    Oracle 核心列信息查看与处理 背景 最近想对数据库表进行跨数据之间的比照 因为有一些自增列或者是时间戳的列不需要进行对比 后者是对比容易导致失真. 所以就准备选用其他方式进行一下处理. 本文主要 ...