Linux下C/C++ 网络扫描(主机扫描技术)
主机扫描是网络扫描的基础,通过对目标网络中主机IP地址的扫描,从一堆主机中扫描出存活的主机,然后以他们为目标进行后续的攻击。一般会借助于ICMP、TCP、UDP等协议的工作机制,检查打开的进程,开放的端口号等等。
主机扫描
主机扫描是在可达状态下检测,局域网下的 ARP 扫描和广域网下的 ICMP Echo 扫描、ICMP Sweep 扫描、ICMP Broadcast 扫描、ICMP Non-Echo 扫描都是基本的扫描技术。还有绕过防火墙和网络过滤设备的高级技术。
- ARP 扫描
向目标主机所在的局域网发送 ARP 广播请求,在局域网连通状态下目标主机必定会响应正常的 ARP 广播请求。故而便可获得IP地址和 MAC 地址等信息。
...
int convertNetworkAddr(const char *inString,uint8_t outNetAddr[PROTOCOL_ADDRESS_LENGTH],uint8_t *netPrefix)
{char *invalidCharPtr;// 读取3个八位字节for (int i = 0; i < PROTOCOL_ADDRESS_LENGTH - 1; ++i) {unsigned long octet = strtoul(inString, &invalidCharPtr, 10);if (octet >= 256 || *invalidCharPtr != '.') {return 1;}inString = invalidCharPtr + 1;outNetAddr[i] = (uint8_t) octet;}// 读取最后一个八位字节unsigned long octet = strtoul(inString, &invalidCharPtr, 10);if (octet >= 256 || *invalidCharPtr != '/') {return 1;}inString = invalidCharPtr + 1;outNetAddr[PROTOCOL_ADDRESS_LENGTH - 1] = octet;unsigned long prefix = strtoul(inString, &invalidCharPtr, 10);if (prefix > 32 || invalidCharPtr == inString) {return 1;}*netPrefix = prefix;// 按位AND ip地址和网络掩码uint8_t hostPartLength = PROTOCOL_ADDRESS_LENGTH * 8 - prefix;for (int j = 0; j < hostPartLength / 8; ++j) {outNetAddr[PROTOCOL_ADDRESS_LENGTH - 1 - j] = 0x00;}if (hostPartLength % 8) {uint8_t mask = (0xFF >> hostPartLength % 8) << hostPartLength % 8;outNetAddr[PROTOCOL_ADDRESS_LENGTH - hostPartLength / 8 - 1] &= mask;}return 0;
}
...
void printPacket(struct ArpPacket *p)
{for (int i = 0; i < sizeof(struct ArpPacket); ++i) {int c = *((char*)p+i) & 0xFF;printf("%2x ", c);if (i%8 == 7)printf("\n");}printf("\n");
}int readNetworkAddr(const char *string,uint8_t dstAddr[PROTOCOL_ADDRESS_LENGTH],uint8_t *dstPrefix)
{if (convertNetworkAddr(string, dstAddr, dstPrefix)) {fprintf(stderr, "Cannot recognize network address from: %s\n", string);exit(1);}DEBUG(printf("========= RECOGNIZED NETWORK ADDRESS ===========\n");printf("IP address: ");for (int j = 0; j < PROTOCOL_ADDRESS_LENGTH; ++j) {printf("%i ", (int)dstAddr[j]);}printf("\nNet prefix: %i\n", (int)(*dstPrefix) );)
}int main(int argc, char **argv)
{
...if (argc != 3) {fprintf(stderr, "Usage: <interface name> <network address>.\n""For example: scan eth0 192.168.0.1/24\n");return 1;}// 打开套接字int s = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP));if (s == -1) {perror("Error in opening socket: ");return 1;}// 读取网络地址uint8_t netAddr[PROTOCOL_ADDRESS_LENGTH];uint8_t netPrefix;readNetworkAddr(argv[2], netAddr, &netPrefix);DEBUG(setHostPart(netAddr, 255, 8);printf("IP address: ");for (int j = 0; j < PROTOCOL_ADDRESS_LENGTH; ++j) {printf("%i ", (int)netAddr[j]);}printf("\n");)struct sockaddr_ll addr;prepareSockaddrll(&addr, argv[1]);struct ArpPacket packet;prepareArpPacket(&packet, &addr, argv[1]);DEBUG(printf("Packet hex dump: \n");printPacket(&packet);)for (int i = 1; i < powl(2, (32 - netPrefix) ) - 1; ++i) {setHostPart(netAddr, i, 32 - netPrefix);setDstIP(netAddr, &packet);DEBUG(printf("Sending ARP request to IP ");printIP(netAddr, stdout);printf(" ..............");)if(sendto(s, &packet, sizeof(packet), 0,(struct sockaddr*) &addr, sizeof(addr)) == -1) {perror("Error in sending ARP request: ");fprintf(stderr, "Error in sending ARP request: %s\n", strerror(errno));return 1;}DEBUG(printf("[ DONE ]\n");)// waiting for responseusleep(200);struct ArpPacket response;ssize_t receivedResponseSize;if (receivedResponseSize = recv(s, &response, sizeof(response), MSG_DONTWAIT | MSG_TRUNC) > 0) {DEBUG(printf("Received %ld bytes of response: \n", (long) receivedResponseSize);printPacket(&response);)if (memcmp(response.senderLogicAddress, packet.senderLogicAddress, sizeof(packet.senderLogicAddress))) {printf("IP ");printIP(response.senderLogicAddress, stdout);printf(" has MAC: ");for (int j = 0; j < HARDWARE_ADDRESS_LENGTH; ++j) {printf("%x:", (int)response.senderHardwareAddress[j]);}printf("\n");}}}return 0;
}
运行结果:

