当前位置: 首页 > news >正文

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++ 网络扫描(主机扫描技术)

主机扫描是网络扫描的基础&#xff0c;通过对目标网络中主机IP地址的扫描&#xff0c;从一堆主机中扫描出存活的主机&#xff0c;然后以他们为目标进行后续的攻击。一般会借助于ICMP、TCP、UDP等协议的工作机制&#xff0c;检查打开的进程&#xff0c;开放的端口号等等。 主机…...

无法将“vue-cli-service”项识别为 cmdlet、函数、脚本文件或不是内部命令的原因和解决方案

经常有小伙伴问我说&#xff0c;为什么我们在开发vue项目的时候&#xff0c;需要在package.json的script对象中&#xff0c;去设置命令启动项目&#xff0c;而不是直接的通过"vue-cli-service serve"命令去把项目跑起来。带着这些疑问&#xff0c;小生在此总结了以下…...

逆流程 场景下 处理状态机变化的方案

背景&#xff1a; 针对某些业务场景下&#xff0c;存在逆流程。 比如场景的场景 正向流程如&#xff0c;发起某项申请->对某项申请进行审批。&#xff08;审批为通过/驳回&#xff09;。这样这个工作流程就算到最终态。 常见的状态机如&#xff0c; 申请未提交&#xff0…...

【剧前爆米花--爪哇岛寻宝】Java实现无头单向非循环链表和无头双向链表与相关题目

作者&#xff1a;困了电视剧 专栏&#xff1a;《数据结构--Java》 文章分布&#xff1a;这是关于数据结构链表的文章&#xff0c;包含了自己的无头单向非循环链表和无头双向链表实现简单实现&#xff0c;和相关题目&#xff0c;想对你有所帮助。 目录 无头单向非循环链表实现 …...

学习MvvmLight工具

最近学习了一下MvvmLight&#xff0c;觉得有些功能还是挺有特色的&#xff0c;所以记录一下 首先新建也给WPF程序 然后在Nuget里面安装MvvmLightLib 包&#xff0c;安装上面那个也可以&#xff0c;但是安装上面那个会自动在代码里面添加一些MvvmLight的demo &#xff0c;安装M…...

基于BiLSTM+CRF医学病例命名实体识别项目

研究背景 为通过项目实战增加对命名实体识别的认识&#xff0c;本文找到中科院软件所刘焕勇老师在github上的开源项目&#xff0c;中文电子病例命名实体识别项目MedicalNamedEntityRecognition。对其进行详细解读。 原项目地址&#xff1a;https://github.com/liuhuanyong/Med…...

05 C语言数据类型

05 C语言数据类型 1、数据类型 编程语言对数据类型分为两派&#xff1a;一种认为要注重&#xff0c;一种认为可以忽视。 C语言类型 1、整数 : char < short < int < long < long long &#xff0c;bool 2、浮点数&#xff1a;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 是一个强大的网络抓包工具&#xff0c;在分析服务之间调用时非常有用。可以将网络中传送的数据包抓取下来进行分析。tcpdump 提供灵活的抓取策略&#xff0c;支持针对网络层、协议、主机、网络或端口的过滤&#xff0c;并提供 and、or、not 等逻辑语句来去掉不想要的信…...

MaxCompute SQL中的所有保留字与关键字如下

– MaxCompute SQL中的所有保留字与关键字如下 注意 命名表、列或分区时&#xff0c;不要使用保留字与关键字&#xff0c;否则可能会报错。 保留字不区分大小写。 在对表、列或是分区命名时如若使用关键字&#xff0c;需给关键字加符号进行转义&#xff0c;否则会报错。 % &am…...

Kafka 压缩算法

压缩 (compression) : 用时间换空间的思想 用较小的 CPU 开销获得磁盘少占用或网络 I/O 少传输 Kafka 消息分两层&#xff1a; 消息日志组成 : n 个消息集合消息集合 (message set) 组成 : n 条日志项 (record item)日志项封装了消息 (message)Kafka 在消息集合层上进行写入…...

关于React Hook(18)

useState&#xff08;&#xff09;&#xff1a;&#x1f449;详情 &#xff08;必须“有条件地调用”&#xff1b;注意避免冗余状态的产生&#xff09; 关于useState的两种使用方式的区别&#xff1a;&#x1f449;详情 关于batch机制&#xff1a;有条件地调用一些状态的set方…...

计算机网络:BGP协议

BGP协议 与其他AS的邻站BPG发言人交换信息。 交换的网络可达性信息&#xff0c;即要到达某一个网络所要经历的一系列AS 发生变化时&#xff0c;更新有变化的部分 BGP协议交换信息的过程&#xff1a;所交换的网络可达性信息就是要到达某一个网络所要经历的一系列AS&#xff…...

91. 解码方法 ——【Leetcode每日刷题】

91. 解码方法 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; ‘A’ -> “1” ‘B’ -> “2” … ‘Z’ -> “26” 要 解码 已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&#xff08;可能有多种方法&#xff0…...

人体存在传感器成品方案,精准感知静止存在,实时智能化感控技术

随着现今智能时代的发展&#xff0c;酒店也越来越趋于智能化&#xff0c;也在不断地推行智慧酒店&#xff0c;这也给人们入住酒店提供了良好的体验。 人体存在感知是智能酒店中极其重要的一项应用技术&#xff0c;只有智能设备通过精准地感知人体存在&#xff0c;才能更好地做…...

mysql连接池的实现

目录 1 池化技术 2 什么是数据库连接池 3 为什么使用数据库连接池 3.1 不使用连接池 3.2 使用连接池 3.3 长连接和连接池的区别 4 数据库连接池运行机制 5 连接池和线程池的关系 6 线程池设计要点 6.1 连接池设计逻辑 构造函数 初始化 请求获取连接 归还连接 析…...

哪种类型蓝牙耳机佩戴最舒服?舒适度最好的蓝牙耳机推荐

如果您想在外出时听自己喜欢的音乐&#xff0c;您需要佩戴耳机&#xff0c;当前的耳机都足够小&#xff0c;可以将它们放在口袋里&#xff0c;即使它们在充电盒中也是如此&#xff0c;舒适度一直都是人们所追求的&#xff0c;舒适之余&#xff0c;佩戴同样稳固更加令人安心&…...

2020蓝桥杯真题洁净数 C语言/C++

题目描述 小明非常不喜欢数字 2&#xff0c;包括那些数位上包含数字 2 的数。如果一个数的数位不包含数字 2&#xff0c;小明将它称为洁净数。 请问在整数 1 至 n 中&#xff0c;洁净数有多少个&#xff1f; 输入描述 输入的第一行包含一个整数 n(1≤n≤10^6)。 输出描述 输…...

【随笔二】useReducer详解及其应用场景

前言 useReducer 实际上是 useState 的升级版&#xff0c;都是用来存储和更新 state&#xff0c;只是应用的场景不一样。 一般情况下&#xff0c;我们使用 useState 就足够项目需要了&#xff0c;不多当遇到以下场景时&#xff0c;使用useReducer 会更好些 。 状态逻辑复杂&…...

打怪升级之istringstream介绍

istringstream类 istringstream本质不是类&#xff0c;是一个宏&#xff0c;或者说是一个流&#xff1a; typedef basic_istringstream<char> istringstream;istringstream从basic_istringstream的char专用项而来。这一部分让人看得摸不着头脑的原因是因为大量使用了st…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...