Skip to content

Commit

Permalink
Moved regex
Browse files Browse the repository at this point in the history
  • Loading branch information
alex27riva committed Oct 19, 2024
1 parent d37d9ea commit 5bf0032
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 131 deletions.
244 changes: 122 additions & 122 deletions cmd/email.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,50 @@ See the LICENSE file for details.
package cmd

import (
"fmt"
"io"
"mime"
"mime/multipart"
"net/mail"
"os"
"strings"
"github.com/spf13/cobra"
"fmt"
"github.com/spf13/cobra"
"io"
"mime"
"mime/multipart"
"net/mail"
"os"
"soc-cli/internal/util"
"strings"
)

var analyzeEmailCmd = &cobra.Command{
Use: "email [file]",
Short: "Analyze an email in .eml format for attachments and links",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
filePath := args[0]
analyzeEmail(filePath)
},
Use: "email [file]",
Short: "Analyze an email in .eml format for attachments and links",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
filePath := args[0]
analyzeEmail(filePath)
},
}

func init() {
rootCmd.AddCommand(analyzeEmailCmd)
rootCmd.AddCommand(analyzeEmailCmd)
}

// analyzeEmail processes the .eml file and extracts attachments and links
func analyzeEmail(filePath string) {
file, err := os.Open(filePath)
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer file.Close()

// Parse the email message
msg, err := mail.ReadMessage(file)
if err != nil {
fmt.Println("Error parsing .eml file:", err)
return
}

fmt.Println("Subject:", msg.Header.Get("Subject"))
fmt.Println("From:", msg.Header.Get("From"))
fmt.Println("To:", msg.Header.Get("To"))
file, err := os.Open(filePath)
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer file.Close()

// Parse the email message
msg, err := mail.ReadMessage(file)
if err != nil {
fmt.Println("Error parsing .eml file:", err)
return
}

fmt.Println("Subject:", msg.Header.Get("Subject"))
fmt.Println("From:", msg.Header.Get("From"))
fmt.Println("To:", msg.Header.Get("To"))

// Check for SPF information
spfHeader := msg.Header.Get("Received-SPF")
Expand All @@ -59,105 +60,104 @@ func analyzeEmail(filePath string) {
fmt.Println("\nSPF Information: No Received-SPF header found.")
}

// Extract DKIM Information
dkimHeader := msg.Header.Get("DKIM-Signature")
if dkimHeader != "" {
fmt.Println("\nDKIM Information:")
fmt.Println(dkimHeader)
} else {
fmt.Println("\nDKIM Information: No DKIM-Signature header found.")
}

// Extract DMARC Information from Authentication-Results header
authResults := msg.Header.Get("Authentication-Results")
if authResults != "" {
extractDMARCDKIM(authResults)
} else {
fmt.Println("\nDMARC Information: No Authentication-Results header found.")
}

mediaType, params, err := mime.ParseMediaType(msg.Header.Get("Content-Type"))
if err != nil {
fmt.Println("Error parsing content type:", err)
return
}

if strings.HasPrefix(mediaType, "multipart/") {
// Handle multipart emails (usually contains attachments and text)
mr := multipart.NewReader(msg.Body, params["boundary"])
processMultipart(mr)
} else {
// Handle single-part emails (just extract links)
body, _ := io.ReadAll(msg.Body)
extractLinks(string(body))
}
// Extract DKIM Information
dkimHeader := msg.Header.Get("DKIM-Signature")
if dkimHeader != "" {
fmt.Println("\nDKIM Information:")
fmt.Println(dkimHeader)
} else {
fmt.Println("\nDKIM Information: No DKIM-Signature header found.")
}

// Extract DMARC Information from Authentication-Results header
authResults := msg.Header.Get("Authentication-Results")
if authResults != "" {
extractDMARCDKIM(authResults)
} else {
fmt.Println("\nDMARC Information: No Authentication-Results header found.")
}

mediaType, params, err := mime.ParseMediaType(msg.Header.Get("Content-Type"))
if err != nil {
fmt.Println("Error parsing content type:", err)
return
}

if strings.HasPrefix(mediaType, "multipart/") {
// Handle multipart emails (usually contains attachments and text)
mr := multipart.NewReader(msg.Body, params["boundary"])
processMultipart(mr)
} else {
// Handle single-part emails (just extract links)
body, _ := io.ReadAll(msg.Body)
extractLinks(string(body))
}
}

// processMultipart processes multipart emails for attachments and links
func processMultipart(mr *multipart.Reader) {
for {
part, err := mr.NextPart()
if err == io.EOF {
break
}
if err != nil {
fmt.Println("Error reading part:", err)
return
}

contentType := part.Header.Get("Content-Type")
disposition := part.Header.Get("Content-Disposition")

// If it's an attachment, list it
if strings.Contains(disposition, "attachment") {
fileName := part.FileName()
if fileName == "" {
fileName = "unnamed attachment"
}
fmt.Printf("Attachment: %s (MIME type: %s)\n", fileName, contentType)
} else {
// Otherwise, it's likely part of the email body (text or HTML)
body, _ := io.ReadAll(part)
extractLinks(string(body))
}
}
for {
part, err := mr.NextPart()
if err == io.EOF {
break
}
if err != nil {
fmt.Println("Error reading part:", err)
return
}

contentType := part.Header.Get("Content-Type")
disposition := part.Header.Get("Content-Disposition")

// If it's an attachment, list it
if strings.Contains(disposition, "attachment") {
fileName := part.FileName()
if fileName == "" {
fileName = "unnamed attachment"
}
fmt.Printf("Attachment: %s (MIME type: %s)\n", fileName, contentType)
} else {
// Otherwise, it's likely part of the email body (text or HTML)
body, _ := io.ReadAll(part)
extractLinks(string(body))
}
}
}

