Last active
March 20, 2022 07:54
-
-
Save NathanFrench/d38ab24b98a3d5c9536e8993e7964997 to your computer and use it in GitHub Desktop.
gobpf SSL snooper.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pid:28357 (openssl) | |
-------- | |
00000000 48 54 54 50 2f 31 2e 31 20 34 30 30 20 42 61 64 |HTTP/1.1 400 Bad| | |
00000010 20 52 65 71 75 65 73 74 0d 0a 53 65 72 76 65 72 | Request..Server| | |
00000020 3a 20 63 6c 6f 75 64 66 6c 61 72 65 2d 6e 67 69 |: cloudflare-ngi| | |
00000030 6e 78 0d 0a 44 61 74 65 3a 20 54 75 65 2c 20 30 |nx..Date: Tue, 0| | |
00000040 32 20 4a 61 6e 20 32 30 31 38 20 32 33 3a 30 37 |2 Jan 2018 23:07| | |
00000050 3a 30 37 20 47 4d 54 0d 0a 43 6f 6e 74 65 6e 74 |:07 GMT..Content| | |
00000060 2d 54 79 70 65 3a 20 74 65 78 74 2f 68 74 6d 6c |-Type: text/html| | |
00000070 0d 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 |..Content-Length| | |
00000080 3a 20 31 37 37 0d 0a 43 6f 6e 6e 65 63 74 69 6f |: 177..Connectio| | |
00000090 6e 3a 20 63 6c 6f 73 65 0d 0a 43 46 2d 52 41 59 |n: close..CF-RAY| | |
000000a0 3a 20 2d 0d 0a 0d 0a 3c 68 74 6d 6c 3e 0d 0a 3c |: -....<html>..<| | |
000000b0 68 65 61 64 3e 3c 74 69 74 6c 65 3e 34 30 30 20 |head><title>400 | | |
000000c0 42 61 64 20 52 65 71 75 65 73 74 3c 2f 74 69 74 |Bad Request</tit| | |
000000d0 6c 65 3e 3c 2f 68 65 61 64 3e 0d 0a 3c 62 6f 64 |le></head>..<bod| | |
000000e0 79 20 62 67 63 6f 6c 6f 72 3d 22 77 68 69 74 65 |y bgcolor="white| | |
000000f0 22 3e 0d 0a 3c 63 65 6e 74 65 72 3e 3c 68 31 3e |">..<center><h1>| | |
00000100 34 30 30 20 42 61 64 20 52 65 71 75 65 73 74 3c |400 Bad Request<| | |
00000110 2f 68 31 3e 3c 2f 63 65 6e 74 65 72 3e 0d 0a 3c |/h1></center>..<| | |
00000120 68 72 3e 3c 63 65 6e 74 65 72 3e 63 6c 6f 75 64 |hr><center>cloud| | |
00000130 66 6c 61 72 65 2d 6e 67 69 6e 78 3c 2f 63 65 6e |flare-nginx</cen| | |
00000140 74 65 72 3e 0d 0a 3c 2f 62 6f 64 79 3e 0d 0a 3c |ter>..</body>..<| | |
00000150 2f 68 74 6d 6c 3e 0d 0a |/html>..| |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/ptrace.h> | |
struct ssl_probe_data { | |
u64 timestamp_ns; | |
u32 pid; | |
u32 len; | |
char comm[16]; | |
char payload[400]; | |
} __attribute__((packed)); | |
BPF_PERF_OUTPUT(perf_SSL_read); | |
BPF_HASH(bufs, u32, u64); | |
int probe_SSL_read_enter(struct pt_regs * ctx, void * ssl, void * buf, int num) { | |
u32 pid = bpf_get_current_pid_tgid(); | |
bufs.update(&pid, (u64 *)&buf); | |
return 0; | |
} | |
int probe_SSL_read_exit(struct pt_regs * ctx, void * ssl, void * buf, int num) { | |
struct ssl_probe_data event = { 0 }; | |
u32 pid = bpf_get_current_pid_tgid(); | |
u64 * bufp = bufs.lookup(&pid); | |
if (bufp == 0) { | |
return 0; | |
} | |
if (PT_REGS_RC(ctx) == 0) { | |
return 0; | |
} | |
event.timestamp_ns = bpf_ktime_get_ns(); | |
event.pid = pid; | |
event.len = PT_REGS_RC(ctx); | |
bpf_get_current_comm(&event.comm, | |
sizeof(event.comm)); | |
if (bufp != 0) { | |
bpf_probe_read(&event.payload, | |
sizeof(event.payload), | |
(char *)*bufp); | |
} | |
bufs.delete(&pid); | |
perf_SSL_read.perf_submit(ctx, | |
&event, | |
sizeof(event)); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"C" | |
"bytes" | |
"encoding/binary" | |
"encoding/hex" | |
"fmt" | |
"io/ioutil" | |
"log" | |
"os" | |
"os/signal" | |
bpf "github.com/iovisor/gobpf/bcc" | |
) | |
// CFile he source BPF file | |
const CFile string = "./ssl-snoop.c" | |
// ProbeEnter the UProbe function name | |
const ProbeEnter string = "probe_SSL_read_enter" | |
// ProbeExit the URETprobe function name | |
const ProbeExit string = "probe_SSL_read_exit" | |
// LibSSLPath the path of the library for our UProbe | |
const LibSSLPath string = "ssl" | |
// LibSSLSymb the symbol to probe from LibSSLPath | |
const LibSSLSymb string = "SSL_read" | |
// perfTblName is the bpf table to read events from | |
const perfTblName string = "perf_SSL_read" | |
type sslDataEvent struct { | |
TimeStamp uint64 `json:"TimeStamp"` | |
Pid uint32 `json:"Pid"` | |
Len uint32 `json:"DataLen"` | |
Comm [16]byte `json:"Comm"` | |
Data [400]byte `json:"SSLData"` | |
} | |
func main() { | |
content, err := ioutil.ReadFile(CFile) | |
if err != nil { | |
log.Fatal(err) | |
} | |
source := string(content) | |
mod := bpf.NewModule(source, []string{}) | |
defer mod.Close() | |
uEnterProbe, _ := mod.LoadUprobe(ProbeEnter) | |
uExitProbe, _ := mod.LoadUprobe(ProbeExit) | |
fmt.Printf("%d %d\n", uExitProbe, uEnterProbe) | |
mod.AttachUprobe( | |
LibSSLPath, | |
LibSSLSymb, | |
uEnterProbe, -1) | |
err = mod.AttachUretprobe( | |
LibSSLPath, | |
LibSSLSymb, | |
uExitProbe, -1) | |
if err != nil { | |
log.Fatal(err) | |
} | |
table := bpf.NewTable(mod.TableId(perfTblName), mod) | |
bpfch := make(chan []byte) | |
signl := make(chan os.Signal, 1) | |
prmap, _ := bpf.InitPerfMap(table, bpfch) | |
signal.Notify(signl, os.Interrupt, os.Kill) | |
go func() { | |
var event sslDataEvent | |
for { | |
data := <-bpfch | |
if err := binary.Read(bytes.NewBuffer(data), | |
binary.LittleEndian, &event); err != nil { | |
log.Printf("error: %s\n", err) | |
continue | |
} | |
var realLen = event.Len | |
if realLen > 400 { | |
event.Len = 400 | |
} | |
fmt.Printf("\npid:%d (%s)\n--------\n%s", | |
event.Pid, | |
event.Comm, | |
hex.Dump(event.Data[:event.Len])) | |
} | |
}() | |
prmap.Start() | |
<-signl | |
prmap.Stop() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment