讲师中心 微信公众号

工具推荐

视频效率加速
AniShort
AniShort

AI短剧协同制作平台

Laper
Laper

剧本策划到成片协作

立刻MV
立刻MV

低成本歌曲 MV、视频生成

updream

一键生成高质量推广成片

使用Golang syscall 实现TCP SYN端口扫描:深入底层网络编程

小辰吖_4884

小辰吖_4884

发布时间:2025-11-09 20:27:01

|

652人浏览过

|

来源于php中文网

原创

使用Golang syscall 实现TCP SYN端口扫描:深入底层网络编程

本文详细阐述如何利用golang的`syscall`包进行tcp syn端口扫描,重点解决自定义tcp头部发送的问题。我们将探讨创建原始套接字、构建ip和tcp头部、计算校验和以及发送数据包的关键技术。同时,文章强调了`syscall`包的跨平台兼容性挑战及应对策略,旨在帮助开发者掌握go语言底层网络编程,构建高效且专业的网络扫描工具。

1. 理解TCP SYN扫描与原始套接字

TCP SYN扫描是一种高效且隐蔽的端口扫描技术。它通过发送一个只设置了SYN标志位的TCP数据包到目标端口,而不完成完整的三次握手。如果目标端口开放,它会返回一个SYN-ACK包;如果端口关闭,则返回一个RST包。通过分析响应,扫描器可以判断端口的开放状态。

在Go语言中,标准库net包提供了高级的网络抽象,如TCP连接、UDP数据包等。然而,它并不直接支持发送自定义的、不完整的TCP数据包(例如只带SYN标志位的包),因为它旨在建立和管理完整的连接。要实现这种底层操作,我们需要绕过标准库的限制,直接与操作系统内核进行交互,这正是原始套接字(Raw Socket)的用武之地。原始套接字允许应用程序直接构造和发送IP层或传输层的数据包,完全控制数据包的每一个字段。

2. 使用syscall包进行底层网络操作

Go语言的syscall包提供了一个与操作系统底层系统调用交互的接口。通过syscall包,我们可以创建原始套接字,并直接在IP层或传输层发送自定义的数据包。

权限要求: 使用原始套接字通常需要操作系统的root(Linux/macOS)或管理员(Windows)权限。这是因为原始套接字允许绕过网络协议栈的正常处理,直接访问和修改网络数据,这可能带来安全风险。

3. 构建TCP SYN扫描器核心组件

实现TCP SYN扫描的核心在于手动构造IP头部和TCP头部,然后通过原始套接字发送。

立即学习“go语言免费学习笔记(深入)”;

Todo List for MacOS
Todo List for MacOS

仅限macOS - 通过AppleScript管理macOS提醒事项应用。支持全功能提醒管理:添加、列出、完成、删除、搜索、创建列表等。

下载

3.1 创建原始套接字

首先,我们需要使用syscall.Socket函数创建一个原始套接字。对于TCP SYN扫描,我们通常在IP层创建套接字,并指定协议为TCP。

import (
    "fmt"
    "syscall"
)

func createRawTCPSocket() (int, error) {
    // AF_INET: IPv4协议族
    // SOCK_RAW: 原始套接字
    // IPPROTO_TCP: 协议为TCP
    fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_TCP)
    if err != nil {
        return -1, fmt.Errorf("创建原始套接字失败: %w", err)
    }
    // 告诉内核我们自己处理IP头部,避免内核自动添加IP头部
    // 并非所有系统都支持或需要此选项,在Linux上通常需要。
    err = syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_HDRINCL, 1)
    if err != nil {
        syscall.Close(fd)
        return -1, fmt.Errorf("设置IP_HDRINCL选项失败: %w", err)
    }
    return fd, nil
}

3.2 构造IP头部

IP头部包含了源IP地址、目标IP地址、数据包长度、协议类型等信息。我们需要手动填充这些字段。

import (
    "encoding/binary"
    "net"
)

const (
    IPv4HeaderLen = 20 // 最小IPv4头部长度
    IPVersion     = 4
    IPProtocolTCP = 6 // TCP协议号
)

// IPv4Header 结构体定义
type IPv4Header struct {
    VersionIHL     uint8  // 版本 (4 bits) 和 头部长度 (4 bits)
    TOS            uint8  // 服务类型
    TotalLen       uint16 // 总长度
    ID             uint16 // 标识
    FragOffset     uint16 // 标志和分片偏移
    TTL            uint8  // 生存时间
    Protocol       uint8  // 协议
    Checksum       uint16 // 头部校验和
    SrcIP          [4]byte
    DstIP          [4]byte
}

func NewIPv4Header(srcIP, dstIP net.IP, payloadLen int) *IPv4Header {
    header := &IPv4Header{
        VersionIHL: (IPVersion << 4) | (IPv4HeaderLen / 4), // 版本4, 头部长度20字节/4 = 5
        TOS:        0,
        TotalLen:   uint16(IPv4HeaderLen + payloadLen), // IP头部 + TCP头部长度
        ID:         uint16(12345), // 任意标识符
        FragOffset: 0,
        TTL:        64, // 默认TTL
        Protocol:   IPProtocolTCP,
        SrcIP:      [4]byte(srcIP.To4()),
        DstIP:      [4]byte(dstIP.To4()),
    }
    // 校验和在组装完整数据包后计算
    return header
}

