Skip to content

Instantly share code, notes, and snippets.

@TotallyNotAHaxxer
Last active April 26, 2023 04:30
Show Gist options
  • Select an option

  • Save TotallyNotAHaxxer/95f1a293b87c01bcdb60744c78cb1ebd to your computer and use it in GitHub Desktop.

Select an option

Save TotallyNotAHaxxer/95f1a293b87c01bcdb60744c78cb1ebd to your computer and use it in GitHub Desktop.
Simple HTTP parsing program in gopacket for my book BHGM
package main
import (
"bufio"
"bytes"
"encoding/base64"
"fmt"
"log"
"net/http"
"regexp"
"strings"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
type HTTPInformation struct {
Hostname string
UserAgent string
URL string
NTLM_Encoded string
NTLM_Decoded string
BASIC_Encoded string
BASIC_Decoded string
DIGEST string
Negotiate string
Session string
Headers []string
}
func DECB64(s string) string {
f, _ := base64.StdEncoding.DecodeString(s)
return string(f)
}
func VALB64(s string) bool {
_, x := base64.StdEncoding.DecodeString(s)
return x == nil
}
func Read_TCP_TO_HTTP(packet gopacket.Packet) (INFO HTTPInformation) {
var data HTTPInformation
if lp := packet.Layer(layers.LayerTypeIPv4); lp != nil {
lpp := lp.(*layers.IPv4)
if lpp.SrcIP.String() != "" {
data.Hostname = lpp.SrcIP.String()
}
}
if lay := packet.Layer(layers.LayerTypeTCP); lay != nil {
if tcp := lay.(*layers.TCP); tcp != nil {
if len(tcp.Payload) != 0 {
r := bufio.NewReader(bytes.NewReader(tcp.Payload))
line, x := http.ReadRequest(r)
if x == nil {
switch line.Proto {
case "HTTP/1.0", "HTTP/1.1", "HTTP/2", "HTTP/2.0", "HTTP/3", "HTTP/3.0", "HTTP/4.0":
if l := line.Host; l != "" {
data.Hostname = l
if line.UserAgent() != "" {
data.UserAgent = line.UserAgent()
}
}
// url
if u := line.URL; u != nil {
if h := line.Host; h != "" {
data.URL = "http://" + h + u.String()
}
}
// Detect NTLM hash
reg := regexp.MustCompile("(?i)Authorization: NTLM (.*)")
dt := reg.FindAllStringSubmatch(string(tcp.Payload), 1)
if dt != nil {
for p := range dt {
data.NTLM_Encoded = strings.Trim(dt[p][0], "Authorization: NTLM")
}
}
// Detect BASIC authentication | Decode and encoded
regf := regexp.MustCompile("(?i)Authorization: Basic (.*)")
dtf := regf.FindAllStringSubmatch(string(tcp.Payload), 1)
if dtf != nil {
for p := range dtf {
if VALB64(string(strings.Trim(dtf[p][0], "Authorization: Basic "))) {
DECB64((strings.Trim(dtf[p][0], "Authorization: Basic ")))
data.BASIC_Encoded = strings.Trim(dtf[p][0], "Authorization: Basic ")
data.BASIC_Decoded = DECB64((strings.Trim(dtf[p][0], "Authorization: Basic ")))
}
}
}
// Detect HTTP Digest Authentication
regf2 := regexp.MustCompile("(?i)Authorization: Digest (.*)")
dtf2 := regf2.FindAllStringSubmatch(string(tcp.Payload), 1)
if dtf2 != nil {
for p := range dtf2 {
data.DIGEST = string(strings.Trim(dtf2[p][0], "Authorization: Digest "))
}
}
// Detect HTTP Negotiate Authentication
regf3 := regexp.MustCompile("(?i)Authorization: Negotiate (.*)")
dtf3 := regf3.FindAllStringSubmatch(string(tcp.Payload), 1)
if dtf3 != nil {
for p := range dtf3 {
data.Negotiate = string(strings.Trim(dtf3[p][0], "Authorization: Negotiate "))
}
}
// Append HTTP layer data
var head string
var msg string
msg += fmt.Sprintf("%s From to %s from %s", line.Method, line.URL, data.Hostname)
for k := range line.Header {
data.Headers = append(data.Headers, k)
}
data.Session = head
}
}
}
}
}
return data
}
func main() {
handle, x := pcap.OpenOffline("HTTP.pcap")
if x != nil {
log.Fatal(x)
}
defer handle.Close()
pkt_src := gopacket.NewPacketSource(handle, handle.LinkType())
var counter int
for packet := range pkt_src.Packets() {
INFO := Read_TCP_TO_HTTP(packet)
counter++
fmt.Println("---- Packet #", counter)
fmt.Println("Hostname | ", INFO.Hostname)
fmt.Println("URL | ", INFO.URL)
fmt.Println("Uagent | ", INFO.UserAgent)
fmt.Println("Basic Auth (encoded) | ", INFO.BASIC_Encoded)
fmt.Println("Basic Auth (decoded) | ", INFO.BASIC_Decoded)
fmt.Println("NTLM (encoded) | ", INFO.NTLM_Encoded)
fmt.Println("Negotiate | ", INFO.Negotiate)
fmt.Println("HTTP Digest | ", INFO.DIGEST)
for _, k := range INFO.Headers {
fmt.Println("Header | ", k)
}
fmt.Println("========================")
fmt.Println("SESSION INFORMATION:")
fmt.Println(INFO.Session)
}
}
/*
THE CODE THAT WAS LEFT OUT OF THE BOOK IS SHOWN BELOW
// Detect NTLM hash
reg := regexp.MustCompile("(?i)Authorization: NTLM (.*)")
dt := reg.FindAllStringSubmatch(string(tcp.Payload), 1)
if dt != nil {
for p := range dt {
data.NTLM_Encoded = strings.Trim(dt[p][0], "Authorization: NTLM")
}
}
// Detect BASIC authentication | Decode and encoded
regf := regexp.MustCompile("(?i)Authorization: Basic (.*)")
dtf := regf.FindAllStringSubmatch(string(tcp.Payload), 1)
if dtf != nil {
for p := range dtf {
if VALB64(string(strings.Trim(dtf[p][0], "Authorization: Basic "))) {
DECB64((strings.Trim(dtf[p][0], "Authorization: Basic ")))
data.BASIC_Encoded = strings.Trim(dtf[p][0], "Authorization: Basic ")
data.BASIC_Decoded = DECB64((strings.Trim(dtf[p][0], "Authorization: Basic ")))
}
}
}
// Detect HTTP Digest Authentication
regf2 := regexp.MustCompile("(?i)Authorization: Digest (.*)")
dtf2 := regf2.FindAllStringSubmatch(string(tcp.Payload), 1)
if dtf2 != nil {
for p := range dtf2 {
data.DIGEST = string(strings.Trim(dtf2[p][0], "Authorization: Digest "))
}
}
// Detect HTTP Negotiate Authentication
regf3 := regexp.MustCompile("(?i)Authorization: Negotiate (.*)")
dtf3 := regf3.FindAllStringSubmatch(string(tcp.Payload), 1)
if dtf3 != nil {
for p := range dtf3 {
data.Negotiate = string(strings.Trim(dtf3[p][0], "Authorization: Negotiate "))
}
}
// Append HTTP layer data
var head string
var msg string
msg += fmt.Sprintf("%s From to %s from %s", line.Method, line.URL, data.Hostname)
for k := range line.Header {
data.Headers = append(data.Headers, k)
}
data.Session = head
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment