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

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

  • 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. 正确理解c# default关键字

    背景 最近QA测试一个我开发的一个Web API时,我意识到之前对C#的default的理解一直是想当然的.具体情况是这样,这个API在某些条件下要返回模型的默认值,写法类似于下面这样 [HttpGe ...

  2. HTML5 postMessage 跨域跨窗口传递消息

    父页面代码: <!DOCTYPE html> <html> <head> <title>选择位置demo</title> <meta ...

  3. AtCoder Regular Contest 120 AB题

    比赛链接:Here A - Max Add 观察一下发现每次输出与两点有关,前缀和和当前位置最大值 int main() { cin.tie(nullptr)->sync_with_stdio( ...

  4. Codeforce1343C. Alternating Subsequence

    Recall that the sequence b is a a subsequence of the sequence a if b can be derived from a by removi ...

  5. 报错:for..in loops iterate over the entire prototype chain, which is virtually never what you want.

    for..in loops iterate over the entire prototype chain, which is virtually never what you want. 意思是使用 ...

  6. C#排序算法3:插入排序

    插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的.记录数增1的有序表. 原理: ⒈ 从第一个元素开始,该元素可以认为已经被排序 ⒉ 取出下一个元素,在已 ...

  7. md文件的基本常用编写语法

    md简介 .md即markdown文件的基本常用编写语法,是一种快速标记.快速排版语言,现在很多前段项目中的说明文件readme等都是用.md文件编写的,而且很多企业也在在鼓励使用这种编辑方式.下面就 ...

  8. Navicat平替工具,一款免费开源的通用数据库工具

    前言 前段时间有小伙伴在群里提问说:因为公司不允许使用破解版的Navicat,有好用的Navicat平替工具推荐吗?今天分享一款免费开源的通用数据库工具:DBeaver. 工具介绍 DBeaver是一 ...

  9. 基于html5开发的Win12网页版,抢先体验

    据 MSPoweruser 报道,Windows 11虽然刚刚开始步入正轨,但最新爆料称微软已经在开启下一个计划,Windows 12 的开发将在 去年3 月份开始.德国科技网站 Deskmodder ...

  10. Oracle表结构&数据类型&约束

    1.Oracle 表结构 1.1.创建表名的规范 推荐以"t_xxx" 不能含有"+- "等非法字符,eg:sql create table "t-1 ...