If you need the complete source code, please add the WeChat number (c17865354792)
tcpdump抓包


- ICMP Echo 扫描
向目标主机发送ICMP Echo Request (type 8)数据包,等待回复的ICMP Echo Reply 包(type 0) 。如果能收到,则表明目标系统可达,否则表明目标系统已经不可达或发送的包被对方的设备过滤掉。
...
/*
获取网络接口的本地信息。*/
int loadLocalData( LocalData *dst, const char *ifname )
{struct ifreq nic;int sock = socket( AF_INET, SOCK_DGRAM, 0 );strncpy( nic.ifr_name, ifname, IFNAMSIZ-1 );nic.ifr_name[IFNAMSIZ-1] = '\0';if( ioctl( sock, SIOCGIFINDEX, &nic ) < 0 ){close( sock );return -1;}dst->ifindex = nic.ifr_ifindex;// 分配的IP地址if( ioctl( sock, SIOCGIFADDR, &nic ) < 0 ){close( sock );return -1;}memcpy( &dst->ip, nic.ifr_addr.sa_data + 2, INET_ALEN );// MAC地址 if( ioctl( sock, SIOCGIFHWADDR, &nic ) < 0 ){close( sock );return -1;}memcpy( &dst->mac, nic.ifr_hwaddr.sa_data, ETH_ALEN );// 子网掩码if( ioctl( sock, SIOCGIFNETMASK, &nic ) < 0 ){close( sock );return -1;}memcpy( &dst->netmask, nic.ifr_netmask.sa_data + 2, INET_ALEN ); close( sock );return 0;
}/*** 为特定协议创建套接字。*/
int createSocket( SocketType type, int msecs )
{int sfd;struct timeval timer;if( type == ICMPSocket )sfd = socket( AF_INET, SOCK_RAW, IPPROTO_ICMP );elsesfd = socket( AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP) );if( sfd < 0 )return -1;// 设置接收数据的最大时间timer.tv_sec = msecs / 1000;timer.tv_usec = msecs % 1000 * 1000;if( setsockopt( sfd, SOL_SOCKET, SO_RCVTIMEO, &timer, sizeof(timer) ) < 0 ){close( sfd );return -1;}return sfd;
}
.../*** 计算增加一个IP地址的结果。*/
struct in_addr ipAddOne( struct in_addr ip )
{struct in_addr aux = { ntohl( ip.s_addr ) };aux.s_addr++;aux.s_addr = htonl( aux.s_addr );return aux;
}/*** 交换两个IP地址的值*/
void ipSwap( struct in_addr *a, struct in_addr *b )
{a->s_addr = a->s_addr ^ b->s_addr; b->s_addr = a->s_addr ^ b->s_addr;a->s_addr = a->s_addr ^ b->s_addr;
}
...int main( int argc, char **argv )
{
...// 验证接口if( !interface ){fprintf( stderr, "Error: No interface given. Use -h for help\n" );return -1;}// 加载本地数据if( loadLocalData( &data, interface ) < 0 ){perror( interface );return -1;}// 验证是否有特定的IP if( strFirst ){if( !inet_aton( strFirst, &first ) ){fprintf( stderr, "%s: Invalid address\n", strFirst );return -1;}if( strLast ){ // 验证是否有范围if( !inet_aton( strLast, &last ) ){fprintf( stderr, "%s: Invalid address\n", strLast );return -1;}else{total = ntohl( last.s_addr ) - ntohl( first.s_addr );if( total < 0 ){total = -total;ipSwap( &first, &last );}total++;}}else{total = 1;}}else{ // 如果没有,则从本地网络数据中获取范围。first.s_addr = data.ip.s_addr & data.netmask.s_addr;first = ipAddOne( first );last.s_addr = data.ip.s_addr | ~data.netmask.s_addr;total = ntohl( last.s_addr ) - ntohl( first.s_addr );}// 创建套接字if( (sfd = createSocket( type, waitTime ) ) < 0 ){perror( "Failed to create socket" );return 2;}...// 扫描周期for( int i = 1 ; i <= total && running ; i++, first = ipAddOne(first) ){printf( "\r(%d%%) Testing %s...", (int)(100.0 / total * i), inet_ntoa(first) );fflush( stdout );if( first.s_addr == data.ip.s_addr ){printf( " (this host)\n" );ups++;}else{switch( isUp(sfd, first, &data) ){case -1:perror( " send request" );break;case 1:puts( " is up" );ups++;}}}close( sfd );printf( "\n%d hosts up\n", ups );return 0;
}
运行结果:

