1

I need to be able to see the path (and headers if possible) of HTTPS connections made through my VpnService that hosts a local VPN server. Is this possible?

For instance, when going to https://google.com/somedir/somejsfile.js, I need to be able to see the whole path (eg. google.com/somedir/somejsfile.js) instead of the SNI (google.com). Is this possible IN ANY WAY, while being safe for end users?

I have managed to handle HTTP requests successfully and see the HTTP requests successfully, however, nowadays most traffic is over HTTPS, so I need a way to somehow see the request headers over HTTPS too.

The following code shows how i establish the VpnService, and read/write the incoming/outgoing packets respectively.

private void runVPN() throws Exception {
        this.mVPNInterface = establishVPN();
        this.mVPNOutputStream = new FileOutputStream(mVPNInterface.getFileDescriptor());
        FileInputStream in = new FileInputStream(mVPNInterface.getFileDescriptor());
        int size = 0;
        while (size != -1 && IsRunning) {
            while ((size = in.read(mPacket)) > 0 && IsRunning) {
                if (mDnsProxy.Stopped || mTcpProxyServer.Stopped) {
                    in.close();
                    throw new Exception("LocalServer stopped.");
                }
                onIPPacketReceived(mIPHeader, size);
            }
            Thread.sleep(100);
        }
        in.close();
        disconnectVPN();
    }

    void onIPPacketReceived(IPHeader ipHeader, int size) throws IOException {

        switch (ipHeader.getProtocol()) {
            case IPHeader.TCP:
                TCPHeader tcpHeader = mTCPHeader;
                tcpHeader.mOffset = ipHeader.getHeaderLength();
                if (tcpHeader.getSourcePort() == mTcpProxyServer.Port) {
                    NatSession session = NatSessionManager.getSession(tcpHeader.getDestinationPort());
                    if (session != null) {
                        ipHeader.setSourceIP(ipHeader.getDestinationIP());
                        tcpHeader.setSourcePort(session.RemotePort);
                        ipHeader.setDestinationIP(LOCAL_IP);

                        Utility.ComputeTCPChecksum(ipHeader, tcpHeader);

                        mVPNOutputStream.write(ipHeader.mData, ipHeader.mOffset, size);
                        mReceivedBytes += size;
                        /*
                        mVPNOutputStream.write(ipHeader.mData, ipHeader.mOffset, size);
                        mReceivedBytes += size;*/
                    } else {
                        Log.d(TAG, "NoSession: " + ipHeader.toString() + " " + tcpHeader.toString());
                    }

                } else {

                    int portKey = tcpHeader.getSourcePort();
                    NatSession session = NatSessionManager.getSession(portKey);
                    if (session == null || session.RemoteIP != ipHeader.getDestinationIP() || session.RemotePort
                            != tcpHeader.getDestinationPort()) {
                        session = NatSessionManager.createSession(portKey, ipHeader.getDestinationIP(), tcpHeader
                                .getDestinationPort());
                    }

                    session.LastNanoTime = System.nanoTime();
                    session.PacketSent++;

                    int tcpDataSize = ipHeader.getDataLength() - tcpHeader.getHeaderLength();
                    if (session.PacketSent == 2 && tcpDataSize == 0) {
                        return;
                    }

                    if (session.BytesSent == 0 && tcpDataSize > 10) {
                        int dataOffset = tcpHeader.mOffset + tcpHeader.getHeaderLength();
                        HttpRequestHeaderParser.parseHttpRequestHeader(session, tcpHeader.mData, dataOffset,
                                tcpDataSize);
                        // Log.d(TAG, "NatSession: " + session);
                        // Log.d(TAG, "Host: " + session.RemoteHost);
                        // Log.d(TAG, "Request: " + session.Method + " " + session.RequestUrl);
                    }

                    ipHeader.setSourceIP(ipHeader.getDestinationIP());
                    ipHeader.setDestinationIP(LOCAL_IP);
                    tcpHeader.setDestinationPort(mTcpProxyServer.Port);

                    Utility.ComputeTCPChecksum(ipHeader, tcpHeader);
                    mVPNOutputStream.write(ipHeader.mData, ipHeader.mOffset, size);
                    session.BytesSent += tcpDataSize;
                    mSentBytes += size;

                }
                break;
            case IPHeader.UDP:
                UDPHeader udpHeader = mUDPHeader;
                udpHeader.mOffset = ipHeader.getHeaderLength();
                if (ipHeader.getSourceIP() == LOCAL_IP && udpHeader.getDestinationPort() == 53) {
                    mDNSBuffer.clear();
                    mDNSBuffer.limit(udpHeader.getTotalLength() - 8);
                    DnsPacket dnsPacket = DnsPacket.fromBytes(mDNSBuffer);
                    if (dnsPacket != null && dnsPacket.Header.QuestionCount > 0) {
                        mDnsProxy.onDnsRequestReceived(ipHeader, udpHeader, dnsPacket);
                    }
                }
                break;
        }

    }

Any help or direction regarding this question is greatly appreciated.

Thank you in advance.

Skosh
  • 165
  • 1
  • 9

0 Answers0