Added mirros and updated LICENSE
This commit is contained in:
parent
51e3b5f01f
commit
ab158c1c9c
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2023, acidvegas <acid.vegas@acid.vegas>
|
||||
Copyright (c) 2024, acidvegas <acid.vegas@acid.vegas>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -8,6 +8,7 @@ This Packet Analysis Tool is designed to capture and analyze network packets in
|
||||
- Supports analysis of TCP, UDP, and ICMP protocols.
|
||||
- Displays packet details such as source/destination IP, source/destination port, packet length, and TTL.
|
||||
- Identifies and displays printable payloads in network traffic.
|
||||
- JSON packet logs for deep analysis.
|
||||
|
||||
## Usage
|
||||
| Argument | Description |
|
||||
@ -15,4 +16,8 @@ This Packet Analysis Tool is designed to capture and analyze network packets in
|
||||
| `-d` | Specify the network device to monitor *(e.g., eth0)*. |
|
||||
| `-c` | Set the packets-per-second threshold for logging. |
|
||||
| `-x` | Provide a comma-separated list of IPs and ports to exclude. |
|
||||
| `-i` | Provide a comma-separated list of IPs and ports to include. |
|
||||
| `-i` | Provide a comma-separated list of IPs and ports to include. |
|
||||
|
||||
___
|
||||
|
||||
###### Mirrors for this repository: [acid.vegas](https://git.acid.vegas/ddosmonit) • [SuperNETs](https://git.supernets.org/acidvegas/ddosmonit) • [GitHub](https://github.com/acidvegas/ddosmonit) • [GitLab](https://gitlab.com/acidvegas/ddosmonit) • [Codeberg](https://codeberg.org/acidvegas/ddosmonit)
|
@ -7,18 +7,22 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
"github.com/google/gopacket/pcap"
|
||||
)
|
||||
|
||||
var (
|
||||
deviceMonitor = flag.String("d", "eth0", "Device to monitor")
|
||||
packetThreshold = flag.Int("c", 5000, "Packets per second threshold to start logging")
|
||||
excludeList = flag.String("x", "", "Comma-separated list of IPs and ports to exclude")
|
||||
includeList = flag.String("i", "", "Comma-separated list of IPs and ports to include")
|
||||
)
|
||||
|
||||
const (
|
||||
ColorReset = "\033[0m"
|
||||
ColorDarkGrey = "\033[90m"
|
||||
@ -30,27 +34,20 @@ const (
|
||||
ColorPink = "\033[95m"
|
||||
)
|
||||
|
||||
var (
|
||||
deviceMonitor = flag.String("d", "eth0", "Device to monitor")
|
||||
packetThreshold = flag.Int("c", 5000, "Packets per second threshold to start logging")
|
||||
excludeList = flag.String("x", "", "Comma-separated list of IPs and ports to exclude")
|
||||
includeList = flag.String("i", "", "Comma-separated list of IPs and ports to include")
|
||||
)
|
||||
|
||||
type PacketInfo struct {
|
||||
Timestamp string `json:"timestamp"`
|
||||
Protocol string `json:"protocol"`
|
||||
SourceIP net.IP `json:"source_ip"`
|
||||
DestIP net.IP `json:"dest_ip"`
|
||||
SourcePort int `json:"source_port"`
|
||||
DestIP net.IP `json:"dest_ip"`
|
||||
DestPort int `json:"dest_port"`
|
||||
Length int `json:"length,omitempty"`
|
||||
TTL int `json:"ttl,omitempty"`
|
||||
WindowSize int `json:"window_size,omitempty"`
|
||||
TCPFlags string `json:"tcp_flags,omitempty"`
|
||||
Checksum int `json:"checksum,omitempty"`
|
||||
PayloadData string `json:"payload_data,omitempty"`
|
||||
TCPFlags string `json:"tcp_flags,omitempty"`
|
||||
ICMPData string `json:"icmp_data,omitempty"`
|
||||
PayloadData string `json:"payload_data,omitempty"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -138,105 +135,6 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func getInterfaceMAC(interfaceName string) (net.HardwareAddr, error) {
|
||||
iface, err := net.InterfaceByName(interfaceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return iface.HardwareAddr, nil
|
||||
}
|
||||
|
||||
func parseAndValidateIPsAndPorts(list string) ([]net.IP, []int) {
|
||||
var ips []net.IP
|
||||
var ports []int
|
||||
|
||||
items := strings.Split(list, ",")
|
||||
for _, item := range items {
|
||||
item = strings.TrimSpace(item)
|
||||
if ip := net.ParseIP(item); ip != nil {
|
||||
ips = append(ips, ip)
|
||||
} else if port, err := strconv.Atoi(item); err == nil {
|
||||
ports = append(ports, port)
|
||||
}
|
||||
}
|
||||
|
||||
return ips, ports
|
||||
}
|
||||
|
||||
func shouldProcessPacket(packet gopacket.Packet, excludeIPs []net.IP, excludePorts []int, includeIPs []net.IP, includePorts []int) bool {
|
||||
ipv4Layer := packet.Layer(layers.LayerTypeIPv4)
|
||||
tcpLayer := packet.Layer(layers.LayerTypeTCP)
|
||||
udpLayer := packet.Layer(layers.LayerTypeUDP)
|
||||
|
||||
var srcIP, dstIP net.IP
|
||||
var srcPort, dstPort int
|
||||
|
||||
if ipv4Layer != nil {
|
||||
ipv4, _ := ipv4Layer.(*layers.IPv4)
|
||||
srcIP = ipv4.SrcIP
|
||||
dstIP = ipv4.DstIP
|
||||
}
|
||||
|
||||
if tcpLayer != nil {
|
||||
tcp, _ := tcpLayer.(*layers.TCP)
|
||||
srcPort = int(tcp.SrcPort)
|
||||
dstPort = int(tcp.DstPort)
|
||||
} else if udpLayer != nil {
|
||||
udp, _ := udpLayer.(*layers.UDP)
|
||||
srcPort = int(udp.SrcPort)
|
||||
dstPort = int(udp.DstPort)
|
||||
}
|
||||
|
||||
if containsIP(excludeIPs, srcIP) || containsIP(excludeIPs, dstIP) || containsPort(excludePorts, srcPort) || containsPort(excludePorts, dstPort) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(includeIPs) > 0 || len(includePorts) > 0 {
|
||||
return containsIP(includeIPs, srcIP) || containsIP(includeIPs, dstIP) || containsPort(includePorts, srcPort) || containsPort(includePorts, dstPort)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func containsIP(ips []net.IP, ip net.IP) bool {
|
||||
for _, listedIP := range ips {
|
||||
if ip.Equal(listedIP) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func containsPort(ports []int, port int) bool {
|
||||
for _, listedPort := range ports {
|
||||
if port == listedPort {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isLikelyPlainText(data []byte) bool {
|
||||
if len(data) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var printableCount, controlCount int
|
||||
for _, runeValue := range string(data) {
|
||||
if unicode.IsPrint(runeValue) || unicode.IsSpace(runeValue) {
|
||||
printableCount++
|
||||
} else if unicode.IsControl(runeValue) {
|
||||
controlCount++
|
||||
}
|
||||
}
|
||||
|
||||
totalChars := len(data)
|
||||
printableRatio := float64(printableCount) / float64(totalChars)
|
||||
controlRatio := float64(controlCount) / float64(totalChars)
|
||||
|
||||
return printableRatio > 0.7 && controlRatio < 0.3
|
||||
}
|
||||
|
||||
func printPacketInfo(packet gopacket.Packet) {
|
||||
var srcIP, dstIP net.IP
|
||||
var srcPort, dstPort int
|
||||
@ -312,57 +210,43 @@ func printWithColors(info PacketInfo) {
|
||||
if len(payloadDisplay) != 0 {
|
||||
if isLikelyPlainText([]byte(payloadDisplay)) {
|
||||
reg := regexp.MustCompile(`[\s\r\n\v\f]+`)
|
||||
payloadDisplay = reg.ReplaceAllString(payloadDisplay, " ")
|
||||
payloadDisplay = strings.TrimSpace(payloadDisplay)
|
||||
payloadDisplay = strings.TrimSpace(reg.ReplaceAllString(payloadDisplay, " "))
|
||||
format := "%sPayload: %s%s%s"
|
||||
if len(payloadDisplay) > 100 {
|
||||
payloadDisplay = fmt.Sprintf("%sPayload: %s%s... %s(%d)%s", ColorCyan, ColorPurple, payloadDisplay[:100], ColorDarkGrey, len(payloadDisplay), ColorReset)
|
||||
payloadDisplay = fmt.Sprintf(format, ColorCyan, ColorPurple, payloadDisplay[:100]+"... "+fmt.Sprintf("%s(%d)%s", ColorDarkGrey, len(payloadDisplay), ColorReset), ColorReset)
|
||||
} else {
|
||||
payloadDisplay = fmt.Sprintf("%sPayload: %s%s%s", ColorCyan, ColorPurple, payloadDisplay, ColorReset)
|
||||
payloadDisplay = fmt.Sprintf(format, ColorCyan, ColorPurple, payloadDisplay, ColorReset)
|
||||
}
|
||||
} else {
|
||||
payloadDisplay = fmt.Sprintf("%sPayload: %sNon-printable data %s(%d)%s", ColorCyan, ColorPurple, ColorDarkGrey, len(payloadDisplay), ColorReset)
|
||||
}
|
||||
}
|
||||
|
||||
srcPortDisplay := ""
|
||||
srcPortDisplay := fmt.Sprintf("%d", info.SourcePort)
|
||||
dstPortDisplay := fmt.Sprintf("%d", info.DestPort)
|
||||
if info.SourcePort == 0 {
|
||||
srcPortDisplay = ""
|
||||
} else {
|
||||
srcPortDisplay = fmt.Sprintf("%d", info.SourcePort)
|
||||
}
|
||||
|
||||
dstPortDisplay := ""
|
||||
if info.DestPort == 0 {
|
||||
dstPortDisplay = ""
|
||||
} else {
|
||||
dstPortDisplay = fmt.Sprintf("%d", info.DestPort)
|
||||
}
|
||||
|
||||
protocolColor := ""
|
||||
switch info.Protocol {
|
||||
case "TCP":
|
||||
protocolColor = ColorGreen
|
||||
case "UDP":
|
||||
protocolColor = ColorYellow
|
||||
case "ICMP":
|
||||
protocolColor = ColorPurple
|
||||
protocolColorMap := map[string]string{
|
||||
"TCP": ColorGreen,
|
||||
"UDP": ColorYellow,
|
||||
"ICMP": ColorPurple,
|
||||
}
|
||||
protocolColor := protocolColorMap[info.Protocol]
|
||||
|
||||
extraData := ""
|
||||
extraData := " "
|
||||
if info.Protocol == "ICMP" {
|
||||
extraData = fmt.Sprintf("%3s", info.ICMPData)
|
||||
} else if info.Protocol == "UDP" {
|
||||
extraData = " "
|
||||
} else if info.Protocol == "TCP" {
|
||||
if info.TCPFlags == "" {
|
||||
extraData = " "
|
||||
} else {
|
||||
extraData = info.TCPFlags
|
||||
}
|
||||
} else if info.Protocol == "TCP" && info.TCPFlags != "" {
|
||||
extraData = info.TCPFlags
|
||||
}
|
||||
|
||||
SEP := ColorDarkGrey + "│" + ColorReset
|
||||
fmt.Printf("%s %s %s %s %15s %-5s -> %15s %-5s %s %s %4d %s %s %3d %s %s %5d %s %s %5d %s %s %s %s\n",
|
||||
fmt.Printf("%s %s %s %s %15s %-5s -> %15s %-5s %s %s %5d %s %s %3d %s %s %5d %s %s %5d %s %s %s %s\n",
|
||||
ColorDarkGrey+info.Timestamp+ColorReset,
|
||||
SEP,
|
||||
protocolColor+fmt.Sprintf("%4s", info.Protocol)+ColorReset,
|
||||
@ -386,47 +270,3 @@ func printWithColors(info PacketInfo) {
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
func writeToFile(data []byte) {
|
||||
fileName := "packet_info.json"
|
||||
file, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
fmt.Println("Error opening file:", err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.Write(data)
|
||||
if err != nil {
|
||||
fmt.Println("Error writing to file:", err)
|
||||
return
|
||||
}
|
||||
_, err = file.WriteString("\n")
|
||||
if err != nil {
|
||||
fmt.Println("Error writing newline to file:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func getTCPFlags(tcp *layers.TCP) string {
|
||||
flagNames := map[bool]string{
|
||||
tcp.FIN: "FIN",
|
||||
tcp.SYN: "SYN",
|
||||
tcp.RST: "RST",
|
||||
tcp.PSH: "PSH",
|
||||
tcp.ACK: "ACK",
|
||||
tcp.URG: "URG",
|
||||
tcp.ECE: "ECE",
|
||||
tcp.CWR: "CWR",
|
||||
tcp.NS: "NS",
|
||||
}
|
||||
|
||||
var flags []string
|
||||
for flag, name := range flagNames {
|
||||
if flag {
|
||||
flags = append(flags, name)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(flags, ",")
|
||||
}
|
BIN
ddosmonit/dmon
BIN
ddosmonit/dmon
Binary file not shown.
@ -1,8 +1,8 @@
|
||||
module dmon
|
||||
module ddosmonit
|
||||
|
||||
go 1.21.5
|
||||
|
||||
require (
|
||||
github.com/google/gopacket v1.1.19 // indirect
|
||||
github.com/google/gopacket v1.1.19 // direct
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d // indirect
|
||||
)
|
||||
|
144
ddosmonit/utils.go
Normal file
144
ddosmonit/utils.go
Normal file
@ -0,0 +1,144 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
)
|
||||
|
||||
func containsIP(ips []net.IP, ip net.IP) bool {
|
||||
for _, listedIP := range ips {
|
||||
if ip.Equal(listedIP) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func containsPort(ports []int, port int) bool {
|
||||
for _, listedPort := range ports {
|
||||
if port == listedPort {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getInterfaceMAC(interfaceName string) (net.HardwareAddr, error) {
|
||||
iface, err := net.InterfaceByName(interfaceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return iface.HardwareAddr, nil
|
||||
}
|
||||
|
||||
func getTCPFlags(tcp *layers.TCP) string {
|
||||
flagNames := map[bool]string{
|
||||
tcp.FIN: "FIN",
|
||||
tcp.SYN: "SYN",
|
||||
tcp.RST: "RST",
|
||||
tcp.PSH: "PSH",
|
||||
tcp.ACK: "ACK",
|
||||
tcp.URG: "URG",
|
||||
tcp.ECE: "ECE",
|
||||
tcp.CWR: "CWR",
|
||||
tcp.NS: "NS",
|
||||
}
|
||||
var flags []string
|
||||
for flag, name := range flagNames {
|
||||
if flag {
|
||||
flags = append(flags, name)
|
||||
}
|
||||
}
|
||||
return strings.Join(flags, ",")
|
||||
}
|
||||
|
||||
func isLikelyPlainText(data []byte) bool {
|
||||
if len(data) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var printableCount, controlCount int
|
||||
for _, runeValue := range string(data) {
|
||||
if unicode.IsPrint(runeValue) || unicode.IsSpace(runeValue) {
|
||||
printableCount++
|
||||
} else if unicode.IsControl(runeValue) {
|
||||
controlCount++
|
||||
}
|
||||
}
|
||||
|
||||
totalChars := len(data)
|
||||
printableRatio := float64(printableCount) / float64(totalChars)
|
||||
controlRatio := float64(controlCount) / float64(totalChars)
|
||||
|
||||
return printableRatio > 0.7 && controlRatio < 0.3
|
||||
}
|
||||
|
||||
func parseAndValidateIPsAndPorts(list string) ([]net.IP, []int) {
|
||||
var ips []net.IP
|
||||
var ports []int
|
||||
|
||||
items := strings.Split(list, ",")
|
||||
for _, item := range items {
|
||||
item = strings.TrimSpace(item)
|
||||
if ip := net.ParseIP(item); ip != nil {
|
||||
ips = append(ips, ip)
|
||||
} else if port, err := strconv.Atoi(item); err == nil {
|
||||
ports = append(ports, port)
|
||||
}
|
||||
}
|
||||
|
||||
return ips, ports
|
||||
}
|
||||
|
||||
func shouldProcessPacket(packet gopacket.Packet, excludeIPs []net.IP, excludePorts []int, includeIPs []net.IP, includePorts []int) bool {
|
||||
var srcIP, dstIP net.IP
|
||||
var srcPort, dstPort int
|
||||
|
||||
if ipv4Layer := packet.Layer(layers.LayerTypeIPv4); ipv4Layer != nil {
|
||||
ipv4 := ipv4Layer.(*layers.IPv4)
|
||||
srcIP, dstIP = ipv4.SrcIP, ipv4.DstIP
|
||||
}
|
||||
|
||||
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
|
||||
tcp := tcpLayer.(*layers.TCP)
|
||||
srcPort, dstPort = int(tcp.SrcPort), int(tcp.DstPort)
|
||||
} else if udpLayer := packet.Layer(layers.LayerTypeUDP); udpLayer != nil {
|
||||
udp := udpLayer.(*layers.UDP)
|
||||
srcPort, dstPort = int(udp.SrcPort), int(udp.DstPort)
|
||||
}
|
||||
|
||||
isExcluded := containsIP(excludeIPs, srcIP) || containsIP(excludeIPs, dstIP) ||
|
||||
containsPort(excludePorts, srcPort) || containsPort(excludePorts, dstPort)
|
||||
isIncluded := (len(includeIPs) == 0 || containsIP(includeIPs, srcIP) || containsIP(includeIPs, dstIP)) &&
|
||||
(len(includePorts) == 0 || containsPort(includePorts, srcPort) || containsPort(includePorts, dstPort))
|
||||
|
||||
return !isExcluded && isIncluded
|
||||
}
|
||||
|
||||
func writeToFile(data []byte) {
|
||||
fileName := "packet_info.json"
|
||||
file, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
fmt.Println("Error opening file:", err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.Write(data)
|
||||
if err != nil {
|
||||
fmt.Println("Error writing to file:", err)
|
||||
return
|
||||
}
|
||||
_, err = file.WriteString("\n")
|
||||
if err != nil {
|
||||
fmt.Println("Error writing newline to file:", err)
|
||||
return
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user