VPN数据包旁路

时间:2014-07-27 10:38:53

标签: java android parsing ip vpn

我正致力于创建模拟VPN(实际上并不创建与服务器的真实连接)以获取所有传入和传出网络字节(信息)。

现在我可以获取数据包并解析它们。我得到的例子:

IP版本:4 标题长度:20 总长度:60 协议:6 来源IP:10.0.2.0 目的地IP:5.20.5.59 主机名:clients4.google.com

我想知道如何与网站/应用程序建立联系(目前它还没有连接)。

在此网站中:http://www.thegeekstuff.com/2014/06/android-vpn-service/写道,需要执行以下步骤:

  1. 从TUN获取IP数据包。与所有VPN服务相同。
  2. 提取第4层信息。协议类型(例如TCP / UDP)及其 有效载荷是必须的。由于之前在TCP中存在握手过程 从中获取实际的有效载荷数据,我们需要回写 先握手包。
  3. 选择相应的套接字以发送有效负载。这一步是 在第4层工作,所以我们需要保存套接字并尝试获取 稍后返回数据。如果有任何返回数据,我们需要通过 这些数据包发送到TUN。
  4. 从套接字获取数据包,并构建第3层数据包。首先,我们需要 构建有效的第4层数据包。 UDP比4字节容易一些 UDP标头仅包含源地址,源端口,目标 地址,目的地端口。 TCP更复杂,因为它是一个状态
  5. 连接,序列号和确认号应该是 设置得当。然后,使用第4层数据包作为有效载荷,我们需要 构建有效的第3层数据包。将IP数据包写回TUN。与...一样 所有VPN服务都可以。
  6. 在第2步,我从数据包中获取信息。但不要轻视应该如何进一步做。也许有人可以详细解释我。另外,也许可以告诉我如何获得目的地港口,当我有其IP地址。还有代码:

        public class VPN extends VpnService implements Handler.Callback, Runnable {
        private static final String TAG = "VpnService";
    
        private String mServerAddress = "127.0.0.1";
        private int mServerPort = 55555;
    
        private Handler mHandler;
        private Thread mThread;
    
        private ParcelFileDescriptor mInterface;
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            if (mHandler == null) {
                mHandler = new Handler(this);
            }
    
            if (mThread != null) {
                mThread.interrupt();
            }
            mThread = new Thread(this, "VpnThread");
            mThread.start();
            return START_STICKY;
        }
    
        @Override
        public void onDestroy() {
            if (mThread != null) {
                mThread.interrupt();
            }
            super.onDestroy();
        }
    
        @Override
        public boolean handleMessage(Message message) {
            if (message != null) {
                Toast.makeText(this, (String) message.obj, Toast.LENGTH_SHORT).show();
            }
            return true;
        }
    
        @Override
        public synchronized void run() {
            try {
                Log.i(TAG, "Starting");
                InetSocketAddress server = new InetSocketAddress(mServerAddress, mServerPort);
                run(server);
    
            } catch (Exception e) {
                Log.e(TAG, "Got " + e.toString());
                try {
                    mInterface.close();
                } catch (Exception e2) {  }
                Message msgObj = mHandler.obtainMessage();
                msgObj.obj = "Disconnected";
                mHandler.sendMessage(msgObj);
    
            } finally {
    
            }
        }
    
        DatagramChannel mTunnel = null;
    
    
        protected boolean run(InetSocketAddress server) throws Exception {
            boolean connected = false;
    
            mTunnel = DatagramChannel.open();
    
            if (!protect(mTunnel.socket())) {
                throw new IllegalStateException("Cannot protect the tunnel");
            }
    
            mTunnel.connect(server);
    
            mTunnel.configureBlocking(false);
            handshake();
    
            connected = true;
            Message msgObj = mHandler.obtainMessage();
            msgObj.obj = "Connected";
            mHandler.sendMessage(msgObj);
    
    
    
            new Thread ()
            {
    
                public void run ()
                {
                    FileInputStream in = new FileInputStream(mInterface.getFileDescriptor());
                    ByteBuffer packet = ByteBuffer.allocate(32767);
    
                    DatagramChannel tunnel = mTunnel;
                    FileOutputStream out = new FileOutputStream(mInterface.getFileDescriptor());
                    int length;
                    String destIP;
    
                    try
                    {
    
                        while (true)
                        {
                            while ((length = in.read(packet.array())) > 0) {
                                packet.limit(length);
                                Log.d(TAG, "Total Length:" + mTunnel.socket().getInetAddress());
    
                                mTunnel.write(packet);
                                packet.flip();
    
                                TCP_IP TCP_debug = new TCP_IP(packet);
                                TCP_debug.debug();
                                destIP = TCP_debug.getDestination();
    
                              //  InetAddress address = InetAddress.getByName(destIP);
                              //  System.out.println(address.getHostAddress()); // Gaunamas IP (185.11.24.36)
                              //  System.out.println(address.getHostName()); // www.15min.lt
    
    
    
                                out.write(packet.array(), 0, length);
                                packet.clear();
    
                                Thread.sleep(100);
    
                            }
                        }
    
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
    
                }
    
            }.start();
    
    
            return connected;
        }
    
        private void makeConnection(String destination, int port) {
            try {
                run(new InetSocketAddress(destination, port));
            }
            catch (Exception e) {
                Log.d(TAG, "klaida jungiantis");
            }
        }
        private void handshake() throws Exception {
    
            if (mInterface == null)
            {
                Builder builder = new Builder();
    
                //builder.setMtu(1500);
                //builder.addAddress("10.0.2.0", 32);
               // builder.addRoute("0.0.0.0", 0);
                 builder.addAddress("192.168.0.1", 24);
                 builder.addDnsServer("8.8.8.8");
                 builder.addRoute("0.0.0.0", 0);
    
                try {
                    mInterface.close();
                } catch (Exception e) {
                    // ignore
                }
    
                mInterface = builder.setSession("VPN'as").establish();
            }
        }
    
    
    }
    
    
    
    public class TCP_IP extends VPN {
    
        private ByteBuffer packet;
        private String hostname;
        private String destIP;
        private String sourceIP;
        private int version;
        private int protocol;
        private int port;
    
    
        public TCP_IP(ByteBuffer pack) {
            this.packet = pack;
        }
    
        public void debug() {
    
    
            int buffer = packet.get();
            int headerlength;
            int temp;
    
            version = buffer >> 4;
            headerlength = buffer & 0x0F;
            headerlength *= 4;
            System.out.println("IP Version:"+version);
            System.out.println("Header Length:"+headerlength);
            String status = "";
            status += "Header Length:"+headerlength;
    
            buffer = packet.get();      //DSCP + EN
            buffer = packet.getChar();  //Total Length
    
            System.out.println( "Total Length:"+buffer);
    
            buffer = packet.getChar();  //Identification
            buffer = packet.getChar();  //Flags + Fragment Offset
            buffer = packet.get();      //Time to Live
            buffer = packet.get();      //Protocol
    
            protocol = buffer;
            System.out.println( "Protocol:"+buffer);
    
            status += "  Protocol:"+buffer;
    
            buffer = packet.getChar();  //Header checksum
    
    
            byte buff = (byte)buffer;
    
            sourceIP  = "";
            buff = packet.get();  //Source IP 1st Octet
            temp = ((int) buff) & 0xFF;
            sourceIP += temp;
            sourceIP += ".";
    
            buff = packet.get();  //Source IP 2nd Octet
            temp = ((int) buff) & 0xFF;
            sourceIP += temp;
            sourceIP += ".";
    
            buff = packet.get();  //Source IP 3rd Octet
            temp = ((int) buff) & 0xFF;
            sourceIP += temp;
            sourceIP += ".";
    
            buff = packet.get();  //Source IP 4th Octet
            temp = ((int) buff) & 0xFF;
            sourceIP += temp;
    
            System.out.println( "Source IP:"+sourceIP);
    
            status += "   Source IP:"+sourceIP;
    
    
            destIP  = "";
    
    
            buff = packet.get();  //Destination IP 1st Octet
            temp = ((int) buff) & 0xFF;
            destIP += temp;
            destIP += ".";
    
            buff = packet.get();  //Destination IP 2nd Octet
            temp = ((int) buff) & 0xFF;
            destIP += temp;
            destIP += ".";
    
            buff = packet.get();  //Destination IP 3rd Octet
            temp = ((int) buff) & 0xFF;
            destIP += temp;
            destIP += ".";
    
            buff = packet.get();  //Destination IP 4th Octet
            temp = ((int) buff) & 0xFF;
            destIP += temp;
    
            System.out.println( "Destination IP:" + destIP);
            status += "   Destination IP:"+destIP;
    
    
    
    
        }
    
        public String getDestination() {
            return destIP;
        }
    
        public int getProtocol() {
            return protocol;
        }
    
        public int getPort() {
            return port;
        }
    
        public String getHostname() {
            return hostname;
        }
    
        public int getIPversion() { return version; }
    
    }
    

1 个答案:

答案 0 :(得分:0)

更改

private String mServerAddress = "127.0.0.1";

private String mServerAddress = "10.0.0.1";

我不知道答案并解释发生了什么,但我在Android Monitor中看到我们无法将localhost(127.0.0.1)用于服务器地址。

使用SSL over HTTP(HTTPS)还有另一个问题。如果您在http://www.gorio.com.br这样的网站中进行连接,则会有效,但如果您尝试https://www.google.com则无法使用。