Corrected the way bpftrace gets the PID infos + try at taking a path
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# dns_bpf_correlate_safe.sh
|
# dns_bpf_correlate_fdmap.sh
|
||||||
set -u
|
set -u
|
||||||
|
|
||||||
DOMAIN=$1
|
DOMAIN=$1
|
||||||
@@ -40,7 +40,7 @@ tcpdump -n -i any port 53 -s0 -ttt -l 2>/dev/null >> "$DNSLOG" &
|
|||||||
TCPDUMP_PID=$!
|
TCPDUMP_PID=$!
|
||||||
echo -e "${GREEN}[*] tcpdump started (PID $TCPDUMP_PID)${RESET}"
|
echo -e "${GREEN}[*] tcpdump started (PID $TCPDUMP_PID)${RESET}"
|
||||||
|
|
||||||
# Start bpftrace (safe, prints nsecs/1000000, PID, COMM, FD)
|
# Start safe bpftrace
|
||||||
bpftrace -e '
|
bpftrace -e '
|
||||||
tracepoint:syscalls:sys_enter_sendto
|
tracepoint:syscalls:sys_enter_sendto
|
||||||
{
|
{
|
||||||
@@ -57,7 +57,7 @@ echo -e "${GREEN}[*] bpftrace started (PID $BPF_PID)${RESET}"
|
|||||||
sleep 1
|
sleep 1
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Helper function: /proc info for PID
|
# Helper: get process info and exe path
|
||||||
proc_info_for_pid() {
|
proc_info_for_pid() {
|
||||||
local pid="$1"
|
local pid="$1"
|
||||||
if [[ -r "/proc/$pid/cmdline" ]]; then
|
if [[ -r "/proc/$pid/cmdline" ]]; then
|
||||||
@@ -69,7 +69,17 @@ proc_info_for_pid() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Tail tcpdump and correlate symmetrically
|
# Map FD → inode → port using /proc/net/udp
|
||||||
|
fd_to_udp_port() {
|
||||||
|
local pid="$1"
|
||||||
|
local fd="$2"
|
||||||
|
local inode
|
||||||
|
inode=$(awk -v fd="$fd" '$1==fd {print $2}' "/proc/$pid/fdinfo/$fd" 2>/dev/null)
|
||||||
|
[[ -z "$inode" ]] && return 1
|
||||||
|
awk -v inode="$inode" '$10==inode {split($2,a,":"); printf "%d", strtonum("0x"a[2])}' /proc/net/udp 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Tail tcpdump and correlate
|
||||||
tail -Fn0 "$DNSLOG" | while IFS= read -r dnsline; do
|
tail -Fn0 "$DNSLOG" | while IFS= read -r dnsline; do
|
||||||
if echo "$dnsline" | grep -qi -- "$DOMAIN"; then
|
if echo "$dnsline" | grep -qi -- "$DOMAIN"; then
|
||||||
detect_ms=$(now_ms)
|
detect_ms=$(now_ms)
|
||||||
@@ -95,7 +105,7 @@ tail -Fn0 "$DNSLOG" | while IFS= read -r dnsline; do
|
|||||||
echo "extracted_src_port: $srcPort" >> "$INCIDENT_FILE"
|
echo "extracted_src_port: $srcPort" >> "$INCIDENT_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Symmetric window: ±HALF_WINDOW_MS
|
# Symmetric window
|
||||||
low_ms=$((detect_ms - HALF_WINDOW_MS))
|
low_ms=$((detect_ms - HALF_WINDOW_MS))
|
||||||
high_ms=$((detect_ms + HALF_WINDOW_MS))
|
high_ms=$((detect_ms + HALF_WINDOW_MS))
|
||||||
awk -v low="$low_ms" -v high="$high_ms" '
|
awk -v low="$low_ms" -v high="$high_ms" '
|
||||||
@@ -115,9 +125,15 @@ tail -Fn0 "$DNSLOG" | while IFS= read -r dnsline; do
|
|||||||
|
|
||||||
pids=$(sed -n 's/.*PID=\([0-9]\+\).*/\1/p' /tmp/_bpf_matches.$$ | sort -u)
|
pids=$(sed -n 's/.*PID=\([0-9]\+\).*/\1/p' /tmp/_bpf_matches.$$ | sort -u)
|
||||||
for pid in $pids; do
|
for pid in $pids; do
|
||||||
|
fds=$(awk -v pid="$pid" '$3==pid {print $5}' /tmp/_bpf_matches.$$ | grep -o '[0-9]\+')
|
||||||
|
for fd in $fds; do
|
||||||
|
port=$(fd_to_udp_port "$pid" "$fd" 2>/dev/null || true)
|
||||||
|
if [[ -n "$port" ]] && [[ "$port" -eq "$srcPort" ]]; then
|
||||||
info=$(proc_info_for_pid "$pid")
|
info=$(proc_info_for_pid "$pid")
|
||||||
echo " [*] $info"
|
echo -e "${GREEN}[+] Matched process: $info${RESET}"
|
||||||
echo " - $info" >> "$INCIDENT_FILE"
|
echo "matched_process: $info" >> "$INCIDENT_FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
echo -e "${YELLOW}[!] No bpftrace events in window${RESET}"
|
echo -e "${YELLOW}[!] No bpftrace events in window${RESET}"
|
||||||
|
|||||||
Reference in New Issue
Block a user