用Go处理原始数据包
文章目录
- 1. gopacket基本使用
- 检索可用设备
- 捕获并过滤数据包
- 2. 嗅探用户凭证
- 3. 绕过SYN泛洪保护进行端口扫描
- SYN Cookie
- 绕过
1. gopacket基本使用
Google开发的gopacket库可以方便地处理网络数据包,比如操作pcap文件,支持BPF过滤器语法(Berkeley Packet Filter, 又称为tcpdump语法)等。
文档:https://pkg.go.dev/github.com/google/gopacket/
安装:
go get github.com/google/gopacket
linux系统需要安装libpcap库:
sudo apt-get install libpcap-dev
windows则需要安装WinPcap。
检索可用设备
文档:https://pkg.go.dev/github.com/google/gopacket/pcap
package mainimport ("fmt""log""github.com/google/gopacket/pcap"
)func main() {pcapDevices, err := pcap.FindAllDevs()if err != nil {log.Panicln(err)}for _, pcapDev := range pcapDevices {fmt.Println(pcapDev.Name)fmt.Println(pcapDev.Description)for _, address := range pcapDev.Addresses {fmt.Printf(" IP: %s\n", address.IP)fmt.Printf(" Netmask: %s\n", address.Netmask)fmt.Printf(" Broadaddr: %s\n", address.Broadaddr)fmt.Printf(" P2P: %s\n", address.P2P)}}
}
捕获并过滤数据包
官网example: https://pkg.go.dev/github.com/google/gopacket/pcap#hdr-Reading_PCAP_Files
保存为pcap官方example: https://pkg.go.dev/github.com/google/gopacket/pcapgo#example-package-CaptureEthernet
BPF语法可参考tcpdump官网:https://www.tcpdump.org/manpages/pcap-filter.7.html
package mainimport ("fmt""log""os""github.com/google/gopacket""github.com/google/gopacket/layers""github.com/google/gopacket/pcap""github.com/google/gopacket/pcapgo"
)func main() {var (strIntface = "enp0s3"nSnaplen = int32(1600)bPromisc = falsenTimeout = pcap.BlockForeverstrFilter = "tcp and port 80"bDevFound = falsestrPcapFile = "/tmp/test.pcap")// 1. Find the interfacedevices, err := pcap.FindAllDevs()if err != nil {log.Panicln(err)}for _, device := range devices {fmt.Printf("iface: %s\n", device.Name)if device.Name == strIntface {bDevFound = truebreak}}if !bDevFound {log.Panicf("Device named '%s' does not exist\n", strIntface)}// 2. Get the handle of the interfacehandle, err := pcap.OpenLive(strIntface, nSnaplen, bPromisc, nTimeout)if err != nil {log.Panicln(err)}defer handle.Close()// 3. set bpf filterif err := handle.SetBPFFilter(strFilter); err != nil {log.Panicln(err)}// 3. save as .pcapfPcap, err := os.Create(strPcapFile)if err != nil {log.Fatal(err)}defer fPcap.Close()pcapw := pcapgo.NewWriter(fPcap)if err := pcapw.WriteFileHeader(1600, layers.LinkTypeEthernet); err != nil {log.Fatalf("WriteFileHeader: %v", err)}// 4. Make handle as the source// source := gopacket.NewPacketSource(handle, handle.LinkType())source := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)for packet := range source.Packets() {fmt.Println(packet)if err := pcapw.WritePacket(packet.Metadata().CaptureInfo, packet.Data()); err != nil {log.Fatalf("pcap.WritePacket(): %v", err)}}
}
保存的/tmp/test.pcap可以用wireshark打开,也可以用 pcap.OpenOffline打开后解码分析,具体可参考asta谢的这篇文章,《网络流量抓包库 gopacket》,以及官方Packet接口注释。
2. 嗅探用户凭证
应用前提:已经拿下目标网络的某台机器
在过滤数据包代码基础上,修改过滤表达式:
strFilter = "tcp and dst port 21"
然后在遍历数据包时,提取应用层,分析其payload中是否有我们关心的关键词:
source := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range source.Packets() {appLayer := packet.ApplicationLayer()if appLayer == nil {continue}payload := appLayer.Payload()arrStrKeyWords := [2]string{"USER", "PASS"}for _, strKeyWord := range arrStrKeyWords {if bytes.Contains(payload, []byte(strKeyWord)) {fmt.Print(string(payload))}}
}
3. 绕过SYN泛洪保护进行端口扫描
SYN Cookie
简单复习一下syn泛洪攻击:攻击者对服务器发送大量的SYN连接请求(第一次握手),却不回复服务器返回的SYN+ACK(第二次握手),服务器就保存了大量半连接(half-open)请求,每个请求都要为TCB(TCP 传输控制块)开辟内存(backlog维护上限),最终内存耗尽或达到backlog上限而拒绝服务。
[syn cookie](https://baike.baidu.com/item/syn cookie)是用来防范SYN Flood攻击的手段之一,服务端收到一个SYN时不需要分配空间,而是结合SYN初始序列号、双方ip、端口等信息计算出SYN-ACK序列号(就是SYN cookies),收到ack时在进行验证。
在使用syn泛洪保护时,通常所有端口(open, closed, filtered)都会产生相同的数据交换,以表明端口处于打开状态。
绕过
TCP SYN泛洪主要发生在OSI的传输层,抓包后自然也要分析传输层(TransportLayer()),要关注的是tcp的标志位(Control Flag),它在下标13的字节。
7->0
CWR | ECE | URG | ACK | PSH | RST | SYN | FIN
通过标志位可以检查是否有三次握手之外的其它数据包,以下的BPF过滤条件可以表示监听服务:
tcp[13] == 0x11 or tcp[13] == 0x10 or tcp[13] == 0x18
解释:
- ACK & FIN : b00010001 == 0x11
- ACK : b00010000 == 0x10
- ACK & PSH: b00011000 == 0x18
源码:
var (nSnaplen = int32(320)bPromisc = truenTimeout = pcap.BlockForeverstrFilter = "tcp[13] == 0x11 or tcp[13] == 0x10 or tcp[13] == 0x18"bDevFound = falsemapResults = make(map[string]int)
)func capture(iface, target string) {handle, err := pcap.OpenLive(iface, nSnaplen, bPromisc, nTimeout)if err != nil {log.Panicln(err)}defer handle.Close()if err := handle.SetBPFFilter(strFilter); err != nil {log.Panicln(err)}source := gopacket.NewPacketSource(handle, handle.LinkType())fmt.Println("Capturing packets")for packet := range source.Packets() {networkLayer := packet.NetworkLayer()if networkLayer == nil {continue}transportLayer := packet.TransportLayer()if transportLayer == nil {continue}srcHost := networkLayer.NetworkFlow().Src().String()srcPort := transportLayer.TransportFlow().Src().String()if srcHost != target {continue}mapResults[srcPort] += 1}
}func explode(portString string) ([]string, error) {ret := make([]string, 0)ports := strings.Split(portString, ",")for _, port := range ports {port := strings.TrimSpace(port)ret = append(ret, port)}return ret, nil
}func newSliceValue(vals []string, p *[]string) *[]string {*p = valsreturn (*[]string)(p)
}func main() {var (pStrFlagDev = flag.String("iface", "", "The interface to capture.")pStrFlagIp = flag.String("ip", "", "The target ip.")pStrFlagPorts = flag.String("ports", "", "The ports to listen to."))flag.Parse()if len(os.Args) != 4 {log.Fatalln("Usage: main.go <capture_iface> <target_ip> <port1,port2,port3>")}devices, err := pcap.FindAllDevs()if err != nil {log.Panicln(err)}for _, device := range devices {if device.Name == *pStrFlagDev {bDevFound = true}}if !bDevFound {log.Panicf("Device named '%s' does not exist\n", *pStrFlagDev)}go capture(*pStrFlagDev, *pStrFlagIp)time.Sleep(1 * time.Second)ports, err := explode(*pStrFlagPorts)if err != nil {log.Panicln(err)}for _, port := range ports {target := fmt.Sprintf("%s:%s", *pStrFlagIp, port)fmt.Println("Trying", target)conn, err := net.DialTimeout("tcp", target, 1000*time.Millisecond)if err != nil {continue}conn.Close()}time.Sleep(2 * time.Second)for port, confidence := range mapResults {if confidence >= 1 {fmt.Printf("Port %s open (confidence: %d)\n", port, confidence)}}
}
用Go处理原始数据包相关推荐
- 使用Packet.dll和npf.sys实现原始数据包的发送和接收
相应源码下载地址: http://download.csdn.net/source/3521479 有人可能问我为什么不直接用wpcap.dll,那个不但功能更强大还稳定.那是因为我这个功能很简单 ...
- linux获取网卡协议地址,读取linux下的网络设备的mac地址与发送原始数据包 (2011-11-23 20:11)...
一:linux下的网络设备 linux的网络设备信息都在/proc/net/dev,从这里我们可以得到所有网卡的名字,如eth0, eth1等等 root@dlrc-desktop:/home/dlr ...
- 【OpenBCI】(2):原始数据包解码
去年我写了一篇OpenBCI的博客[OpenBCI]:Matlab实时读取数据流(labstreaminglayer),讲述如何用python的SDK将OpenBCI数据读取到Matlab中. ...
- 使用tcpdump查看原始数据包
点击上方 "后端架构师"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 关注订阅号「后端架构师」,收看更多精彩内容 每日英文 Nothing can ...
- 肝了三天,万字长文教你玩转 tcpdump,从此抓包不用愁
图源 | 视觉中国 来源|Python编程时光(ID: Cool-Python) 今天要给大家介绍的一个 Unix 下的一个 网络数据采集分析工具 -- Tcpdump,也就是我们常说的抓包工具. 与 ...
- java使用原始套接字技术进行数据包截获_Linux零拷贝技术,看完这篇文章就懂了...
本文讲解 Linux 的零拷贝技术,云计算是一门很庞大的技术学科,融合了很多技术,Linux 算是比较基础的技术,所以,学好 Linux 对于云计算的学习会有比较大的帮助. 为什么需要零拷贝 传统的 ...
- 如何处理网络丢包故障?—Vecloud微云
我们在使用ping命令对目的站进行询问时,数据包由于各种原因在信道中丢失的现象,就是网络丢包.网络丢包是网络中常见的故障之一,它会引起网速降低甚至造成网络中断. 以下是几种常见的网络丢包故障现象及处理 ...
- SSL加密包解析的几个概念梳理
1.DPI技术初识 DPI(Deep PacketInspection)深度包检测技术是在传统IP数据包检测技术(OSI L2-L4之间包含的数据包元素的检测分析)之上增加了对应用层数据的应用协议识别 ...
- NewLife.Net——管道处理器解决粘包
Tcp网络编程,必须要解决的一个问题就是粘包,尽管解决办法有很多,这里讲一个比较简单的方法. 老规矩,先上代码:https://github.com/nnhy/NewLife.Net.Tests 一. ...
最新文章
- python封装方法有几种_Python打包exe文件方法汇总【4种】
- 2019.01.19-2018年6月NEYC集训sequence
- Knockout.Js案例一Introduction
- mysql实现decode_Oracle中的DECODE()函数,MySQL中怎么实现DECODE()函数
- Qt中设置窗体固定大小的方法
- 软考网络规划设计师备考及通过心得
- Android学习笔记(八)——在Manifest中设置ActionBar
- C#通过序列化实现深表复制
- swift中变量的几种类型
- 最少拍控制系统设计(二)纹波问题分析与无纹波系统的设计与仿真(附matlab和simulink源文件)
- pscc2018教程photoshop软件全套入门到精通分享
- python 搭建服务器
- 三维温度场 matlab,matlab绘制温度场
- UG NX二次开发(C#)-UI Styler-批量选择点
- HDOJ 5296 Annoying problem
- ios隐私政策_新的iOS 14已经揭露了严重的隐私问题
- android坐标画图软件下载,地图坐标app下载-地图坐标软件下载v4.8.15 安卓版-西西软件下载...
- SDK对接遇到的问题与解决
- Tomcat 在IE中下载rar文件直接以乱码方式打开解决方案
- 如何注册@live.com的邮箱