diff --git a/bpftrace_20251121_212318.log b/bpftrace_20251121_212318.log deleted file mode 100644 index e69de29..0000000 diff --git a/bpftrace_20251121_212423.log b/bpftrace_20251121_212423.log deleted file mode 100644 index e69de29..0000000 diff --git a/bpftrace_20251121_212538.log b/bpftrace_20251121_212538.log deleted file mode 100644 index e69de29..0000000 diff --git a/bpftrace_20251121_212615.log b/bpftrace_20251121_212615.log deleted file mode 100644 index e69de29..0000000 diff --git a/dns-debunk.sh b/dns-debunk.sh index 6a30744..c62b634 100755 --- a/dns-debunk.sh +++ b/dns-debunk.sh @@ -1,13 +1,10 @@ #!/usr/bin/env bash -# dns_bpf_correlate.sh -# Usage: sudo ./dns_bpf_correlate.sh -# -# Requires: bpftrace, tcpdump, date (GNU) -# Purpose: correlate DNS packets (tcpdump) with the process that issued them using bpftrace syscall tracing. +# dns_bpf_correlate_fixed.sh set -u -DOMAIN=$1 -WINDOW_MS=2000 # how many ms back to search for matching bpftrace events +DOMAIN="tracker1.myporn.club" +WINDOW_MS=2000 +HALF_WINDOW_MS=$((WINDOW_MS/2)) BASE_TS="$(date +%Y%m%d_%H%M%S)" DNSLOG="${DOMAIN}_${BASE_TS}_dns.log" BPFLOG="bpftrace_${BASE_TS}.log" @@ -19,12 +16,12 @@ RED="\e[31m"; GREEN="\e[32m"; YELLOW="\e[33m"; BLUE="\e[34m"; RESET="\e[0m" TCPDUMP_PID="" BPF_PID="" -now_ms() { date +%s%3N; } # epoch milliseconds (GNU date) +now_ms() { date +%s%3N; } cleanup() { echo -e "${BLUE}[*] Stopping background processes...${RESET}" - [[ -n "$TCPDUMP_PID" ]] && sudo kill "$TCPDUMP_PID" 2>/dev/null || true - [[ -n "$BPF_PID" ]] && sudo kill "$BPF_PID" 2>/dev/null || true + [[ -n "$TCPDUMP_PID" ]] && kill "$TCPDUMP_PID" 2>/dev/null || true + [[ -n "$BPF_PID" ]] && kill "$BPF_PID" 2>/dev/null || true sleep 0.1 echo -e "${BLUE}[*] Done.${RESET}" exit 0 @@ -35,64 +32,50 @@ echo -e "${BLUE}[*] Domain: ${YELLOW}$DOMAIN${RESET}" echo -e "${BLUE}[*] DNS log: ${YELLOW}$DNSLOG${RESET}" echo -e "${BLUE}[*] bpftrace log: ${YELLOW}$BPFLOG${RESET}" echo -e "${BLUE}[*] Incidents directory: ${YELLOW}$INCIDENT_DIR${RESET}" -echo -e "${BLUE}[*] Window for correlation: ${YELLOW}${WINDOW_MS} ms${RESET}" +echo -e "${BLUE}[*] Window for correlation: ${YELLOW}${WINDOW_MS} ms (±${HALF_WINDOW_MS} ms)${RESET}" echo "" -# Start tcpdump -> DNSLOG (writes raw tcpdump lines) -sudo tcpdump -n -i any port 53 -s0 -ttt -l 2>/dev/null >> "$DNSLOG" & +# Start tcpdump +tcpdump -n -i any port 53 -s0 -ttt -l 2>/dev/null >> "$DNSLOG" & TCPDUMP_PID=$! echo -e "${GREEN}[*] tcpdump started (PID $TCPDUMP_PID)${RESET}" -# Start bpftrace inline printing epoch seconds + ms and PID/COMM/FD -# We print: . PID= COMM= FD= -# Use time (seconds since epoch) and nsecs to produce ms fraction. -sudo bpftrace -e ' +# Start bpftrace inline (correct syntax) +bpftrace -e ' tracepoint:syscalls:sys_enter_sendto { - $s = time; // seconds since epoch - $ms = (nsecs/1000000) % 1000; + $s = time; $ms = nsecs/1000000 % 1000; printf("%d.%03d PID=%d COMM=%s FD=%d\n", $s, $ms, pid, comm, args->fd); } ' > "$BPFLOG" 2>/dev/null & BPF_PID=$! sleep 0.2 -# Quick liveness check for bpftrace log (it may stay empty until events occur, but we ensure process exists) if ! kill -0 "$BPF_PID" 2>/dev/null; then - echo -e "${YELLOW}[!] bpftrace failed to start (process exited). Check bpftrace availability and permissions.${RESET}" - echo -e "${YELLOW} Try: sudo bpftrace -e 'tracepoint:syscalls:sys_enter_sendto { printf(\"hi\\n\"); }'${RESET}" + echo -e "${RED}[!] bpftrace failed to start!${RESET}" cleanup fi - -# Wait a short moment and check file is being appended to (if no events yet file may be empty - warn instead of failing) +echo -e "${GREEN}[*] bpftrace started (PID $BPF_PID)${RESET}" sleep 1 -if [[ ! -s "$BPFLOG" ]]; then - echo -e "${YELLOW}[!] Note: bpftrace log is currently empty (no sendto events observed yet). This is normal until a process performs sendto().${RESET}" -fi - -echo -e "${GREEN}[*] bpftrace started (PID $BPF_PID) -- logging to $BPFLOG${RESET}" echo "" -# Helper: gather proc info for PID +# Helper function: /proc info for PID proc_info_for_pid() { local pid="$1" if [[ -r "/proc/$pid/cmdline" ]]; then - local exe - exe=$(sudo readlink -f "/proc/$pid/exe" 2>/dev/null || true) - local cmd - cmd=$(sudo tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null || true) + local exe=$(readlink -f "/proc/$pid/exe" 2>/dev/null || true) + local cmd=$(tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null || true) echo "pid=$pid exe=${exe:-N/A} cmdline='${cmd:-N/A}'" else echo "pid=$pid (no /proc info)" fi } -# Tail dns log and correlate with bpftrace by timestamp +# Tail tcpdump and correlate symmetrically tail -Fn0 "$DNSLOG" | while IFS= read -r dnsline; do - # case-insensitive match for domain if echo "$dnsline" | grep -qi -- "$DOMAIN"; then detect_ms=$(now_ms) - echo -e "${RED}[!] Suspicious DNS request detected @ ${YELLOW}${detect_ms}${RESET}" + echo -e "${RED}[!] Suspicious DNS request detected @${YELLOW}$detect_ms${RESET}" echo -e "${YELLOW}$dnsline${RESET}" echo "" @@ -104,66 +87,51 @@ tail -Fn0 "$DNSLOG" | while IFS= read -r dnsline; do echo "detected_at_ms: $detect_ms" } > "$INCIDENT_FILE" - # extract src token (token after IP token) + # extract source IP/port src_tok=$(echo "$dnsline" | awk '{for(i=1;i<=NF;i++) if($i=="IP" || $i=="IP6"){print $(i+1); exit}}' || true) if [[ -n "$src_tok" ]]; then srcPort="${src_tok##*.}" srcIP="${src_tok%.*}" - echo -e "${GREEN}[+] Extracted source: IP=${YELLOW}${srcIP}${RESET} PORT=${YELLOW}${srcPort}${RESET}" + echo -e "${GREEN}[+] Extracted source: IP=${YELLOW}$srcIP${RESET} PORT=${YELLOW}$srcPort${RESET}" echo "extracted_src_ip: $srcIP" >> "$INCIDENT_FILE" echo "extracted_src_port: $srcPort" >> "$INCIDENT_FILE" - else - echo -e "${YELLOW}[!] Could not extract source IP/port from tcpdump line${RESET}" - echo "extracted_src_ip: N/A" >> "$INCIDENT_FILE" - echo "extracted_src_port: N/A" >> "$INCIDENT_FILE" fi - # Search BPFLOG for events within WINDOW_MS before detection - # BPF lines start like: 1600000000.123 PID=123 COMM=foo FD=... - low_ms=$((detect_ms - WINDOW_MS)) - high_ms=$((detect_ms)) + # Symmetric window: half before, half after + low_ms=$((detect_ms - HALF_WINDOW_MS)) + high_ms=$((detect_ms + HALF_WINDOW_MS)) awk -v low="$low_ms" -v high="$high_ms" ' BEGIN{FS=" "; OFS=" "} { - # parse first token as seconds.ms if ($1 ~ /^[0-9]+\.[0-9]{3}$/) { split($1, a, ".") - t_s = a[1]; t_ms = a[2] - t = t_s * 1000 + t_ms + t_s=a[1]; t_ms=a[2]; t=t_s*1000+t_ms if (t >= low && t <= high) print $0 } }' "$BPFLOG" | tee -a "$INCIDENT_FILE" > /tmp/_bpf_matches.$$ || true if [[ -s /tmp/_bpf_matches.$$ ]]; then - echo -e "${GREEN}[+] bpftrace events found within ${WINDOW_MS} ms:${RESET}" + echo -e "${GREEN}[+] bpftrace events found in ±${HALF_WINDOW_MS}ms window:${RESET}" sed 's/^/ /' /tmp/_bpf_matches.$$ - echo "" >> "$INCIDENT_FILE" echo "bpftrace_matches:" >> "$INCIDENT_FILE" cat /tmp/_bpf_matches.$$ >> "$INCIDENT_FILE" - # extract PIDs pids=$(sed -n 's/.*PID=\([0-9]\+\).*/\1/p' /tmp/_bpf_matches.$$ | sort -u) - if [[ -n "$pids" ]]; then - echo -e "${GREEN}[+] Candidate PIDs: ${YELLOW}$pids${RESET}" - echo "" >> "$INCIDENT_FILE" - echo "candidate_pids:" >> "$INCIDENT_FILE" - for pid in $pids; do - info=$(proc_info_for_pid "$pid") - echo " - $info" - echo " - $info" >> "$INCIDENT_FILE" - done - fi + for pid in $pids; do + info=$(proc_info_for_pid "$pid") + echo " [*] $info" + echo " - $info" >> "$INCIDENT_FILE" + done else - echo -e "${YELLOW}[!] No bpftrace events found in window (this can happen if syscall happened >${WINDOW_MS}ms before tcpdump line or bpftrace didn't capture).${RESET}" - echo "bpftrace_matches: NONE in ${WINDOW_MS}ms window" >> "$INCIDENT_FILE" + echo -e "${YELLOW}[!] No bpftrace events in window${RESET}" + echo "bpftrace_matches: NONE in ±${HALF_WINDOW_MS}ms" >> "$INCIDENT_FILE" fi - # append an ss snapshot for context echo "" >> "$INCIDENT_FILE" echo "ss_snapshot:" >> "$INCIDENT_FILE" - sudo ss -tulpn 2>/dev/null >> "$INCIDENT_FILE" || true + ss -tulpn 2>/dev/null >> "$INCIDENT_FILE" || true - echo -e "${GREEN}[+] Incident saved to ${YELLOW}${INCIDENT_FILE}${RESET}" + echo -e "${GREEN}[+] Incident saved to ${YELLOW}$INCIDENT_FILE${RESET}" echo -e "${BLUE}------------------------------------------------------${RESET}" echo "" rm -f /tmp/_bpf_matches.$$ diff --git a/ipify_20251121_212318_dns.log b/ipify_20251121_212318_dns.log deleted file mode 100644 index 8b13789..0000000 --- a/ipify_20251121_212318_dns.log +++ /dev/null @@ -1 +0,0 @@ - diff --git a/ipify_20251121_212423_dns.log b/ipify_20251121_212423_dns.log deleted file mode 100644 index 8b13789..0000000 --- a/ipify_20251121_212423_dns.log +++ /dev/null @@ -1 +0,0 @@ - diff --git a/ipify_20251121_212538_dns.log b/ipify_20251121_212538_dns.log deleted file mode 100644 index 8b13789..0000000 --- a/ipify_20251121_212538_dns.log +++ /dev/null @@ -1 +0,0 @@ - diff --git a/ipify_20251121_212615_dns.log b/ipify_20251121_212615_dns.log deleted file mode 100644 index 8b13789..0000000 --- a/ipify_20251121_212615_dns.log +++ /dev/null @@ -1 +0,0 @@ -