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.