首页
社区
课程
招聘
[原创]Windows ICMP 隧道开发研究
2023-10-24 10:59 9928

[原创]Windows ICMP 隧道开发研究

2023-10-24 10:59
9928

 本文主要研究在Windows平台下的 ICMP 隧道的简单开发和部署使用。


本文适合了解ICMP隧道基础的安全编程爱好者可以通过百度谷歌或在微信公众号中搜索“ICMP隧道了解该内容


01

ICMP协议简介


ICMP协议是TCP/IP模型中的网络层协议,既不属于TCP协议,也不属于UDP协议,没有端口号的概念,通常用于探测网络是否通畅。Ping 命令就是 ICMP协议实现的一个案例。


02

ICMP隧道简介


红队攻击者通常利用ICMP数据包传输隐蔽信息,比如建立C2信道,俗称ICMP隧道,该隧道比较隐蔽。


03

ICMP隧道优缺点

  • 优点:

防火墙对 ICMP_ECHO 数据包通常是放行的,并且一般情况下,内部主机不会检查 ICMP 数据包所携带的数据内容,所以隐蔽性比较高;

  • 缺点:

ICMP 隧道是无连接的,和 UDP 一样很不稳定,而且隐蔽隧道的带宽很低;


04

ICMP隧道项目


下面介绍一个简单的ICMP隧道开发项目,可用于上传或下载文件。

项目链接:https://github.com/bigbang95/icmp_tunnel

项目使用C++语言编写,封装了CicmpClientSocket、CicmpServerSocket 等数据传输类,操作简单易懂。

可直接使用 VS2019 编译器 Release x64 方式编译即可。


05

Windows 下 ICMP 隧道服务端系统配置

Windows 防火墙新建自定义ICMP入站规则


【实验环境:Windows 10 - 20H2】


1. 点击新建规则


2. 设置规则类型

图片


3. 设置程序(一定选“特定程序”,不能选“所有程序”,否则ICMP隧道会因为出问题,而不能使用)

图片


4. 设置“协议和端口”


5. 设置“作用域”

图片


6. 设置“操作“

图片


7. 设置“配置文件”

图片


8. 设置“名称”


9. 到此,已成功新建并启用了自定义ICMP入站规则。


06

ICMP隧道部署


一、服务端(VPS)设置,通常是控制端

  1. 启用 Windows 防火墙;

  2. 禁用入站规则:文件和打印机共享(回显请求 - ICMPv4-In);

  3. 新建并启用“ICMP自定义”规则(注意:配置为”指定程序“,而非”所有程序“);

二、客户端设置,通常是被控端

无需特殊设置;

三、运行程序

  1. 在服务端(VPS)Windows 中,管理员权限运行 server.exe;

  2. 在客户端(局域网)Windows 中,直接普通用户权限运行 client.exe;

四、开始测试ICMP隧道


07

注意事项


服务端程序必须以 “嗅探” 的方式,绑定指定网卡;

bind IP 地址不能是 0.0.0.0,必须是具体的 IP 地址,如:192.168.204.128;

如果 bind IP 地址是 0.0.0.0,WSAIoctl 函数 返回错误代码:10022,即 Invalid argument;


使用 Windows 作为 服务端 的系统时,(注意:是设置 “入站” 规则)

Windows 防火墙应 新建并启用 “自定义 ICMP 入站规则”,方法见上面的 “05 Windows 下 ICMP 隧道服务端系统配置”,而不应使用 规则 “文件印机共享(回显请求 - ICMPv4-In)”,此规则应该被禁用;


位于服务端的 Windows 系统,设置防火墙时,需要 重点 注意:

1.  关闭 Windows 防火墙,会使 系统 自动应答 ping 命令 请求包;

2.  启用 Windows 防火墙,但使用 “文件和打印机共享(回显请求 - ICMPv4-In)” 或 “自定义 ICMP 规则 配置为 所有程序”,均会使 系统 自动应答 ping 命令 请求包;

解决方案:

启用 Windows 防火墙,新建并设置 “自定义 ICMP 规则” 并配置为 “特定程序(如:c:\path\server.exe)”


Windows(ICMP 隧道)服务端程序,需要使用原始套接字,以混杂模式,接收 原始数据包(IP 协议数据包),然后寻找指定 ICMP 请求包(包含命令结果信息),并返回 响应包(包含命令指令信息);

注意:需要管理员权限;


