Reformat code

This commit is contained in:
maride 2023-09-02 23:49:02 +02:00
parent 1989ae996f
commit 21c956c545
26 changed files with 102 additions and 101 deletions

View File

@ -2,15 +2,16 @@ package analyze
import ( import (
"fmt" "fmt"
"log"
"github.com/google/gopacket"
"github.com/maride/pancap/output" "github.com/maride/pancap/output"
"github.com/maride/pancap/protocol" "github.com/maride/pancap/protocol"
"github.com/google/gopacket"
"log"
) )
var ( var (
// Store total amount and amount of visited packets // Store total amount and amount of visited packets
totalPackets int totalPackets int
processedPackets int processedPackets int
) )
@ -71,4 +72,3 @@ func handleErr(err error) {
log.Printf("Encountered error while examining packets, continuing anyway. Error: %s", err.Error()) log.Printf("Encountered error while examining packets, continuing anyway. Error: %s", err.Error())
} }
} }

View File

@ -23,10 +23,10 @@ func GenerateTree(strarr []string) string {
// iterate over each element // iterate over each element
for iter, elem := range strarr { for iter, elem := range strarr {
// check if we got the last element // check if we got the last element
if iter < len(strarr) - 1 { if iter < len(strarr)-1 {
tmpstr = fmt.Sprintf("%s├ %s\n", tmpstr, elem) tmpstr = fmt.Sprintf("%s├ %s\n", tmpstr, elem)
} else { } else {
tmpstr = fmt.Sprintf( "%s╰ %s\n", tmpstr, elem) tmpstr = fmt.Sprintf("%s╰ %s\n", tmpstr, elem)
} }
} }

View File

@ -3,29 +3,30 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap" "github.com/google/gopacket/pcap"
) )
var ( var (
filenameFlag *string filenameFlag string
) )
// Registers the flag --file // Registers the flag --file
func registerFileFlags() { func registerFileFlags() {
filenameFlag = flag.String("file", "", "PCAP file to base analysis on") flag.StringVar(&filenameFlag, "file", "", "PCAP file to base analysis on")
} }
// Opens the PCAP, returns its packets and the link type or an error // Opens the PCAP, returns its packets and the link type or an error
func openPCAP() (*gopacket.PacketSource, layers.LinkType, error) { func openPCAP() (*gopacket.PacketSource, layers.LinkType, error) {
// Check if we even got a file. // Check if we even got a file.
if *filenameFlag == "" { if filenameFlag == "" {
return nil, 0, fmt.Errorf("missing file to analyze. Please specifiy it with --file") return nil, 0, fmt.Errorf("missing file to analyze. Please specifiy it with --file")
} }
// Open specified file // Open specified file
handle, openErr := pcap.OpenOffline(*filenameFlag) handle, openErr := pcap.OpenOffline(filenameFlag)
if openErr != nil { if openErr != nil {
// There were some problems opening the file // There were some problems opening the file
return nil, 0, openErr return nil, 0, openErr

View File

@ -3,11 +3,12 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/maride/pancap/analyze"
"github.com/maride/pancap/output"
"log" "log"
"math/rand" "math/rand"
"time" "time"
"github.com/maride/pancap/analyze"
"github.com/maride/pancap/output"
) )
func main() { func main() {

View File

@ -6,10 +6,10 @@ import (
) )
type File struct { type File struct {
name string name string
content []byte content []byte
origin string origin string
hash string hash string
} }
// Creates a new file object and calculates the hash of the given content // Creates a new file object and calculates the hash of the given content
@ -21,4 +21,4 @@ func NewFile(name string, content []byte, origin string) File {
origin: origin, origin: origin,
hash: hash, hash: hash,
} }
} }

View File