// extractDMARCDKIM extracts DMARC and DKIM results from the Authentication-Results header
func extractDMARCDKIM(authResults string) {
fmt.Println("\nAuthentication Results:")
fmt.Println(authResults)

// Check for DKIM result
if strings.Contains(authResults, "dkim=pass") {
fmt.Println("DKIM: pass")
} else if strings.Contains(authResults, "dkim=fail") {
fmt.Println("DKIM: fail")
} else {
fmt.Println("DKIM: No DKIM result found.")
}

// Check for DMARC result
if strings.Contains(authResults, "dmarc=pass") {
fmt.Println("DMARC: pass")
} else if strings.Contains(authResults, "dmarc=fail") {
fmt.Println("DMARC: fail")
} else {
fmt.Println("DMARC: No DMARC result found.")
}
}
fmt.Println("\nAuthentication Results:")
fmt.Println(authResults)

// Check for DKIM result
if strings.Contains(authResults, "dkim=pass") {
fmt.Println("DKIM: pass")
} else if strings.Contains(authResults, "dkim=fail") {
fmt.Println("DKIM: fail")
} else {
fmt.Println("DKIM: No DKIM result found.")
}

// Check for DMARC result
if strings.Contains(authResults, "dmarc=pass") {
fmt.Println("DMARC: pass")
} else if strings.Contains(authResults, "dmarc=fail") {
fmt.Println("DMARC: fail")
} else {
fmt.Println("DMARC: No DMARC result found.")
}
}

// extractLinks extracts URLs from email body text or HTML
func extractLinks(body string) {
links := URLRegex.FindAllString(body, -1)

if len(links) > 0 {
fmt.Println("\nLinks found in the email:")
for _, link := range links {
fmt.Println("-", link)
}
} else {
fmt.Println("\nNo links found in the email.")
}
links := util.URLRegex.FindAllString(body, -1)

if len(links) > 0 {
fmt.Println("\nLinks found in the email:")
for _, link := range links {
fmt.Println("-", link)
}
} else {
fmt.Println("\nNo links found in the email.")
}
}
9 changes: 5 additions & 4 deletions cmd/extractIoc.go → cmd/extract_ioc.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/spf13/cobra"
"log"
"os"
"soc-cli/internal/util"
)

type iocOutput struct {
Expand Down Expand Up @@ -47,10 +48,10 @@ func extractIOCs(filePath string, asJSON bool) {
}

// Find all IOCs
uniqueURLs := removeDuplicates(URLRegex.FindAllString(string(data), -1))
uniqueIPs := removeDuplicates(IPRegex.FindAllString(string(data), -1))
uniqueEmails := removeDuplicates(EmailRegex.FindAllString(string(data), -1))
uniqueHashes := removeDuplicates(SHA256Regex.FindAllString(string(data), -1))
uniqueURLs := removeDuplicates(util.URLRegex.FindAllString(string(data), -1))
uniqueIPs := removeDuplicates(util.IPRegex.FindAllString(string(data), -1))
uniqueEmails := removeDuplicates(util.EmailRegex.FindAllString(string(data), -1))
uniqueHashes := removeDuplicates(util.SHA256Regex.FindAllString(string(data), -1))

if asJSON {
// Prepare data for JSON output
Expand Down
5 changes: 3 additions & 2 deletions cmd/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import (
"log"
"os"
"soc-cli/internal/apis"
"soc-cli/internal/util"
)

func analyzeIP(ip string) {

// Validate provided IP address
if IPRegex.MatchString(ip) {
if RFC1918Regex.MatchString(ip) {
if util.IPRegex.MatchString(ip) {
if util.RFC1918Regex.MatchString(ip) {
fmt.Printf("The IP provided %s is a RFC1918 bogus IP address.\n", ip)
os.Exit(0)
} else if ip == "127.0.0.1" {
Expand Down
4 changes: 2 additions & 2 deletions cmd/whois.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ func displayData(domainInfo apis.DomainInfo) {
fmt.Printf("Updated Date: %s\n", domainInfo.Domain.UpdatedDate)
fmt.Printf("Expiration Date: %s\n", domainInfo.Domain.ExpirationDate)

color.Blue("\nRegistrar Information:")
color.Blue("\nRegistrar Information")
fmt.Printf("Registrar Name: %s\n", domainInfo.Registrar.Name)
fmt.Printf("Registrar Phone: %s\n", domainInfo.Registrar.Phone)
fmt.Printf("Registrar Email: %s\n", domainInfo.Registrar.Email)

color.Blue("\nRegistrant Information:")
color.Blue("\nRegistrant Information")
fmt.Printf("Registrant Name: %s\n", domainInfo.Registrant.Name)
fmt.Printf("Registrant Organization: %s\n", domainInfo.Registrant.Organization)
fmt.Printf("Registrant Country: %s\n", domainInfo.Registrant.Country)
Expand Down
2 changes: 1 addition & 1 deletion cmd/constants.go → internal/util/regex.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Copyright © 2024 Alessandro Riva
Licensed under the MIT License.
See the LICENSE file for details.
*/
package cmd
package util

import "regexp"

Expand Down

0 comments on commit 5bf0032

Please sign in to comment.