Skip to content

Commit 514b6c3

Browse files
added more checks for FTP and SNMP
1 parent c4284e7 commit 514b6c3

File tree

7 files changed

+51
-24
lines changed

7 files changed

+51
-24
lines changed

layers/ethernet.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func (ef *EthernetFrame) Parse(data []byte) error {
111111
}
112112

113113
func (ef *EthernetFrame) NextLayer() Layer {
114-
if next := GetNextLayer(LayerName(ef.EtherType.Desc)); next != nil {
114+
if next := GetLayer(LayerName(ef.EtherType.Desc)); next != nil {
115115
if err := next.Parse(ef.Payload); err == nil {
116116
return next
117117
}

layers/ftp.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ func (f *FTPMessage) Summary() string {
2323
func (f *FTPMessage) Parse(data []byte) error {
2424
buf := make([]byte, 0, len(data))
2525
buf = append(buf, data...)
26+
if !checkFTP(buf) {
27+
return fmt.Errorf("malformed ftp message")
28+
}
2629
f.summary = nil
2730
f.data = nil
2831
sp := bytes.Split(buf, crlf)
@@ -43,3 +46,9 @@ func (f *FTPMessage) Parse(data []byte) error {
4346

4447
func (f *FTPMessage) NextLayer() Layer { return nil }
4548
func (f *FTPMessage) Name() LayerName { return LayerFTP }
49+
50+
func checkFTP(data []byte) bool {
51+
return (len(data) >= 4 && isDigit(data[0]) && isDigit(data[1]) &&
52+
isDigit(data[2]) && (data[3] == ' ' || data[3] == '-')) ||
53+
(len(data) >= 3 && isUpper(data[0]) && isUpper(data[1]) && isUpper(data[2]))
54+
}

layers/ipv4.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ func protodesc(proto IPProto) string {
218218
}
219219

220220
func (p *IPv4Packet) NextLayer() Layer {
221-
if next := GetNextLayer(LayerName(p.Protocol.Desc)); next != nil {
221+
if next := GetLayer(LayerName(p.Protocol.Desc)); next != nil {
222222
if err := next.Parse(p.Payload); err == nil {
223223
return next
224224
}

layers/ipv6.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func (p *IPv6Packet) nextLayer() string {
120120
}
121121

122122
func (p *IPv6Packet) NextLayer() Layer {
123-
if next := GetNextLayer(LayerName(p.nextLayer())); next != nil {
123+
if next := GetLayer(LayerName(p.nextLayer())); next != nil {
124124
if err := next.Parse(p.Payload); err == nil {
125125
return next
126126
}

layers/layers.go

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func parseNextLayerFallback(data []byte) Layer {
7373
return nil
7474
}
7575
for _, layer := range Layers {
76-
next := GetNextLayer(layer)
76+
next := GetLayer(layer)
7777
if err := next.Parse(data); err == nil {
7878
return next
7979
}
@@ -90,25 +90,25 @@ func parseNextLayerFromBytes(data []byte) Layer {
9090
var next Layer
9191
firstByte := buf[0]
9292
if firstByte >= 0x45 && firstByte <= 0x4F {
93-
next = GetNextLayer(LayerIPv4)
93+
next = GetLayer(LayerIPv4)
9494
if err := next.Parse(buf); err == nil {
9595
return next
9696
}
9797
}
9898
if firstByte>>4 == 6 {
99-
next = GetNextLayer(LayerIPv6)
99+
next = GetLayer(LayerIPv6)
100100
if err := next.Parse(buf); err == nil {
101101
return next
102102
}
103103
}
104104
if firstByte == HandshakeTLSVal {
105-
next = GetNextLayer(LayerTLS)
105+
next = GetLayer(LayerTLS)
106106
if err := next.Parse(buf); err == nil {
107107
return next
108108
}
109109
}
110-
if firstByte == 0x30 {
111-
next = GetNextLayer(LayerSNMP)
110+
if checkFTP(buf) {
111+
next = GetLayer(LayerFTP)
112112
if err := next.Parse(buf); err == nil {
113113
return next
114114
}
@@ -117,29 +117,35 @@ func parseNextLayerFromBytes(data []byte) Layer {
117117
b1 := binary.BigEndian.Uint16(buf[0:2])
118118
b2 := binary.BigEndian.Uint16(buf[2:4])
119119
if b1 == 1 && (b2 == 0x0800 || b2 == 0x86dd) {
120-
next = GetNextLayer(LayerARP)
120+
next = GetLayer(LayerARP)
121121
if err := next.Parse(buf); err == nil {
122122
return next
123123
}
124124
}
125125
}
126+
if checkSNMP(buf) {
127+
next = GetLayer(LayerSNMP)
128+
if err := next.Parse(buf); err == nil {
129+
return next
130+
}
131+
}
126132
if len(buf) > 15 {
127133
b1 := binary.BigEndian.Uint16(buf[12:14])
128134
if b1 == 0x0806 || b1 == 0x0800 || b1 == 0x86dd {
129-
next = GetNextLayer(LayerETH)
135+
next = GetLayer(LayerETH)
130136
if err := next.Parse(buf); err == nil {
131137
return next
132138
}
133139
}
134140
}
135141
if bytes.Contains(buf, protohttp10) || bytes.Contains(buf, protohttp11) {
136-
next = GetNextLayer(LayerHTTP)
142+
next = GetLayer(LayerHTTP)
137143
if err := next.Parse(buf); err == nil {
138144
return next
139145
}
140146
}
141147
if bytes.Contains(buf, protoSSH) {
142-
next = GetNextLayer(LayerSSH)
148+
next = GetLayer(LayerSSH)
143149
if err := next.Parse(buf); err == nil {
144150
return next
145151
}
@@ -170,17 +176,17 @@ func parseNextLayerFromPorts(data []byte, src, dst *uint16) Layer {
170176
var next Layer
171177
switch {
172178
case addrMatch(src, dst, []uint16{53, 5353, 853, 5355}):
173-
next = GetNextLayer(LayerDNS)
179+
next = GetLayer(LayerDNS)
174180
case addrMatch(src, dst, []uint16{80, 8080, 8000, 8888, 81, 591, 5911}):
175-
next = GetNextLayer(LayerHTTP)
181+
next = GetLayer(LayerHTTP)
176182
case addrMatch(src, dst, []uint16{161, 162, 10161, 10162, 1161, 2161}):
177-
next = GetNextLayer(LayerSNMP)
183+
next = GetLayer(LayerSNMP)
178184
case addrMatch(src, dst, []uint16{21, 20, 2121, 8021}):
179-
next = GetNextLayer(LayerFTP)
185+
next = GetLayer(LayerFTP)
180186
case addrMatch(src, dst, []uint16{22, 2222, 2200, 222, 2022}):
181-
next = GetNextLayer(LayerSSH)
187+
next = GetLayer(LayerSSH)
182188
case addrMatch(src, dst, []uint16{443, 465, 993, 995, 8443, 9443, 10443, 8444, 5228}):
183-
next = GetNextLayer(LayerTLS)
189+
next = GetLayer(LayerTLS)
184190
default:
185191
return nil
186192
}
@@ -206,7 +212,7 @@ func ParseNextLayer(data []byte, src, dst *uint16) Layer {
206212
return parseNextLayerFallback(buf)
207213
}
208214

209-
func GetNextLayer(layer LayerName) Layer {
215+
func GetLayer(layer LayerName) Layer {
210216
switch layer {
211217
case LayerETH:
212218
return &EthernetFrame{}
@@ -262,3 +268,11 @@ func add16WithCarryWrapAround(x, y uint16) uint16 {
262268
sum32 = (sum32 & 0xFFFF) + (sum32 >> 16)
263269
return uint16(sum32)
264270
}
271+
272+
func isDigit(b byte) bool {
273+
return b >= '0' && b <= '9'
274+
}
275+
276+
func isUpper(b byte) bool {
277+
return b >= 'A' && b <= 'Z'
278+
}

layers/snmp.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,18 @@ func (s *SNMPMessage) Summary() string {
1818
}
1919

2020
func (s *SNMPMessage) Parse(data []byte) error {
21-
if data[0] != 0x30 {
22-
return fmt.Errorf("not ASN.1 SEQUENCE")
23-
}
2421
buf := make([]byte, 0, len(data))
2522
buf = append(buf, data...)
23+
if !checkSNMP(buf) {
24+
return fmt.Errorf("not ASN.1 SEQUENCE")
25+
}
2626
s.Payload = buf
2727
return nil
2828
}
2929

3030
func (s *SNMPMessage) NextLayer() Layer { return nil }
3131
func (s *SNMPMessage) Name() LayerName { return LayerSNMP }
32+
33+
func checkSNMP(data []byte) bool {
34+
return len(data) > 6 && data[0] == 0x30 && (data[2] == 0x02 || data[2] == 0x04)
35+
}

mshark.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (mw *Writer) WritePacket(timestamp time.Time, data []byte) error {
8484
mw.packets++
8585
fmt.Fprintf(mw.w, "- Packet: %d Timestamp: %s\n", mw.packets, timestamp.Format("2006-01-02T15:04:05.000000-0700"))
8686
fmt.Fprintln(mw.w, packetDelimeter)
87-
next := layers.GetNextLayer(layers.LayerETH)
87+
next := layers.GetLayer(layers.LayerETH)
8888
if next == nil {
8989
return nil
9090
}

0 commit comments

Comments
 (0)