142 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
| package d4tls
 | |
| 
 | |
| import (
 | |
| 	"crypto/md5"
 | |
| 	"encoding/hex"
 | |
| 	"fmt"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/glaslos/tlsh"
 | |
| )
 | |
| 
 | |
| var grease = map[uint16]bool{
 | |
| 	0x0a0a: true, 0x1a1a: true, 0x2a2a: true, 0x3a3a: true,
 | |
| 	0x4a4a: true, 0x5a5a: true, 0x6a6a: true, 0x7a7a: true,
 | |
| 	0x8a8a: true, 0x9a9a: true, 0xaaaa: true, 0xbaba: true,
 | |
| 	0xcaca: true, 0xdada: true, 0xeaea: true, 0xfafa: true,
 | |
| }
 | |
| 
 | |
| // D4Fingerprinting computes fingerprints doh
 | |
| func (t *TLSSession) D4Fingerprinting(fd string) bool {
 | |
| 	switch fd {
 | |
| 	case "ja3":
 | |
| 		t.ja3()
 | |
| 	case "ja3s":
 | |
| 		t.ja3s()
 | |
| 	case "tlsh":
 | |
| 		t.d4fg()
 | |
| 	default:
 | |
| 		return false
 | |
| 	}
 | |
| 
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| func (t *TLSSession) d4fg() string {
 | |
| 	buf := t.Record.JA3 + t.Record.JA3S
 | |
| 	for _, cert := range t.Record.Certificates {
 | |
| 		buf += fmt.Sprintf("%q", cert.Issuer) + fmt.Sprintf("%q", cert.Subject)
 | |
| 	}
 | |
| 	buf = strings.Replace(buf, "-", "", -1)
 | |
| 	buf = strings.Replace(buf, ",", "", -1)
 | |
| 	buf = strings.Replace(buf, "\"", "", -1)
 | |
| 
 | |
| 	out, _ := tlsh.HashBytes([]byte(buf))
 | |
| 	t.Record.TLSH = out.String()
 | |
| 	return buf
 | |
| }
 | |
| 
 | |
| func (t *TLSSession) ja3s() bool {
 | |
| 	var buf []byte
 | |
| 
 | |
| 	buf = strconv.AppendInt(buf, int64(t.handShakeRecord.ETLSHandshakeServerHello.Vers), 10)
 | |
| 	// byte (44) is ","
 | |
| 	buf = append(buf, byte(44))
 | |
| 
 | |
| 	// If the Server Cipher is not in GREASE
 | |
| 	if grease[uint16(t.handShakeRecord.ETLSHandshakeServerHello.CipherSuite)] == false {
 | |
| 		buf = strconv.AppendInt(buf, int64(t.handShakeRecord.ETLSHandshakeServerHello.CipherSuite), 10)
 | |
| 	}
 | |
| 	buf = append(buf, byte(44))
 | |
| 
 | |
| 	// If there are extensions
 | |
| 	if len(t.handShakeRecord.ETLSHandshakeServerHello.AllExtensions) > 0 {
 | |
| 		for i, e := range t.handShakeRecord.ETLSHandshakeServerHello.AllExtensions {
 | |
| 			if grease[uint16(e)] == false {
 | |
| 				buf = strconv.AppendInt(buf, int64(e), 10)
 | |
| 				if (i + 1) < len(t.handShakeRecord.ETLSHandshakeServerHello.AllExtensions) {
 | |
| 					// byte(45) is "-"
 | |
| 					buf = append(buf, byte(45))
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	t.Record.JA3S = string(buf)
 | |
| 	tmp := md5.Sum(buf)
 | |
| 	t.Record.JA3SDigest = hex.EncodeToString(tmp[:])
 | |
| 
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| func (t *TLSSession) ja3() bool {
 | |
| 	var buf []byte
 | |
| 
 | |
| 	buf = strconv.AppendInt(buf, int64(t.handShakeRecord.ETLSHandshakeClientHello.Vers), 10)
 | |
| 	// byte (44) is ","
 | |
| 	buf = append(buf, byte(44))
 | |
| 
 | |
| 	// If there are Cipher Suites
 | |
| 	if len(t.handShakeRecord.ETLSHandshakeClientHello.CipherSuites) > 0 {
 | |
| 		for i, cs := range t.handShakeRecord.ETLSHandshakeClientHello.CipherSuites {
 | |
| 			if grease[uint16(cs)] == false {
 | |
| 				buf = strconv.AppendInt(buf, int64(cs), 10)
 | |
| 				// byte(45) is "-"
 | |
| 				if (i + 1) < len(t.handShakeRecord.ETLSHandshakeClientHello.CipherSuites) {
 | |
| 					buf = append(buf, byte(45))
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	buf = append(buf, byte(44))
 | |
| 
 | |
| 	// If there are extensions
 | |
| 	if len(t.handShakeRecord.ETLSHandshakeClientHello.AllExtensions) > 0 {
 | |
| 		for i, e := range t.handShakeRecord.ETLSHandshakeClientHello.AllExtensions {
 | |
| 			if grease[uint16(e)] == false {
 | |
| 				buf = strconv.AppendInt(buf, int64(e), 10)
 | |
| 				if (i + 1) < len(t.handShakeRecord.ETLSHandshakeClientHello.AllExtensions) {
 | |
| 					buf = append(buf, byte(45))
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	buf = append(buf, byte(44))
 | |
| 
 | |
| 	// If there are Supported Curves
 | |
| 	if len(t.handShakeRecord.ETLSHandshakeClientHello.SupportedCurves) > 0 {
 | |
| 		for i, cs := range t.handShakeRecord.ETLSHandshakeClientHello.SupportedCurves {
 | |
| 			buf = strconv.AppendInt(buf, int64(cs), 10)
 | |
| 			if (i + 1) < len(t.handShakeRecord.ETLSHandshakeClientHello.SupportedCurves) {
 | |
| 				buf = append(buf, byte(45))
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	buf = append(buf, byte(44))
 | |
| 
 | |
| 	// If there are Supported Points
 | |
| 	if len(t.handShakeRecord.ETLSHandshakeClientHello.SupportedPoints) > 0 {
 | |
| 		for i, cs := range t.handShakeRecord.ETLSHandshakeClientHello.SupportedPoints {
 | |
| 			buf = strconv.AppendInt(buf, int64(cs), 10)
 | |
| 			if (i + 1) < len(t.handShakeRecord.ETLSHandshakeClientHello.SupportedPoints) {
 | |
| 				buf = append(buf, byte(45))
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	t.Record.JA3 = string(buf)
 | |
| 	tmp := md5.Sum(buf)
 | |
| 	t.Record.JA3Digest = hex.EncodeToString(tmp[:])
 | |
| 	return true
 | |
| }
 |