@ -46,12 +46,12 @@ func StoreFiles() {
var filesToExtract []File var filesToExtract []File
// Check different flag scenarios // Check different flag scenarios
if *targetAllFiles { if targetAllFiles {
// We should extract all files. // We should extract all files.
filesToExtract = registeredFiles filesToExtract = registeredFiles
} else { } else {
// We should extract only a given set of files // We should extract only a given set of files
fileList := strings.Split(*targetFiles, ",") fileList := strings.Split(targetFiles, ",")
for _, f := range fileList { for _, f := range fileList {
// Iterate over desired files // Iterate over desired files
found := false found := false
@ -80,7 +80,7 @@ func StoreFiles() {
// Writes the given file object to disk, along with a stats file placed next to it. // Writes the given file object to disk, along with a stats file placed next to it.
func writeOut(f File) { func writeOut(f File) {
targetName := fmt.Sprintf("%s%c%s", *targetOutput, os.PathSeparator, f.hash) targetName := fmt.Sprintf("%s%c%s", targetOutput, os.PathSeparator, f.hash)
targetDescName := fmt.Sprintf("%s.info", targetName) targetDescName := fmt.Sprintf("%s.info", targetName)
targetDescription := fmt.Sprintf("Filename: %s\nHash: %s\nOrigin: %s\nSize: %d", f.name, f.hash, f.origin, len(f.content)) targetDescription := fmt.Sprintf("Filename: %s\nHash: %s\nOrigin: %s\nSize: %d", f.name, f.hash, f.origin, len(f.content))

View File

@ -3,19 +3,19 @@ package output
import "flag" import "flag"
var ( var (
fullOutput *bool fullOutput bool
printEmptyBlocks *bool printEmptyBlocks bool
targetFiles *string targetFiles string
targetAllFiles *bool targetAllFiles bool
targetOutput *string targetOutput string
graphOutput *string graphOutput string
) )
func RegisterFlags() { func RegisterFlags() {
fullOutput = flag.Bool("full-output", false, "Show full output instead of limiting submodule output") flag.BoolVar(&fullOutput, "full-output", false, "Show full output instead of limiting submodule output")
printEmptyBlocks = flag.Bool("print-empty-blocks", false, "Prints blocks (submodule output) even if the submodule doesn't have any content to print.") flag.BoolVar(&printEmptyBlocks, "print-empty-blocks", false, "Prints blocks (submodule output) even if the submodule doesn't have any content to print.")
targetFiles = flag.String("extract-these", "", "Comma-separated list of files to extract.") flag.StringVar(&targetFiles, "extract-these", "", "Comma-separated list of files to extract.")
targetAllFiles = flag.Bool("extract-all", false, "Extract all files found.") flag.BoolVar(&targetAllFiles, "extract-all", false, "Extract all files found.")
targetOutput = flag.String("extract-to", "./extracted", "Directory to store extracted files in.") flag.StringVar(&targetOutput, "extract-to", "./extracted", "Directory to store extracted files in.")
graphOutput = flag.String("create-graph", "", "Create a Graphviz graph out of collected communication") flag.StringVar(&graphOutput, "create-graph", "", "Create a Graphviz graph out of collected communication")
} }

View File

@ -1,11 +1,10 @@
package output package output
import ( import (
"crypto/sha256"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"crypto/sha256"
"github.com/google/gopacket" "github.com/google/gopacket"
) )
@ -40,13 +39,13 @@ func AddPkgToGraph(pkg gopacket.Packet) {
// CreateGraph writes out a Graphviz digraph // CreateGraph writes out a Graphviz digraph
func CreateGraph() { func CreateGraph() {
if *graphOutput == "" { if graphOutput == "" {
// No graph requested // No graph requested
return return
} }
// Start with the Graphviz-specific header // Start with the Graphviz-specific header
dot := fmt.Sprintf("# Compile with `neato -Tpng %s > %s.png`\n", *graphOutput, *graphOutput) dot := fmt.Sprintf("# Compile with `neato -Tpng %s > %s.png`\n", graphOutput, graphOutput)
dot += "digraph pancap {\n\toverlap = false;\n" dot += "digraph pancap {\n\toverlap = false;\n"
// First, gather all nodes as-is and write them out // First, gather all nodes as-is and write them out
@ -61,7 +60,7 @@ func CreateGraph() {
dot += "}\n" dot += "}\n"
// Write out // Write out
ioutil.WriteFile(*graphOutput, []byte(dot), 0644) ioutil.WriteFile(graphOutput, []byte(dot), 0644)
} }
// Creates a list of distinct nodes, Graphviz-compatible // Creates a list of distinct nodes, Graphviz-compatible

View File

@ -25,7 +25,7 @@ func Finalize() {
} }
// Check if something graph-worthy was collected // Check if something graph-worthy was collected
if *graphOutput == "" && len(graphPkgs) > 0 { if graphOutput == "" && len(graphPkgs) > 0 {
// User didn't want a graph // User didn't want a graph
printer.Println("To summarize the communcation flow with a Graphviz graph, specify --create-graph <out.dot>.") printer.Println("To summarize the communcation flow with a Graphviz graph, specify --create-graph <out.dot>.")
} }

View File

@ -2,17 +2,18 @@ package output
import ( import (
"fmt" "fmt"
"github.com/fatih/color"
"strings" "strings"
"github.com/fatih/color"
) )
const ( const (
MaxContentLines = 50 MaxContentLines = 50
SnipMark = "----- cut at 50 entries -----" SnipMark = "----- cut at 50 entries -----"
) )
var ( var (
DidSnip bool DidSnip bool
DidAvoidEmptyBlock bool DidAvoidEmptyBlock bool
) )
@ -21,7 +22,7 @@ var (
// If the content is longer than MaxContentLines, content is cut. // If the content is longer than MaxContentLines, content is cut.
func PrintBlock(headline string, content string) { func PrintBlock(headline string, content string) {
// Avoid printing empty blocks - at least if user didn't specify it otherwise // Avoid printing empty blocks - at least if user didn't specify it otherwise
if len(content) == 0 && !*printEmptyBlocks { if len(content) == 0 && !printEmptyBlocks {
// No content and we are not forced to print empty blocks, return // No content and we are not forced to print empty blocks, return
DidAvoidEmptyBlock = true DidAvoidEmptyBlock = true
return return
@ -38,7 +39,7 @@ func PrintBlock(headline string, content string) {
} }
// Cut to MaxContentLines if required // Cut to MaxContentLines if required
if !(*fullOutput) { if !(fullOutput) {
// User states that they don't want to see the whole output - cut content. // User states that they don't want to see the whole output - cut content.
content = cutContent(content) content = cutContent(content)
} }

View File

@ -2,24 +2,24 @@ package arp
import ( import (
"fmt" "fmt"
"github.com/maride/pancap/common"
"github.com/maride/pancap/output"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
"github.com/maride/pancap/output"
"log" "log"
"net" "net"
) )
var ( var (
arpStatsList []arpStats arpStatsList []arpStats
devices []arpDevice devices []arpDevice
linkLocalBlock = net.IPNet{ linkLocalBlock = net.IPNet{
IP: net.IPv4(169, 254, 0, 0), IP: net.IPv4(169, 254, 0, 0),
Mask: net.IPv4Mask(255, 255, 0, 0), Mask: net.IPv4Mask(255, 255, 0, 0),
} }
) )
type Protocol struct {} type Protocol struct{}
// Checks if the given packet is an ARP packet we can process // Checks if the given packet is an ARP packet we can process
func (p *Protocol) CanAnalyze(packet gopacket.Packet) bool { func (p *Protocol) CanAnalyze(packet gopacket.Packet) bool {
@ -118,7 +118,7 @@ func (p *Protocol) getStatOrCreate(macaddr string) *arpStats {
// None found yet, we need to create a new one // None found yet, we need to create a new one
arpStatsList = append(arpStatsList, arpStats{ arpStatsList = append(arpStatsList, arpStats{
macaddr: macaddr, macaddr: macaddr,
}) })
// And return it // And return it

View File

@ -2,5 +2,5 @@ package arp
type arpDevice struct { type arpDevice struct {
macaddr string macaddr string
ipaddr string ipaddr string
} }

View File

@ -1,9 +1,9 @@
package arp package arp
type arpStats struct { type arpStats struct {
macaddr string macaddr string
asked int asked int
answered int answered int
askedList []string askedList []string
answeredList []string answeredList []string
} }

View File

@ -1,16 +1,16 @@
package dhcpv4 package dhcpv4
import ( import (
"github.com/maride/pancap/output"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/output"
) )
type Protocol struct { type Protocol struct {
hostnames []hostname hostnames []hostname
networkSetup map[layers.DHCPOpt][]byte networkSetup map[layers.DHCPOpt][]byte
requestMAC []string requestMAC []string
responses []dhcpResponse responses []dhcpResponse
} }
// Checks if the given packet is a DHCP packet we can process // Checks if the given packet is a DHCP packet we can process

View File

@ -1,9 +1,8 @@
package dhcpv4 package dhcpv4
type dhcpResponse struct { type dhcpResponse struct {
destMACAddr string destMACAddr string
newIPAddr string newIPAddr string
serverMACAddr string serverMACAddr string
askedFor bool askedFor bool
} }

View File

@ -1,8 +1,8 @@
package dhcpv4 package dhcpv4
type hostname struct { type hostname struct {
hostname string hostname string
requestedByMAC string requestedByMAC string
granted bool granted bool
deniedHostname string deniedHostname string
} }

View File

@ -2,8 +2,8 @@ package dhcpv4
import ( import (
"fmt" "fmt"
"github.com/maride/pancap/common"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
"log" "log"
) )

View File

@ -12,13 +12,13 @@ import (
var ( var (
watchedOpts = []layers.DHCPOpt{ watchedOpts = []layers.DHCPOpt{
layers.DHCPOptSubnetMask, // Option 1 layers.DHCPOptSubnetMask, // Option 1
layers.DHCPOptRouter, // Option 3 layers.DHCPOptRouter, // Option 3
layers.DHCPOptDNS, // Option 6 layers.DHCPOptDNS, // Option 6
layers.DHCPOptBroadcastAddr, // Option 28 layers.DHCPOptBroadcastAddr, // Option 28
layers.DHCPOptNTPServers, // Option 42 layers.DHCPOptNTPServers, // Option 42
layers.DHCPOptLeaseTime, // Option 51 layers.DHCPOptLeaseTime, // Option 51
layers.DHCPOptT1, // Option 58 layers.DHCPOptT1, // Option 58
} }
) )
@ -126,7 +126,7 @@ func formatDate(rawDate []byte) (string, bool) {
intDate := binary.LittleEndian.Uint32(rawDate) intDate := binary.LittleEndian.Uint32(rawDate)
seconds := intDate % 60 seconds := intDate % 60
minutes := intDate / 60 % 60 minutes := intDate / 60 % 60
hours := intDate / 60 / 60 % 60 hours := intDate / 60 / 60 % 60
formattedDate := "" formattedDate := ""
// Check which words we need to pick // Check which words we need to pick

View File

@ -2,8 +2,8 @@ package dhcpv4
import ( import (
"fmt" "fmt"
"github.com/maride/pancap/common"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
) )
// Processes the DHCP request packet handed over // Processes the DHCP request packet handed over

View File

@ -2,8 +2,8 @@ package dhcpv4
import ( import (
"fmt" "fmt"
"github.com/maride/pancap/common"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
"log" "log"
) )

View File

@ -2,20 +2,20 @@ package dns
import ( import (
"fmt" "fmt"
"github.com/maride/pancap/common"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
"golang.org/x/net/publicsuffix" "golang.org/x/net/publicsuffix"
"log" "log"
) )
var ( var (
numAnswers int numAnswers int
answerDomains []string answerDomains []string
answerBaseDomains []string answerBaseDomains []string
answerPrivateDomains []string answerPrivateDomains []string
answerType = make(map[layers.DNSType]int) answerType = make(map[layers.DNSType]int)
answerPublicIPv4 []string answerPublicIPv4 []string
answerPrivateIPv4 []string answerPrivateIPv4 []string
) )
// Called on every DNS packet to process response(s) // Called on every DNS packet to process response(s)

View File

@ -8,7 +8,7 @@ import (
var ( var (
privateBlocks = []net.IPNet{ privateBlocks = []net.IPNet{
{net.IPv4(10, 0, 0, 0), net.IPv4Mask(255, 0, 0, 0)}, // 10.0.0.0/8 {net.IPv4(10, 0, 0, 0), net.IPv4Mask(255, 0, 0, 0)}, // 10.0.0.0/8
{net.IPv4(172, 16, 0, 0), net.IPv4Mask(255, 240, 0, 0)}, // 172.16.0.0/12 {net.IPv4(172, 16, 0, 0), net.IPv4Mask(255, 240, 0, 0)}, // 172.16.0.0/12
{net.IPv4(192, 168, 0, 0), net.IPv4Mask(255, 255, 0, 0)}, // 192.168.0.0/24 {net.IPv4(192, 168, 0, 0), net.IPv4Mask(255, 255, 0, 0)}, // 192.168.0.0/24
{net.IPv4(100, 64, 0, 0), net.IPv4Mask(255, 192, 0, 0)}, // 100.64.0.0/10 {net.IPv4(100, 64, 0, 0), net.IPv4Mask(255, 192, 0, 0)}, // 100.64.0.0/10
@ -58,7 +58,7 @@ func (p *Protocol) generateDNSTypeSummary(typearr map[layers.DNSType]int) string
if iter == 0 { if iter == 0 {
// We don't need to append yet // We don't need to append yet
answerstr = elem answerstr = elem
} else if iter == len(answerarr) - 1 { } else if iter == len(answerarr)-1 {
// Last element, use "and" instead of a comma // Last element, use "and" instead of a comma
answerstr = fmt.Sprintf("%s and %s", answerstr, elem) answerstr = fmt.Sprintf("%s and %s", answerstr, elem)
} else { } else {
@ -68,4 +68,4 @@ func (p *Protocol) generateDNSTypeSummary(typearr map[layers.DNSType]int) string
} }
return answerstr return answerstr
} }

View File

@ -1,12 +1,12 @@
package dns package dns
import ( import (
"github.com/maride/pancap/output"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/output"
) )
type Protocol struct {} type Protocol struct{}
func (p *Protocol) CanAnalyze(packet gopacket.Packet) bool { func (p *Protocol) CanAnalyze(packet gopacket.Packet) bool {
return packet.Layer(layers.LayerTypeDNS) != nil return packet.Layer(layers.LayerTypeDNS) != nil

View File

@ -2,18 +2,18 @@ package dns
import ( import (
"fmt" "fmt"
"github.com/maride/pancap/common"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/maride/pancap/common"
"golang.org/x/net/publicsuffix" "golang.org/x/net/publicsuffix"
"log" "log"
) )
var ( var (
numQuestions int numQuestions int
questionDomains []string questionDomains []string
questionBaseDomains []string questionBaseDomains []string
questionPrivateDomains []string questionPrivateDomains []string
questionType = make(map[layers.DNSType]int) questionType = make(map[layers.DNSType]int)
) )
// Called on every DNS packet to process questions // Called on every DNS packet to process questions
@ -72,4 +72,4 @@ func (p *Protocol) generateDNSQuestionSummary() string {
// And return summary // And return summary
return summary return summary
} }

View File

@ -1,20 +1,20 @@
package http package http
import ( import (
"github.com/maride/pancap/common"
"github.com/maride/pancap/output"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/google/gopacket/tcpassembly" "github.com/google/gopacket/tcpassembly"
"github.com/maride/pancap/common"
"github.com/maride/pancap/output"
) )
type Protocol struct { type Protocol struct {
initialized bool initialized bool
requestFactory *httpRequestFactory requestFactory *httpRequestFactory
responseFactory *httpResponseFactory responseFactory *httpResponseFactory
requestPool *tcpassembly.StreamPool requestPool *tcpassembly.StreamPool
responsePool *tcpassembly.StreamPool responsePool *tcpassembly.StreamPool
requestAssembler *tcpassembly.Assembler requestAssembler *tcpassembly.Assembler
responseAssembler *tcpassembly.Assembler responseAssembler *tcpassembly.Assembler
} }

View File

@ -3,17 +3,17 @@ package http
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"github.com/maride/pancap/output"
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/tcpassembly" "github.com/google/gopacket/tcpassembly"
"github.com/google/gopacket/tcpassembly/tcpreader" "github.com/google/gopacket/tcpassembly/tcpreader"
"github.com/maride/pancap/output"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
) )
var ( var (
responseSummaryLines []string responseSummaryLines []string
) )
type httpResponseFactory struct{} type httpResponseFactory struct{}