-
Notifications
You must be signed in to change notification settings - Fork 0
/
sniffer.go
153 lines (134 loc) · 3.53 KB
/
sniffer.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package main
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
var allowedExtensions = []string{"exe", "zip", "rar", "bat", "cmd", "jar", "ps1", "jpg", "jpeg", "gif", "png", "bmp", "txt", "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx"}
func proxyHandler(packet gopacket.Packet, client *http.Client) {
tcpLayer := packet.Layer(layers.LayerTypeTCP)
if tcpLayer == nil {
return
}
_, _ = tcpLayer.(*layers.TCP)
appLayer := packet.ApplicationLayer()
if appLayer == nil {
return
}
payload := appLayer.Payload()
request, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(payload)))
if err != nil {
fmt.Println("[!] Error reading request:", err)
return
}
request.URL.Scheme = "http"
request.URL.Host = request.Host
request.RequestURI = ""
fmt.Println("[*] Received request:")
fmt.Printf("[+] Method: %s\n", request.Method)
fmt.Printf("[+] URL: %s\n", request.URL.String())
for name, values := range request.Header {
for _, value := range values {
fmt.Printf("[+] %s: %s\n", name, value)
}
}
resp, err := client.Do(request)
if err != nil {
fmt.Println("[!] Error sending request:", err)
return
}
defer resp.Body.Close()
handleResponse(packet, resp)
}
func handleResponse(packet gopacket.Packet, resp *http.Response) {
tcpLayer := packet.Layer(layers.LayerTypeTCP)
if tcpLayer == nil {
return
}
_, _ = tcpLayer.(*layers.TCP)
fmt.Println("[*] Received response:")
fmt.Println("[+] Status:", resp.Status)
for name, values := range resp.Header {
for _, value := range values {
fmt.Printf("[+] %s: %s\n", name, value)
}
}
contentType := resp.Header.Get("Content-Type")
if strings.HasPrefix(contentType, "text/html") {
return
}
urlPath, err := url.PathUnescape(resp.Request.URL.Path)
if err != nil {
fmt.Println("[!] Error decoding URL path:", err)
return
}
fileName := filepath.Base(urlPath)
fileExt := strings.ToLower(filepath.Ext(fileName))
if fileExt != "" && fileExt[1:] != "" && contains(allowedExtensions, fileExt[1:]) {
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("[!] Error reading response body:", err)
return
}
saveFileContent(content, fileName)
} else {
fmt.Println("[*] Ignoring file:", fileName)
}
}
func contains(slice []string, s string) bool {
for _, elem := range slice {
if elem == s {
return true
}
}
return false
}
func saveFileContent(content []byte, fileName string) {
err := ioutil.WriteFile(fileName, content, 0644)
if err != nil {
fmt.Println("[!] Error saving file:", err)
} else {
fmt.Println("[*] File saved:", fileName)
}
}
func main() {
ifaceName := "eth0" // Replace with the name of your network interface
iface, err := pcap.OpenLive(ifaceName, 65536, true, pcap.BlockForever)
if err != nil {
fmt.Println("[!] Error opening network interface:", err)
os.Exit(1)
}
defer iface.Close()
filter := "tcp port 80"
err = iface.SetBPFFilter(filter)
if err != nil {
fmt.Println("[!] Error setting BPF filter:", err)
os.Exit(1)
}
packetSource := gopacket.NewPacketSource(iface, iface.LinkType())
client := &http.Client{
Transport: &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
conn, err := net.Dial(network, addr)
if err != nil {
return nil, err
}
return conn, nil
},
},
}
fmt.Println("[*] Starting packet capture...")
for packet := range packetSource.Packets() {
proxyHandler(packet, client)
}
}