// Serialize 将IPv4Header序列化为字节切片
func (h *IPv4Header) Serialize() []byte {
    buf := make([]byte, IPv4HeaderLen)
    buf[0] = h.VersionIHL
    buf[1] = h.TOS
    binary.BigEndian.PutUint16(buf[2:4], h.TotalLen)
    binary.BigEndian.PutUint16(buf[4:6], h.ID)
    binary.BigEndian.PutUint16(buf[6:8], h.FragOffset)
    buf[8] = h.TTL
    buf[9] = h.Protocol
    binary.BigEndian.PutUint16(buf[10:12], h.Checksum) // 校验和先置0,后续计算
    copy(buf[12:16], h.SrcIP[:])
    copy(buf[16:20], h.DstIP[:])
    return buf
}

3.3 构造TCP头部

TCP头部包含了源端口、目标端口、序列号、ACK序列号、标志位(如SYN、ACK、RST等)、窗口大小等信息。对于SYN扫描,我们需要将SYN标志位设置为1,ACK序列号设置为0。

const (
    TCPHeaderLen = 20 // 最小TCP头部长度
    TCPFlagSYN   = 0x02
)

// TCPHeader 结构体定义
type TCPHeader struct {
    SrcPort    uint16
    DstPort    uint16
    SeqNum     uint32
    AckNum     uint32
    DataOffset uint8  // 4 bits Data Offset, 4 bits Reserved
    Flags      uint8  // URG ACK PSH RST SYN FIN (6 bits)
    Window     uint16
    Checksum   uint16
    UrgentPtr  uint16
}

func NewTCPSYNHeader(srcPort, dstPort uint16) *TCPHeader {
    header := &TCPHeader{
        SrcPort:    srcPort,
        DstPort:    dstPort,
        SeqNum:     1105024978, // 任意初始序列号
        AckNum:     0,          // SYN包,ACK序列号为0
        DataOffset: TCPHeaderLen / 4, // 头部长度 (5 * 4字节 = 20字节)
        Flags:      TCPFlagSYN, // SYN标志位
        Window:     14600,      // 窗口大小
        UrgentPtr:  0,
    }
    // 校验和在组装完整数据包后计算
    return header
}

// Serialize 将TCPHeader序列化为字节切片
func (h *TCPHeader) Serialize() []byte {
    buf := make([]byte, TCPHeaderLen)
    binary.BigEndian.PutUint16(buf[0:2], h.SrcPort)
    binary.BigEndian.PutUint16(buf[2:4], h.DstPort)
    binary.BigEndian.PutUint32(buf[4:8], h.SeqNum)
    binary.BigEndian.PutUint32(buf[8:12], h.AckNum)

    // DataOffset (4 bits) + Reserved (4 bits)
    // Flags (URG ACK PSH RST SYN FIN)
    // DataOffsetAndFlags 字段的构造需要注意位操作
    buf[12] = (h.DataOffset << 4) | (0x00 & 0x0F) // DataOffset + Reserved
    buf[13] = h.Flags // Flags

    binary.BigEndian.PutUint16(buf[14:16], h.Window)
    binary.BigEndian.PutUint16(buf[16:18], h.Checksum) // 校验和先置0
    binary.BigEndian.PutUint16(buf[18:20], h.UrgentPtr)
    return buf
}

3.4 校验和计算

IP头部和TCP头部都需要计算校验和。校验和用于检测数据在传输过程中是否被损坏。TCP校验和的计算还需要包含一个“伪头部”(Pseudo-Header),其中包含源IP、目标IP、协议和TCP长度。

// calculateChecksum 计算标准的互联网校验和 (one's complement sum)
func calculateChecksum(data []byte) uint16 {
    var sum uint32
    // 确保数据长度为偶数,如果为奇数则末尾补零
    if len(data)%2 != 0 {
        data = append(data, 0)
    }

    for i := 0; i < len(data); i += 2 {
        sum += uint32(binary.BigEndian.Uint16(data[i : i+2]))
    }

    // 将溢出的高位加到低位
    for sum>>16 > 0 {
        sum = (sum & 0xffff) + (sum >> 16)
    }

    return uint16(^sum) // 取反
}

// PseudoHeader 用于TCP校验和计算
type PseudoHeader struct {
    SrcIP      [4]byte
    DstIP      [4]byte
    Zero       uint8 // 必须为0
    Protocol   uint8
    TCPLength  uint16 // TCP头部+数据长度
}

func (ph *PseudoHeader) Serialize() []byte {
    buf := make([]byte, 12) // 4+4+1+1+2 = 12 bytes
    copy(buf[0:4], ph.SrcIP[:])
    copy(buf[4:8], ph.DstIP[:])
    buf[8] = ph.Zero
    buf[9] = ph.Protocol
    binary

相关文章

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

539

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

616

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1296

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

811

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1886

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

5414

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

2514

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

4366

2025.06.17

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

0

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn