mirror of
https://github.com/wader/fq.git
synced 2024-11-26 10:33:53 +03:00
pcap: fuzz: Skip ssl2 packet if too short
Should report error somehow?
This commit is contained in:
parent
38509683a7
commit
b525d0b3c8
@ -18,23 +18,24 @@ type IPEndpoint struct {
|
||||
|
||||
type TCPConnection struct {
|
||||
ClientEndpoint IPEndpoint
|
||||
ServerEnpoint IPEndpoint
|
||||
ClientStream *bytes.Buffer
|
||||
ServerStream *bytes.Buffer
|
||||
ServerEndpoint IPEndpoint
|
||||
ClientToServer *bytes.Buffer
|
||||
ServerToClient *bytes.Buffer
|
||||
|
||||
tcpstate *reassembly.TCPSimpleFSM
|
||||
optchecker reassembly.TCPOptionCheck
|
||||
net, transport gopacket.Flow
|
||||
tcpState *reassembly.TCPSimpleFSM
|
||||
optChecker reassembly.TCPOptionCheck
|
||||
net gopacket.Flow
|
||||
transport gopacket.Flow
|
||||
}
|
||||
|
||||
func (t *TCPConnection) Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir reassembly.TCPFlowDirection, nextSeq reassembly.Sequence, start *bool, ac reassembly.AssemblerContext) bool {
|
||||
// has ok state?
|
||||
if !t.tcpstate.CheckState(tcp, dir) {
|
||||
if !t.tcpState.CheckState(tcp, dir) {
|
||||
// TODO: handle err?
|
||||
return false
|
||||
}
|
||||
// has ok options?
|
||||
if err := t.optchecker.Accept(tcp, ci, dir, nextSeq, start); err != nil {
|
||||
if err := t.optChecker.Accept(tcp, ci, dir, nextSeq, start); err != nil {
|
||||
// TODO: handle err?
|
||||
return false
|
||||
}
|
||||
@ -52,9 +53,9 @@ func (t *TCPConnection) ReassembledSG(sg reassembly.ScatterGather, ac reassembly
|
||||
|
||||
switch dir {
|
||||
case reassembly.TCPDirClientToServer:
|
||||
t.ClientStream.Write(data)
|
||||
t.ClientToServer.Write(data)
|
||||
case reassembly.TCPDirServerToClient:
|
||||
t.ServerStream.Write(data)
|
||||
t.ServerToClient.Write(data)
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,17 +80,17 @@ func (fd *Decoder) New(net, transport gopacket.Flow, tcp *layers.TCP, ac reassem
|
||||
IP: append([]byte(nil), net.Src().Raw()...),
|
||||
Port: int(binary.BigEndian.Uint16(transport.Src().Raw())),
|
||||
},
|
||||
ServerEnpoint: IPEndpoint{
|
||||
ServerEndpoint: IPEndpoint{
|
||||
IP: append([]byte(nil), net.Dst().Raw()...),
|
||||
Port: int(binary.BigEndian.Uint16(transport.Dst().Raw())),
|
||||
},
|
||||
ClientStream: &bytes.Buffer{},
|
||||
ServerStream: &bytes.Buffer{},
|
||||
ClientToServer: &bytes.Buffer{},
|
||||
ServerToClient: &bytes.Buffer{},
|
||||
|
||||
net: net,
|
||||
transport: transport,
|
||||
tcpstate: reassembly.NewTCPSimpleFSM(fsmOptions),
|
||||
optchecker: reassembly.NewTCPOptionCheck(),
|
||||
tcpState: reassembly.NewTCPSimpleFSM(fsmOptions),
|
||||
optChecker: reassembly.NewTCPOptionCheck(),
|
||||
}
|
||||
|
||||
fd.TCPConnections = append(fd.TCPConnections, stream)
|
||||
@ -98,8 +99,8 @@ func (fd *Decoder) New(net, transport gopacket.Flow, tcp *layers.TCP, ac reassem
|
||||
}
|
||||
|
||||
type Decoder struct {
|
||||
TCPConnections []*TCPConnection
|
||||
IPV4Reassbled []IPV4Reassembled
|
||||
TCPConnections []*TCPConnection
|
||||
IPV4Reassembled []IPV4Reassembled
|
||||
|
||||
ipv4Defrag *ip4defrag.IPv4Defragmenter
|
||||
tcpAssembler *reassembly.Assembler
|
||||
@ -115,36 +116,38 @@ func New() *Decoder {
|
||||
return flowDecoder
|
||||
}
|
||||
|
||||
func (fd *Decoder) SLLPacket(bs []byte) {
|
||||
fd.packet(gopacket.NewPacket(bs, layers.LayerTypeLinuxSLL, gopacket.Lazy))
|
||||
func (fd *Decoder) SLLPacket(bs []byte) error {
|
||||
return fd.packet(gopacket.NewPacket(bs, layers.LayerTypeLinuxSLL, gopacket.Lazy))
|
||||
}
|
||||
|
||||
func (fd *Decoder) EthernetFrame(bs []byte) {
|
||||
fd.packet(gopacket.NewPacket(bs, layers.LayerTypeEthernet, gopacket.Lazy))
|
||||
func (fd *Decoder) EthernetFrame(bs []byte) error {
|
||||
return fd.packet(gopacket.NewPacket(bs, layers.LayerTypeEthernet, gopacket.Lazy))
|
||||
}
|
||||
|
||||
func (fd *Decoder) packet(p gopacket.Packet) {
|
||||
func (fd *Decoder) packet(p gopacket.Packet) error {
|
||||
// TODO: linkType
|
||||
ip4Layer := p.Layer(layers.LayerTypeIPv4)
|
||||
if ip4Layer != nil {
|
||||
ip4, _ := ip4Layer.(*layers.IPv4)
|
||||
l := ip4.Length
|
||||
newip4, err := fd.ipv4Defrag.DefragIPv4(ip4)
|
||||
newIPv4, err := fd.ipv4Defrag.DefragIPv4(ip4)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else if newip4 != nil {
|
||||
return err
|
||||
} else if newIPv4 != nil {
|
||||
// TODO: correct way to detect finished reassemble?
|
||||
if newip4.Length != l {
|
||||
if newIPv4.Length != l {
|
||||
// TODO: better way to reconstruct package?
|
||||
sb := gopacket.NewSerializeBuffer()
|
||||
b, _ := sb.PrependBytes(len(newip4.Payload))
|
||||
copy(b, newip4.Payload)
|
||||
_ = newip4.SerializeTo(sb, gopacket.SerializeOptions{
|
||||
b, _ := sb.PrependBytes(len(newIPv4.Payload))
|
||||
copy(b, newIPv4.Payload)
|
||||
if err := newIPv4.SerializeTo(sb, gopacket.SerializeOptions{
|
||||
FixLengths: true,
|
||||
ComputeChecksums: true,
|
||||
})
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fd.IPV4Reassbled = append(fd.IPV4Reassbled, IPV4Reassembled{
|
||||
fd.IPV4Reassembled = append(fd.IPV4Reassembled, IPV4Reassembled{
|
||||
SourceIP: ip4.SrcIP,
|
||||
DestinationIP: ip4.DstIP,
|
||||
Datagram: sb.Bytes(),
|
||||
@ -154,8 +157,10 @@ func (fd *Decoder) packet(p gopacket.Packet) {
|
||||
if !ok {
|
||||
panic("not a PacketBuilder")
|
||||
}
|
||||
nextDecoder := newip4.NextLayerType()
|
||||
_ = nextDecoder.Decode(newip4.Payload, pb)
|
||||
nextDecoder := newIPv4.NextLayerType()
|
||||
if err := nextDecoder.Decode(newIPv4.Payload, pb); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,6 +170,8 @@ func (fd *Decoder) packet(p gopacket.Packet) {
|
||||
tcp, _ := tcp.(*layers.TCP)
|
||||
fd.tcpAssembler.Assemble(p.NetworkLayer().NetworkFlow(), tcp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fd *Decoder) Flush() {
|
||||
|
@ -77,7 +77,8 @@ func decodePcap(d *decode.D, in interface{}) interface{} {
|
||||
}
|
||||
|
||||
if fn, ok := linkToDecodeFn[linkType]; ok {
|
||||
fn(fd, bs)
|
||||
// TODO: report decode errors
|
||||
_ = fn(fd, bs)
|
||||
}
|
||||
|
||||
if g, ok := linkToFormat[linkType]; ok {
|
||||
|
@ -240,7 +240,9 @@ var blockFns = map[uint64]func(d *decode.D, dc *decodeContext){
|
||||
linkType := dc.interfaceTypes[int(interfaceID)]
|
||||
|
||||
if fn, ok := linkToDecodeFn[linkType]; ok {
|
||||
fn(dc.flowDecoder, bs)
|
||||
// TODO: report decode errors
|
||||
_ = fn(dc.flowDecoder, bs)
|
||||
_ = fn(dc.flowDecoder, bs)
|
||||
}
|
||||
|
||||
if g, ok := linkToFormat[linkType]; ok {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package pcap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/wader/fq/format"
|
||||
"github.com/wader/fq/format/inet/flowsdecoder"
|
||||
"github.com/wader/fq/pkg/bitio"
|
||||
@ -14,10 +16,15 @@ var linkToFormat = map[int]*decode.Group{
|
||||
format.LinkTypeLINUX_SLL2: &pcapngSLL2PacketFormat,
|
||||
}
|
||||
|
||||
var linkToDecodeFn = map[int]func(fd *flowsdecoder.Decoder, bs []byte){
|
||||
var linkToDecodeFn = map[int]func(fd *flowsdecoder.Decoder, bs []byte) error{
|
||||
format.LinkTypeETHERNET: (*flowsdecoder.Decoder).EthernetFrame,
|
||||
format.LinkTypeLINUX_SLL: (*flowsdecoder.Decoder).SLLPacket,
|
||||
format.LinkTypeLINUX_SLL2: func(fd *flowsdecoder.Decoder, bs []byte) {
|
||||
format.LinkTypeLINUX_SLL2: func(fd *flowsdecoder.Decoder, bs []byte) error {
|
||||
if len(bs) < 20 {
|
||||
// TODO: too short sll packet, error somehow?
|
||||
return fmt.Errorf("packet too short %d", len(bs))
|
||||
}
|
||||
|
||||
// TODO: gopacket does not support SLL2 atm so convert SLL to SSL2
|
||||
nbs := []byte{
|
||||
0, bs[10], // packet type
|
||||
@ -27,13 +34,14 @@ var linkToDecodeFn = map[int]func(fd *flowsdecoder.Decoder, bs []byte){
|
||||
bs[0], bs[1], // protocol type
|
||||
}
|
||||
nbs = append(nbs, bs[20:]...)
|
||||
fd.SLLPacket(nbs)
|
||||
|
||||
return fd.SLLPacket(nbs)
|
||||
},
|
||||
}
|
||||
|
||||
func fieldFlows(d *decode.D, fd *flowsdecoder.Decoder, tcpStreamFormat decode.Group, ipv4PacketFormat decode.Group) {
|
||||
d.FieldArray("ipv4_reassembled", func(d *decode.D) {
|
||||
for _, p := range fd.IPV4Reassbled {
|
||||
for _, p := range fd.IPV4Reassembled {
|
||||
bb := bitio.NewBufferFromBytes(p.Datagram, -1)
|
||||
if dv, _, _ := d.TryFieldFormatBitBuf(
|
||||
"ipv4_packet",
|
||||
@ -51,29 +59,29 @@ func fieldFlows(d *decode.D, fd *flowsdecoder.Decoder, tcpStreamFormat decode.Gr
|
||||
d.FieldStruct("flow", func(d *decode.D) {
|
||||
d.FieldValueStr("source_ip", s.ClientEndpoint.IP.String())
|
||||
d.FieldValueU("source_port", uint64(s.ClientEndpoint.Port), format.TCPPortMap)
|
||||
d.FieldValueStr("destination_ip", s.ServerEnpoint.IP.String())
|
||||
d.FieldValueU("destination_port", uint64(s.ServerEnpoint.Port), format.TCPPortMap)
|
||||
csBB := bitio.NewBufferFromBytes(s.ClientStream.Bytes(), -1)
|
||||
d.FieldValueStr("destination_ip", s.ServerEndpoint.IP.String())
|
||||
d.FieldValueU("destination_port", uint64(s.ServerEndpoint.Port), format.TCPPortMap)
|
||||
csBB := bitio.NewBufferFromBytes(s.ClientToServer.Bytes(), -1)
|
||||
if dv, _, _ := d.TryFieldFormatBitBuf(
|
||||
"client_stream",
|
||||
csBB,
|
||||
tcpStreamFormat,
|
||||
format.TCPStreamIn{
|
||||
SourcePort: s.ClientEndpoint.Port,
|
||||
DestinationPort: s.ServerEnpoint.Port,
|
||||
DestinationPort: s.ServerEndpoint.Port,
|
||||
},
|
||||
); dv == nil {
|
||||
d.FieldRootBitBuf("client_stream", csBB)
|
||||
}
|
||||
|
||||
scBB := bitio.NewBufferFromBytes(s.ServerStream.Bytes(), -1)
|
||||
scBB := bitio.NewBufferFromBytes(s.ServerToClient.Bytes(), -1)
|
||||
if dv, _, _ := d.TryFieldFormatBitBuf(
|
||||
"server_stream",
|
||||
scBB,
|
||||
tcpStreamFormat,
|
||||
format.TCPStreamIn{
|
||||
SourcePort: s.ClientEndpoint.Port,
|
||||
DestinationPort: s.ServerEnpoint.Port,
|
||||
DestinationPort: s.ServerEndpoint.Port,
|
||||
},
|
||||
); dv == nil {
|
||||
d.FieldRootBitBuf("server_stream", scBB)
|
||||
|
Loading…
Reference in New Issue
Block a user