手写一个UDP端口探测程序

今天让我们一起来看看UDP端口探测是怎么个事,本篇文章主要用到SOCK_DGRAM 套接字类型。

socket套接字相关的文章:

socket套接字你搞清楚了吗?

如何使用socket系统调用创建TCP三次握手呢?

SOCK_DGRAM 是 Linux 套接字(Socket)的一种类型,它提供无连接的、不可靠的数据报服务。这种套接字通常用于 UDP (User Datagram Protocol) 用户数据报协议。

UDP报文结构

特性

  1. 无连接:通信前不需要建立连接
  2. 数据报服务:数据以独立的数据包形式传输
  3. 不可靠传输:不保证数据到达顺序,可能丢失或重复
  4. 边界保留:数据保持发送时的消息边界
  5. 高效:相比 SOCK_STREAM 开销更小

示例:向目标服务发送UDP报文,测试目标服务是否回包(验证端口是否存活)

func main() {
    // 创建套接字
	fd, err := syscall.Socket(
		syscall.AF_INET,
		syscall.SOCK_DGRAM,
		syscall.IPPROTO_UDP,
	)
	if err != nil {
		log.Fatalf("create socket err: %v", err)
	}
	defer syscall.Close(fd)

	// 设置超时
	tv := syscall.Timeval{Sec: 3, Usec: 0}
	if err := syscall.SetsockoptTimeval(
		fd, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv); err != nil {
		log.Fatalf("Set timeout error: %v\n", err)
		return
	}

	// 构造目标IP及端口
	dstIP := net.ParseIP("192.168.1.5").To4()
	dstPort := 1234
	dstAddr := &syscall.SockaddrInet4{Port: dstPort}
	copy(dstAddr.Addr[:], dstIP.To4())

	// 发送探测数据
	msg := []byte("hello udp!")
	if err := syscall.Sendto(fd, msg, 0, dstAddr); err != nil {
		log.Fatalf("send err: %v", err)
		return
	}

	// 尝试接收响应
	buf := make([]byte, 1024)
	_, _, err = syscall.Recvfrom(fd, buf, 0)
	if err != nil {
		if err == syscall.EAGAIN || err == syscall.EWOULDBLOCK {
			log.Fatalf("No response received\n")
		} else {
			log.Fatalf("Receive error: %v\n", err)
		}
		return
	}
	log.Fatalf("udp probe success!\n")
}

(1)首先创建syscall.Socket()套接字,指定syscall.SOCK_DGRAM套接字类型
(2)设置链接超时时间
(3)创建要探测的UDP服务地址(目标IP及端口)
(4)封装消息体
(5)最后使用 syscall.Recvfrom 接收UDP服务响应

📢 注意

由于UDP协议是非面向连接的,对UDP端口的探测也就不可能像TCP端口的探测那样依赖于连接建立过程,这也使得UDP端口扫描的可靠性不高。

上述案例是建立在目标udp服务有回包的基础上实现的,如果目标udp服务没有回包我们如何来探测呢

对UDP端口的扫描,参考另一种思路:利用ICMP端口不可达报文进行扫描。

原理是当一个UDP端口接收到一个UDP数据报时:

  • 如果它是关闭的,就会给源端发回一个ICMP端口不可达数据报;
  • 如果它是开放的,那么就会忽略这个数据报,也就是将它丢弃而不返回任何的信息。

下面用nmap命令针对 114 DNS服务UDP端口开始扫描

扫描状态显示 open|filterd 代表可能丢弃 UDP 包,导致结果不确定性。

下面通过tcpdump开始抓包
① 首先namp首先发送了ICMP包探测
② 随后114DNS服务进行ICMP回包
③ ④ icmp应答后,nmap才开始发UDP数据包,最后114DNS也没有回复udp数据包。

技术文章持续更新,请大家多多关注呀~~

搜索微信公众号,关注我【 帽儿山的枪手 】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值