TCPDump working from adb shell but not from device

1.4k views Asked by At

I am developing an android application to monitor network usage in android devices.

One of the application requirements is to provide a “.pcap” file created by tcpdump command. When I try to execute tcpdum command from adb shell, everything works fine and I am able to create this file. But when I try to execute this command from the device itself, using a java code, I get permission denied error.

It should be mentioned that my java code works fine for other commands that do not demand a special privilege.

It also should be mentioned that I used two of the following rooted devices (first Samsung – running android 4.4, second samsung - running android 5.1.1)

Moreover, I tried to install another tcpdump binary and gave it execution privilege and also tried a different variations of tcpdump command in order to obtain a privilege with “su”. From what I understand, this is the behavior of the kernel and it’s for security reasons, but despite this, I would like to know If is there a way to get around this / give my application the permissions it need in order to run the mentioned commands. Below, the commands I tried to run and the responses that I was given.

Command: tcpdump -l -i eth1 -w /sdcard/output.pcap Response: tcpdump: eth1: You don't have permission to capture on that device (socket: Operation not permitted)

Command: tcpdump -w /sdcard/output.pcap Response: tcpdump: Can't open netlink socket 13:Permission denied

Response: tcpdump: rmnet0: You don't have permission to capture on that device.

my manifest permissions:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_SUPERUSER"/>

the relevant code:

public static boolean executeCommandViaShell(String sCmd) {
    DataInputStream isErr = null, isRes = null;
    BufferedReader brErr = null, brRes = null;
    try {
        Process process = Runtime.getRuntime().exec(sCmd);
        isErr = new DataInputStream(process .getErrorStream());
        brErr = new BufferedReader(new InputStreamReader(isErr));
        isRes = new DataInputStream(process .getInputStream());
        brRes = new BufferedReader(new InputStreamReader(isRes));
        // errors:
        while ((m_sMessage = brErr.readLine()) != null) {
            if (m_sMessage.equalsIgnoreCase("INVALID"))
            {
                return false;
            }
        }
        while ((m_sMessage = brRes.readLine()) != null) {
            if (m_sMessage.equals("SUCCESS")) {
                Log.d(TAG, "SUCCESS m_sMessage: " + m_sMessage);
            }
            else {
                return false;
            }
        }
        return true;
    }
    catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    finally {
        try {
            isErr.close();
            isRes.close();
            brErr.close();
            brRes.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
0

There are 0 answers