Windows(ICMP 隧道)服务端程序,必须 设置 IP_HDRINCL 标志,即 用户 自己 填充 IP 头;否则,程序将自动填充 IP 头信息,其中指定的 协议 不是 icmp,因而导致 响应包 是畸形 icmp 响应包,造成错误;


SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP); 

该行代码执行后,若程序没有管理员权限,则程序返回错误代码:10013,即 Permission denied)


ICMP 隧道中 设置 ICMP 响应包 时,应注意:

ICMP Head 部分 仅仅修改 type、checksum,将它们 都设置为 0,然后 重新计算 checksum 即可;

ICMP Data 部分 请求内容 和 响应内容 完全一样时,Wireshark 抓的 icmp 请求包与响应包 显示为匹配,无警告;

否则,Wireshark 抓的 icmp 请求包与响应包 显示为不匹配,有警告,此时 ICMP 隧道容易被发觉;


以太网中, MTU(最大传输单元) 设置为 1500;

所以,ICMP Data 部分 最大长度为:

MTU(1500字节) - IP 首部长度(20字节)- ICMP首部长度(8字节) = 1472 字节


08

常见错误 及 解决方法

  • VPS 系统为 Windows Server 2016,当前用户为 Administrator,使用本文方法设置 Windows 防火墙,ICMP 隧道 服务端程序 仍然无法接收 ICMP 请求包?

    • 原因:在设置中 自定义 ICMP 入站规则,指定了程序路径为:%USERPROFILE%\Desktop\s\server.exe,可能失败原因是 %USERPROFILE% 识别为错误的路径;

    • 解决方法:在设置中的 自定义 ICMP 入站规则 属性 中,修改该程序路径为:%SystemDrive%\Users\Administrator\Desktop\s\server.exe ,即可;

  • 客户端发送 icmp 请求包后,服务端发送 icmp 响应包,但 WireShark 过滤 icmp 数据包后,只发现了 icmp 请求包,未发现 icmp 响应包(当前未设置 IP_HDRINCL 标志,即 不需要 自己填充 IP 头

    • 原因:考虑 sendto 发送 响应数据包,未返回错误,猜想 响应数据包 发送成功,但该响应包不具备 icmp 协议形式,所以 Wireshark 抓不到 icmp 响应包;

    • 解决方法:既然响应包发送成功,不是 icmp 协议形式,有可能是其他协议形式,再次使用 Wireshark 过滤协议,这次过滤表达式为:ip.addr==120.229.78.16 && (!tcp && !tls),结果 发现 IPv4 畸形包正好对应 发送成功的 响应包;


09

icmp 校验和 算法 (经过验证)

    USHORT CicmpSocket::CheckSum(const char* buf, size_t size)
    {
           size_t i;
           ULONGLONG sum = 0;
    
           for (i = 0; i < size; i += 2) {
                   sum += *(USHORT*)buf;
                   buf += 2;
           }
    
           if (size - i > 0) {
                   sum += *(BYTE*)buf;
           }
    
           while ((sum >> 16) != 0) {
                   sum = (sum & 0xffff) + (sum >> 16);
           }
    
           return (USHORT)~sum;
    }


    10

    解决 从 ICMP 服务端 发送(68MB - 198 MB)大文件

    到 ICMP 客户端 失败的 bug

    1. 原因很可能是 icmp 请求包 Data 部分 数据长度 小于 32 字节,NAT 路由器设备丢弃了 icmp 响应包造成的;

    2. 解决办法使 icmp 请求包 Data 部分 数据长度 大于等于 32 字节即可;(github 项目 https://github.com/bigbang95/icmp_tunnel 仅需如下更改即可)


      // 修改文件 icmp_tunnel\icmp\icmpSocket.h
      
      struct ICMP_DATA_HEAD
      {
             UINT seq;
             USHORT flags;
             char sz[26]; // 仅添加 此行代码 即可
      };


      11

      参考链接

      1. Python3实现ICMP远控后门(中)之“嗅探”黑科技-腾讯云开发者社区-腾讯云 (tencent.com) ——(https://cloud.tencent.com/developer/article/1152186)

      2. GitHub - bigbang95/icmp_tunnel: 一个简单的 稳定 ICMP 传输 示例,在公网中传输可能有点慢,但很稳定,适合初学者——(https://github.com/bigbang95/icmp_tunnel)


      12

      声明


      本文所述方法,仅供安全研究使用。凡擅自用于违法用途,将被追究法律责任。其违法行为均与本人无关。特此声明!


      原文链接:Windows ICMP 隧道开发研究 (qq.com)


      [培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

      最后于 2023-10-24 11:47 被bigbang95编辑 ,原因:
      收藏
      点赞5
      打赏
      分享
      最新回复 (7)
      雪    币: 22979
      活跃值: (3332)
      能力值: (RANK:648 )
      在线值:
      发帖
      回帖
      粉丝
      KevinsBobo 8 2023-10-24 11:34
      2
      0
      部分图片存在问题,麻烦修复一下
      雪    币: 420
      活跃值: (574)
      能力值: ( LV3,RANK:20 )
      在线值:
      发帖
      回帖
      粉丝
      bigbang95 2023-10-24 11:38
      3
      0
      KevinsBobo 部分图片存在问题,麻烦修复一下
      ok,我看一下
      雪    币: 420
      活跃值: (574)
      能力值: ( LV3,RANK:20 )
      在线值:
      发帖
      回帖
      粉丝
      bigbang95 2023-10-24 11:56
      4
      0
      KevinsBobo 部分图片存在问题,麻烦修复一下
      感谢版主,已修复
      雪    币: 1638
      活跃值: (2783)
      能力值: ( LV2,RANK:10 )
      在线值:
      发帖
      回帖
      粉丝
      qj111111 2023-10-29 16:04
      5
      0
      emmmm,能用这种协议pass gfw不,感觉可以利用一下,在某些极端环境下,比如墙越升越高,进化至白名单模式(sni阻断)利用该协议,就是带宽太低了
      雪    币: 3344
      活跃值: (1361)
      能力值: ( LV2,RANK:10 )
      在线值:
      发帖
      回帖
      粉丝
      Elice 2023-10-30 09:07
      6
      0
      qj111111 emmmm,能用这种协议pass gfw不,感觉可以利用一下,在某些极端环境下,比如墙越升越高,进化至白名单模式(sni阻断)利用该协议,就是带宽太低了
      感觉不太行
      雪    币: 1638
      活跃值: (2783)
      能力值: ( LV2,RANK:10 )
      在线值:
      发帖
      回帖
      粉丝
      qj111111 2023-10-30 09:31
      7
      0
      Elice 感觉不太行

      | 专家 | 思考和回答 |

      | --- | --- |

      | 专家一 | 这是一个复杂的技术问题,涉及到网络协议,特别是ICMP协议的特性以及GFW防火墙的工作方式。ICMP协议通常用于发送网络错误报告或其他需要网络反馈的信息,它并不是为传输大量的数据流设计的。在理论上,ICMP协议的数据部分大小最多可以达到65535字节(包头部分已经剔除)。因此,如果我们完全利用这一最大值,那么在一个秒钟内,如果可以发送1000个这样的包,最大带宽将是65535字节 * 8位/字节 * 1000个包/秒 = 524280000位/秒,即约500Mbps。但这仅仅是理论值,实际上由于各种因素,如网络延迟,丢包等问题,实际带宽可能会远低于这个值。 |

      | 专家二 | 专家一的回答非常详细,但我想强调一点,GFW防火墙的设计就是为了防止这种类型的流量。GFW有很多复杂的技术,包括深度包检测(DPI)和行为分析,这些都可能影响通过ICMP协议发送大量数据的能力。并且,由于ICMP是一个非常重要的协议,用于网络诊断和错误报告,如果存在大量的ICMP流量,可能会引起网络提供商的注意,甚至可能被视为一种形式的拒绝服务攻击(DDoS)。这可能导致连接被限速或者完全被封锁。因此,虽然理论上的带宽可能很高,但实际使用中可能会遭遇各种限制。 |

      | 专家三 | 专家二的想法非常重要。实际上,我们还需要考虑VPS的带宽以及其与GFW之间的网络连接质量。如果VPS的带宽或者网络连接不佳,那么即使ICMP协议理论上的带宽很高,实际的网络传输速度也可能受到限制。另外,使用ICMP协议传输数据需要对数据进行封装和解封装,这个过程也需要消耗一定的计算资源,可能会进一步限制实际的传输速度。因此,虽然我们可以计算出ICMP协议理论上的最大带宽,但是在实际应用中,可能会受到很多限制,真正可用的带宽可能远低于理论最大值。 |


      雪    币: 19299
      活跃值: (28938)
      能力值: ( LV2,RANK:10 )
      在线值:
      发帖
      回帖
      粉丝
      秋狝 2023-10-30 09:37
      8
      1
      感谢分享
      游客
      登录 | 注册 方可回帖
      返回