-
Notifications
You must be signed in to change notification settings - Fork 301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Built-in TLS Decryption #57
Comments
With the purpose of minimizing the dependencies, here is a quick overview of the LittleProxy-mitm depedencies (max depth 3):
@koh-osug can you please clarify the need for the additional dependencies of LittleProxy-mitm over LittleProxy? E.g. jdk15to18 and conscrypt. Regarding the project structure, I think it's better to keep LittleProxy-mitm in a separate code base, unless it requires a tight integration with PCAPdroid. |
I will check with my Android test project how much is left after using the Android shrinker. Usually almost all from the utilitiy libraries and major parts of bouncy castle should get removed resulting in just a few HD floppy disks. |
Great! I think LittleProxy should be run as a thread in PCAPdroid and communicate with it via the socks5 interface (will I will take care of the socks5 migration asap). This will allow PCAPdroid to carry on the TLS decryption asynchronously while processing the network packets in parallel. I've added a roadmap for this feature in the issue description above, we can work on a branch until it is complete. You can proceed with the integration. Once the embedded LittleProxy works correctly, I will take care of the final step to show the decrypted data in PCAPdroid/in the PCAP. For this I will need a call API in LittleProxy-mitm to read the decrypted data back in PCAPdroid. The API should expose: the decrypted data |
Filtering the HTTP request seems to be possible with LittleProxy. I hope the filter is the one seeing the plain text. How will you map the plain text to the original requests? I can record the plain text, but somehow then later you have to know which plain text corresponds to which encrypted text. |
1.3 MB is a good result, I think we can settle with this. Great work!
The idea is the following: when LittleProxy is started I will register a callback (via a java interface). Whenever the proxy decrypts a packet, it will call the callback with the decrypted data and the connection information (original 5 tuple). With the 5 tuple I can retrieve the original connection and set the plain text data. In b029895 I've implemented the SOCKS5 proxy client. This replaces the old "tunnel" mode. You should now be able to redirect the TCP packets to LittleProxy by using SOCKS5. Edit: another step is required in order to make this work with an embedded LittleProxy. Since LittleProxy will make connections on his own, we must exclude these connections from the VPN, otherwise they will go back into the VPNService in a loop. To do this, the VpnService protect api must be called on every socket open by LittleProxy. In order to keep LittleProxy clean, I'd suggest to do this by registering a callback at LittleProxy startup via a java interface. Of course I'm assuming that LittleProxy provides an api to extract the raw socket from netty. |
I will have a look into this. My first concern is if LittleProxy is actually supporting SOCKS5. I'm not familiar with the protocol, but what I see is that it needs a HTTP CONNECT call to trigger the proxy. |
I'm investigating this one as alternative: https://github.com/chhsiao90/nitmproxy |
I had an issue with nitmproxy because the addresses received from SOCKS have been IP addresses, no hostnames anymore. I added a handler to extract the Server Name Indication and this looks good now. I created a fork and check its stability. LittleProxy might be maintained, but it is focusing too much on HTTP, nitmproxy supports more protocols and has the MITM feature is included. I have tested in under Linux and by connecting from Android to it. |
Have you tested it with TLS 1.3 and HTTP2? A SOCKS proxy opens up more possibilities so I also encourage this choice. |
I have tested the page "https://tools.keycdn.com/http2-test" with FF usign the HTTP2 protocol. The web page is working. |
Great! Please provide a pull request/branch to review when ready! If you want a more interactive technical discussion you can reach me on the telegram group |
Sure, will do. I have an issue with a specific domain. I'm in contact with the developer and I'm analyzing this. It is not a problem in a PC environment, but the same code is not working on Android. Most likely the Android SSLEngine stack is behaving differently. But the website seems to use a strange combination of TLS protocols, I could not detect this with any other web page. |
The Android internal SSL Engine seems to have some issues with TLS 1.3 and ALPN. I have patched netty to be able to use the BouncyCastle TLS implementation which is working for the above mentioned issue. I will wait until this gets accepted to have it available as published dependency. |
The nitmproxy can now transparently detect HTTP/HTTPS and supports also at least Android 8. I have also some older phones which I can check. A new API was added to plugin loggers I will add an AIDL interface around this so that PCAPdroid can call this. |
The android emulator is a convenient tool to test stuff on different SDK versions and devices. I see that the API is HTTPS oriented, does it provide a way to handle non HTTPS traffic? Also I think it could be better to run the proxy as a thread in PCAPdroid, to save IPC complexity and overhead. |
OK, not having it as separate app makes it simpler. Non HTTP is still on the TO DO list. |
Hi! |
Whatever is supported by conscrypt using the Java SSL engine can be supported. If this is not on the roadmap of both support will only be possible with external SOCKS based proxy tools supporting quic. |
@emanuele-f Hi emanuele! Any update on this topic? |
The necessary upstream project nitmproxy is now supporting non HTTP data, I'm currently testing it. If it works, a data logger must be still added, but I then we are almost there. |
@koh-osug any update on this? Can I help with the tests? |
Sorry, taking longer than expected. I tested SMTP, IMAP and HTTPS. Looks good. You can test the latest version from it from the command line, too: https://github.com/chhsiao90/nitmproxy |
PCAPdroid has minSdkVersion 21, on which android version the built-in Conscrypt provides ALPN support (links appreciated)? The loggers callbacks can be adapted at any time (e.g. via a fork), that's not a problem. Ps. Here is the link to for BouncyCastle missing TLS renegotiation support: bcgit/bc-java#593 |
The APLN support requires a backport from a later Java 9 version to Android (OpenJDK 9+181). The important method is |
Thanks for the clarification. 2 MB overhead is ok, but 8 seems too much to me. Anyway, please note that if BouncyCastle is integrated into PCAPdroid, it must meet the f-droid policy, so it is either built as a submodule or it is downloaded from a trusted repository. |
I have raised a pull request in nitmproxy: chhsiao90/nitmproxy#73 to provide the connection context with the log handler. source/dest IP + port + transmitted data would be sufficient, I assume? |
The nitmproxy maintainer seems not to handle this. So, I started on my own, I think I'm on the right track now, actually it seems simple, let's see how it works. |
I'm looking again at this problem as this feature is something users are demanding. The Java libraries evaluated so far are not actively developed and in my opinion they are not mature enough to carry on this task. The only tool which I trust can do the job is mitmproxy. In #123 I've implemented a plugin which can pass the HTTP and websockets decrypted data to PCAPdroid. My idea to implement the built-in decryption is to bundle mitmproxy with its dependencies so that PCAPdroid can start/stop it at will and receive the decrypted data. This may either be implemented directly in PCAPdroid or into a separate app. The only obstacle to this is python. It seems like building python for Android is not easy and most projects on this matter are now abandoned. The most promising one seems to be chaquopy, although closed source. I've start experimenting with it but faced dependency issues. Another candidate is python-for-android. In short, I'm willing to implement a very basic app with mitmproxy which can be controlled by PCAPdroid. I'm opting for a separate apk right now both for convenience and because in my tests bundling python with mitmproxy requires about 10 MB of overhead per ABI (so x4) in the apk size. |
With 6f42015 the built-in decryption is now integrated. The decryption requires the installation of the PCAPdroid-mitm addon as a separate apk. I've decided to separate it from the PCAPdroid app because of the size (the addon apk is about ~36 MB) and because it relies on the third-party chaquopy gradle plugin, which is closed source and it has build-time dependencies which complicate the build. This is just an initial integration and there are a lot of things to improve. |
These are good news. Is the chaquopy approach raising any security concerns? I.e. because it is closed source, is it safe to used it without any risk of hidden code? |
These concerns are legit for any closed source software. chaquopy is quite a complicate plugin so it's not easy to review it, but given that it widely known, it has a public github page for issues and a clear monetization plan, I think we can trust it. One drawback though is that the license code cannot be make public, so people trying to build the In short, it does its job and it does it well, although it's not open source. Unless other equivalent foss solutions are implemented, this is what we have now and I'm very satisfied with the result. |
So for now, is there any option to produce decryptable or decrypted pcap file for analysis in wireshark? |
Thank you for this useful package! I have a question which, I guess, is similar to the one by @kenduq. How does one decrypt the PCAP file with the help of the new plugin? I installed the plugin but I couldn't see any changes in the app itself. Are decryption keys saved separately somewhere? |
This is not released yet. You either need to build PCAPdroid from source (dev branch) or install a pre-built debug apk. Here is a pre-built apk for the latest commit. Then you should enable the "TLS decryption (preview)" option in the PCAPdroid settings.
This is still a work in progress, at the moment the app shows the decrypted HTTP request data (see this screenshot). I'm implementing the ability to show the full HTTP request/response in the app. See below for decryption keys.
I've just added (in 12727bd) the ability to export the decryption keys, to be used in Wireshark. Be sure to install the latest debug apk (link above), then you can export them (the capture must be running): This link explains how to load them in Wireshark. A more practical way to get a decryptable pcap will be available with #185 |
Tried to export SSL keylog file but the exported .txt file is empty. |
The keylog must be exported after the HTTPS connection is established. The ability to inspect the full HTTP payload from PCAPdroid is now implemented, check out #107 (comment) . A lock icon now reports the state of the decryption.
|
In latest debug version i can see the app crashing and also hanging when "Full payload" toggle is turned on. |
Should be fixed in fe26ecc. New debug apk. |
Consider also creating whitelist of apps that may be captured. I guess then the whitelist structure may be like that:
I don't know what's more reliable for version detection - i.e. when loading list of target apps you can mark them:
The idea is that amount of directly decryptable apps will be small and finally they won't update each day. So there will be added software confirmed by community, so I'm not sure that this list will be updated very often. I guess also it's worth to make minimal in-app update of this list to once per week or even less (but with ability to manually update). Also one more notice is to avoid adding to list ROM-specific apps, i.e. something with package |
Today I tested the beta TLS decryption with a patched Signal apk and it worked in PCAPdroid. I could see decrypted TLS packets. But in wireshark via the http server and also after saving the pcap in pcapdroid and opening this file afterwards in wireshark I could only see encrypted TLS packets. Edit: I noticed that I can export the SSLKEYLOG. However that crashes the app with the debug release. If I see correctly this should be fixed with 6854284 |
Try this one. The keylog file is now exported when the capture is stopped. If you still experience the crash, please report the stack trace |
Thank you very much and also for the fast response. Worked like a charm. |
This will be implemented in #185 |
This is a great addition to PCAPdroid, and I look forward to using it for my research. Might it be possible to add an option to drop UDP traffic on port 443? This usually prevents apps from using QUIC, and instead makes these apps fallback to TCP. There might be some complications with some Private DNS solutions -- in this case, one might just let the user know that this must be disabled? |
I read that this fallback behavior is implemented by chrome. Is this part of the standard or it only applies to some apps? Please provide more info in a separate issue and also possibly an example on how it helps with decryption
Private DNS should user TLS on port 443. Do any of them use UDP on port 443? |
Not sure if this is part of a standard. I guess some firewall configurations don't allow UDP on port 443, and thus a fallback is usually needed. From my personal experience analysing thousands of Android apps, blocking UDP on port 443 works pretty well. I've opened a new issue #213.
Actually, no. I just checked that. Just wasn't sure! EDIT: This has been added to PCAPdroid now. |
At the current status, PCAPdroid requires an external proxy in order to decrypt TLS packets. On the other hand, a built-in solution would provide the following advantages:
decrypteddecryptable PCAPRequirements
Candidates
Other approaches:
java.nio
for networking, which fits the minimal dependencies requirementUser Experience
Users will have an option to enable the built-in TLS decryption by a toggle. The old mitmproxy option will be replaced with a more generic ability to use socks5 proxy, which is independent from the TLS decryption. Once enabled, the TLS decryption will happen under the hoods; android proxy settings will be untouched. It will have the following effects:
The PCAP will also contain the decrypted payload data in place of the original TLS dataThe traffic could be dumped in the PCAPNG file format, which contains a "Decryption Secrets Block" to store the decryption keys.In essence TLS will be decapsulated and its inner data shown.
Roadmap
The built-in decryption is now implemented via the PCAPdroid-mitm addon.
sslunpinning
) and Certificate transparency (avoid using a system cert or use magisk hide) - see the docsThe text was updated successfully, but these errors were encountered: