1

I am running tcpdump using the subprocess module in python to capture a trace of a website, using this piece of code:

import subprocess
from tbselenium.tbdriver import TorBrowserDriver

site = "check.torproject.org"

try:

        process = subprocess.Popen(['sudo', 'tcpdump', '-l', '-i', 'eth0', '-w', 'trace.pcap'], stdout=subprocess.PIPE)

        with TorBrowserDriver("/path/to/tor-browser_en-US/") as driver:
            driver.load_url("https://" + site, wait_on_page=20)

        process.send_signal(subprocess.signal.SIGTERM)

except OSError:
    print "OSError"

The code gives me an OSError and when I try to open the pcap file in wireshark I get the following error box:

The capture file appears to have been cut short in the middle of a packet.

I've read this solution to the same issue, and have tried sending both a SIGINT and a SIGTERM, but I get the same truncated-packet message in each case along with an OSError. I have also tried using process.terminate() but that doesn't work either. Is there any way I could make tcpdump exit cleanly while running in sudo mode. Thanks!

QPTR
  • 1,620
  • 7
  • 26
  • 47

2 Answers2

1

As the OSError: [Errno 1] Operation not permitted suggest, killing the process is not permitted. Because you used sudo, killing the process should be instantiated sudo as well. Maybe you try this:

import subprocess
import os
from tbselenium.tbdriver import TorBrowserDriver

site = "check.torproject.org"

try:
    process = subprocess.Popen(['sudo', 'tcpdump', '-l', '-i', 'eth0', '-w', 'trace.pcap'], stdout=subprocess.PIPE)

    with TorBrowserDriver("/path/to/tor-browser_en-US/") as driver:
        driver.load_url("https://" + site, wait_on_page=20)

    cmd = "sudo kill " + str(process.pid)
    os.system(cmd)
except OSError, e:
    print e
Kadir
  • 1,664
  • 2
  • 19
  • 22
  • Thank you so much, it works! Exits cleanly reporting the number of packets captured. And no truncated packets reported by `wireshark`. – QPTR Apr 14 '17 at 12:22
1

Since tcpdump needs su privileges you can simply run the script as su and check for it before you spawn tcpdump:

# Check we are running as root:
if os.geteuid() != 0:
    print('This script requires root privileges to capture packets. Try running this script as root.')
    raise SystemExit

# Start TCPDUMP
import subprocess, os
_process = subprocess.Popen(['tcpdump', '-nnvvv', '-s0', '-w', os.path.join('/tmp', 'output.pcap'), ])

This way you can run

_process.terminate()

or

_process.kill()

to send the proper signal to tcpdump

datu-puti
  • 1,306
  • 14
  • 33