mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-28 02:52:42 +00:00
feat(osiris): add TCP and TLS fingerprinting
Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
//go:build freebsd
|
||||
|
||||
package fingerprint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type tcpInfo struct {
|
||||
State uint8
|
||||
Options uint8
|
||||
SndScale uint8
|
||||
RcvScale uint8
|
||||
__pad [4]byte
|
||||
Rto uint32
|
||||
Ato uint32
|
||||
SndMss uint32
|
||||
RcvMss uint32
|
||||
Unacked uint32
|
||||
Sacked uint32
|
||||
Lost uint32
|
||||
Retrans uint32
|
||||
Fackets uint32
|
||||
Last_data_sent uint32
|
||||
Last_ack_sent uint32
|
||||
Last_data_recv uint32
|
||||
Last_ack_recv uint32
|
||||
Pmtu uint32
|
||||
Rcv_ssthresh uint32
|
||||
RTT uint32
|
||||
RTTvar uint32
|
||||
Snd_ssthresh uint32
|
||||
Snd_cwnd uint32
|
||||
Advmss uint32
|
||||
Reordering uint32
|
||||
Rcv_rtt uint32
|
||||
Rcv_space uint32
|
||||
Total_retrans uint32
|
||||
Snd_wnd uint32
|
||||
// Truncated for brevity — add more fields if needed
|
||||
}
|
||||
|
||||
// AssignTCPFingerprint extracts TCP fingerprint information from a connection
|
||||
func AssignTCPFingerprint(conn net.Conn) (*JA4T, error) {
|
||||
tcpConn, ok := conn.(*net.TCPConn)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("not a TCPConn")
|
||||
}
|
||||
|
||||
rawConn, err := tcpConn.SyscallConn()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("SyscallConn failed: %w", err)
|
||||
}
|
||||
|
||||
var info tcpInfo
|
||||
var sysErr error
|
||||
|
||||
err = rawConn.Control(func(fd uintptr) {
|
||||
size := uint32(unsafe.Sizeof(info))
|
||||
_, _, errno := syscall.Syscall6(
|
||||
syscall.SYS_GETSOCKOPT,
|
||||
fd,
|
||||
uintptr(syscall.IPPROTO_TCP),
|
||||
uintptr(syscall.TCP_INFO),
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uintptr(unsafe.Pointer(&size)),
|
||||
0,
|
||||
)
|
||||
if errno != 0 {
|
||||
sysErr = errno
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("SyscallConn.Control: %w", err)
|
||||
}
|
||||
if sysErr != nil {
|
||||
return nil, fmt.Errorf("getsockopt TCP_INFO: %w", sysErr)
|
||||
}
|
||||
|
||||
fp := &JA4T{
|
||||
Window: info.Snd_wnd,
|
||||
MSS: uint16(info.SndMss),
|
||||
WindowScale: info.SndScale,
|
||||
}
|
||||
|
||||
const (
|
||||
TCPI_OPT_TIMESTAMPS = 1 << 0
|
||||
TCPI_OPT_SACK = 1 << 1
|
||||
TCPI_OPT_WSCALE = 1 << 2
|
||||
)
|
||||
|
||||
if info.Options&TCPI_OPT_SACK != 0 {
|
||||
fp.Options = append(fp.Options, 4, 1)
|
||||
}
|
||||
if info.Options&TCPI_OPT_TIMESTAMPS != 0 {
|
||||
fp.Options = append(fp.Options, 8, 1)
|
||||
}
|
||||
if info.Options&TCPI_OPT_WSCALE != 0 {
|
||||
fp.Options = append(fp.Options, 3)
|
||||
}
|
||||
|
||||
return fp, nil
|
||||
}
|
||||
Reference in New Issue
Block a user