Захват сетевых пакетов в Android?

Я работаю над проектом, где мне нужно захватить входящие/исходящие пакеты и сохранить их в файле pcap.

Android предоставил VpnService для этой цели, который был добавлен в API-уровень 14. Хотя, похоже, на SO существует много вопросов относительно этого, удивительно, что на нем очень мало рабочих примеров. Я попытался использовать ToyVpn, который добавлен в образцы, но я не смог заставить его работать. Затем я пришел к этому примеру.

Пример VpnService

В этом примере суммируется захват на следующих этапах.

  • Создайте интерфейс TUN (я все еще не уверен, что TUN работает, но просматривает в Интернете, говорит, что это эмуляция сетевого уровня на устройстве).
  • Получить дескриптор файла для входящих пакетов и исходящих пакетов через TUN.
  • Направляет эти пакеты на фактический сервер. (Не уверен, какой сервер здесь? Каждый исходящий пакет имеет requestUrl, поэтому сервер здесь означает делегирование запроса на сервер requestUrl. Или сервер означает, что создать свой собственный сервер где-нибудь на AWS и перенаправить весь трафик, который, в свою очередь, перенаправит трафик на фактический пункт назначения).
  • Получите ответ от сервера.
  • С помощью TUN снова отправьте этот ответ на предполагаемый компонент приложения.

Я создал TUN, используя приведенный ниже код. Я дал адрес, который был указан в вышеупомянутом учебнике. Не уверен, если есть правильные значения. И как решить этот адрес.

 Builder builder = new Builder();
 ParcelFileDescriptor mInterface = builder.setSession("MyVPNService")
          .addAddress("192.168.0.1", 24)
          .addDnsServer("8.8.8.8")
          .addRoute("0.0.0.0", 0).establish();

Затем я получил файловый дескриптор и открыл туннель.

     FileInputStream in = new FileInputStream(
              mInterface.getFileDescriptor());
   DatagramChannel tunnel = DatagramChannel.open();
          // I have created a EC2 instance on AWS, and gave the ip Address and port of that server. Not sure if this is the correct method.

          tunnel.connect(new InetSocketAddress("54.254.187.207", 5000));
          //d. Protect this socket, so package send by it will not be feedback to the vpn service.
          protect(tunnel.socket());

Затем применяется цикл while для чтения пакетов.

 while (true) {

        BufferedReader reader  = new BufferedReader(new InputStreamReader(in));
        while(true){
          String line = reader.readLine();
          if(line ==null){
            break;
          }else{
            System.out.println("line is "+line);
          }
    // I am guessing that here after reading the packets, I need to forward them to the actual server. 

        }}

который давал мне следующий вывод

02-21 19:12:26.074 16435-16778/awesomedroidapps.com.debugger I/System.out: line is E����@�'@��@������<��5��,��������������������graphfacebookcom������E����@�(@��
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is E����@[email protected]��@����d�:�N����P�V�x�%0/�W�����
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is ��EP���
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is �%0.�%0/E����L�@��@�����Ɂ��5��8�[�����������������apploadingestcrittercismcom������E����@�:@��@�����d6�� �>�Wz� y�A�x�[����
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is ��[email protected]�
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is y�1�y�7E����A�@��@��������5��-��-�����������������decidemixpanelcom������E������;@��@�F���d6��   �>�Wz�y�A�x������
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is ��]@���F����BA   �+��q�ϔ���Jb2_'�D�y�̯��[:�1)���PΠ�ѡ���h71�L�3�=~������(�����������������S�~'U������9d_���"�I�E����@[email protected]��@�
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is ���d�:�N����P�V�x�%0/�W������
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is ��^P���
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is �%0.�%0/E����=�@��@���������5��)l����������������t   appsflyercom������E����=�@��@������6��5��)�.����������������t   appsflyercom������E����@[email protected]��@����d�:�N����P�V�x�%0/�W������
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is ���P���

Из журналов видно, что я могу захватить исходящие пакеты в TUN. Вышеупомянутые журналы где-то печатают хосты, такие как facebook.com, что заставляет меня поверить, что я на правильном пути.

Но что мне делать дальше после этого? Как пересылать данные на сервер? Я считаю, что есть меньше рабочих примеров. Но может кто-нибудь дать мне шаг за шагом процедуру о том, как достичь этой цели?

Обновление. При дальнейшем копании я узнал, что мне нужно создать сервер и переслать перехваченные пакеты на сервер. Я создал сервер на своем компьютере и смог успешно пересылать перехваченные пакеты на мой сервер. Но я не уверен, как получить фактический IP-адрес и порт назначения из полученного пакета, чтобы я мог отправить их в назначенный пункт назначения.

PS. Я также прошел через JnetPcap библиотеку, но, похоже, для захвата живых пакетов телефон должен быть который не является требованием моего приложения.

Ответы

Ответ 1

Довольно уверен, что лучше всего настроить прокси-сервер, а затем использовать что-то вроде wireshark для мониторинга трафика, идущего туда и обратно. Я не эксперт в этом, но в старые времена, прежде чем коммутаторы маршрутизаторов были настолько дешевы, это было очень легко, потому что все пакеты были переданы всем компьютерам в одной подсети. Возможно, если вы сможете получить хаб/маршрутизатор, который имеет возможность отключить переключение, вы можете использовать этот метод вместо прокси.

В наши дни большинство коммитов выполняется с использованием http и для этого у вас есть отличные инструменты, такие как Charles (mac) и Fiddler (windows), которые делают именно то, что вы хотите, за исключением http. Они могут по крайней мере дать вам идеи о том, как сделать то же самое с Wireshark