If you need the complete source code, please add the WeChat number (c17865354792)
tcpdump抓包:


- ICMP Sweep 扫描


总结
这里我们就知道了其实主机扫描很简单,只需要证明其主机存活就好。我们只需要对目标主机发送特定的数据包,如果目标主机有回应,那么我们就认为该主机是存活的;反之如果对方不回应,我们就认为其不是存活主机。
Welcome to follow WeChat official account【程序猿编码】
相关文章:
Linux下C/C++ 网络扫描(主机扫描技术)
主机扫描是网络扫描的基础,通过对目标网络中主机IP地址的扫描,从一堆主机中扫描出存活的主机,然后以他们为目标进行后续的攻击。一般会借助于ICMP、TCP、UDP等协议的工作机制,检查打开的进程,开放的端口号等等。 主机…...
无法将“vue-cli-service”项识别为 cmdlet、函数、脚本文件或不是内部命令的原因和解决方案
经常有小伙伴问我说,为什么我们在开发vue项目的时候,需要在package.json的script对象中,去设置命令启动项目,而不是直接的通过"vue-cli-service serve"命令去把项目跑起来。带着这些疑问,小生在此总结了以下…...
逆流程 场景下 处理状态机变化的方案
背景: 针对某些业务场景下,存在逆流程。 比如场景的场景 正向流程如,发起某项申请->对某项申请进行审批。(审批为通过/驳回)。这样这个工作流程就算到最终态。 常见的状态机如, 申请未提交࿰…...
【剧前爆米花--爪哇岛寻宝】Java实现无头单向非循环链表和无头双向链表与相关题目
作者:困了电视剧 专栏:《数据结构--Java》 文章分布:这是关于数据结构链表的文章,包含了自己的无头单向非循环链表和无头双向链表实现简单实现,和相关题目,想对你有所帮助。 目录 无头单向非循环链表实现 …...
学习MvvmLight工具
最近学习了一下MvvmLight,觉得有些功能还是挺有特色的,所以记录一下 首先新建也给WPF程序 然后在Nuget里面安装MvvmLightLib 包,安装上面那个也可以,但是安装上面那个会自动在代码里面添加一些MvvmLight的demo ,安装M…...
基于BiLSTM+CRF医学病例命名实体识别项目
研究背景 为通过项目实战增加对命名实体识别的认识,本文找到中科院软件所刘焕勇老师在github上的开源项目,中文电子病例命名实体识别项目MedicalNamedEntityRecognition。对其进行详细解读。 原项目地址:https://github.com/liuhuanyong/Med…...
05 C语言数据类型
05 C语言数据类型 1、数据类型 编程语言对数据类型分为两派:一种认为要注重,一种认为可以忽视。 C语言类型 1、整数 : char < short < int < long < long long ,bool 2、浮点数:float < double < long doub…...
C++11:右值引用和移动语义
文章目录1. 左值和右值表达式1.1 概念1.2 左值和右值2. 左值引用和右值引用2.1 相互引用2.2 示例代码2.3 左值引用使用场景缺点2.4 右值引用和移动语义小结2.5 移动赋值2.6 右值引用的其他使用场景右值引用版本的插入函数3. 完美转发3.1 万能引用3.2 如何实现完美转发3.3 完美转…...
tcpdump网络抓包工具
tcpdump 是一个强大的网络抓包工具,在分析服务之间调用时非常有用。可以将网络中传送的数据包抓取下来进行分析。tcpdump 提供灵活的抓取策略,支持针对网络层、协议、主机、网络或端口的过滤,并提供 and、or、not 等逻辑语句来去掉不想要的信…...
MaxCompute SQL中的所有保留字与关键字如下
– MaxCompute SQL中的所有保留字与关键字如下 注意 命名表、列或分区时,不要使用保留字与关键字,否则可能会报错。 保留字不区分大小写。 在对表、列或是分区命名时如若使用关键字,需给关键字加符号进行转义,否则会报错。 % &am…...
Kafka 压缩算法
压缩 (compression) : 用时间换空间的思想 用较小的 CPU 开销获得磁盘少占用或网络 I/O 少传输 Kafka 消息分两层: 消息日志组成 : n 个消息集合消息集合 (message set) 组成 : n 条日志项 (record item)日志项封装了消息 (message)Kafka 在消息集合层上进行写入…...
关于React Hook(18)
useState():👉详情 (必须“有条件地调用”;注意避免冗余状态的产生) 关于useState的两种使用方式的区别:👉详情 关于batch机制:有条件地调用一些状态的set方…...
计算机网络:BGP协议
BGP协议 与其他AS的邻站BPG发言人交换信息。 交换的网络可达性信息,即要到达某一个网络所要经历的一系列AS 发生变化时,更新有变化的部分 BGP协议交换信息的过程:所交换的网络可达性信息就是要到达某一个网络所要经历的一系列ASÿ…...
91. 解码方法 ——【Leetcode每日刷题】
91. 解码方法 一条包含字母 A-Z 的消息通过以下映射进行了 编码 : ‘A’ -> “1” ‘B’ -> “2” … ‘Z’ -> “26” 要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法࿰…...
人体存在传感器成品方案,精准感知静止存在,实时智能化感控技术
随着现今智能时代的发展,酒店也越来越趋于智能化,也在不断地推行智慧酒店,这也给人们入住酒店提供了良好的体验。 人体存在感知是智能酒店中极其重要的一项应用技术,只有智能设备通过精准地感知人体存在,才能更好地做…...
mysql连接池的实现
目录 1 池化技术 2 什么是数据库连接池 3 为什么使用数据库连接池 3.1 不使用连接池 3.2 使用连接池 3.3 长连接和连接池的区别 4 数据库连接池运行机制 5 连接池和线程池的关系 6 线程池设计要点 6.1 连接池设计逻辑 构造函数 初始化 请求获取连接 归还连接 析…...
哪种类型蓝牙耳机佩戴最舒服?舒适度最好的蓝牙耳机推荐
如果您想在外出时听自己喜欢的音乐,您需要佩戴耳机,当前的耳机都足够小,可以将它们放在口袋里,即使它们在充电盒中也是如此,舒适度一直都是人们所追求的,舒适之余,佩戴同样稳固更加令人安心&…...
2020蓝桥杯真题洁净数 C语言/C++
题目描述 小明非常不喜欢数字 2,包括那些数位上包含数字 2 的数。如果一个数的数位不包含数字 2,小明将它称为洁净数。 请问在整数 1 至 n 中,洁净数有多少个? 输入描述 输入的第一行包含一个整数 n(1≤n≤10^6)。 输出描述 输…...
【随笔二】useReducer详解及其应用场景
前言 useReducer 实际上是 useState 的升级版,都是用来存储和更新 state,只是应用的场景不一样。 一般情况下,我们使用 useState 就足够项目需要了,不多当遇到以下场景时,使用useReducer 会更好些 。 状态逻辑复杂&…...
打怪升级之istringstream介绍
istringstream类 istringstream本质不是类,是一个宏,或者说是一个流: typedef basic_istringstream<char> istringstream;istringstream从basic_istringstream的char专用项而来。这一部分让人看得摸不着头脑的原因是因为大量使用了st…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
