Guides/Monitoring network traffic from an Android app: Difference between revisions
m →Step 2. Set up proxy settings on the mobile device: Change image sizes |
No edit summary |
||
(19 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
* access to a Wi-Fi network that you can connect to with the computer and the mobile device. | * access to a Wi-Fi network that you can connect to with the computer and the mobile device. | ||
== | == Install a proxy server == | ||
In this guide, we will use the [https://www.charlesproxy.com/ Charles proxy server]. There may be other, better alternatives that I have not tried using. Feel free to edit this guide if you feel like you have a better proxy server. | In this guide, we will use the [https://www.charlesproxy.com/ Charles proxy server]. There may be other, better alternatives that I have not tried using. Feel free to edit this guide if you feel like you have a better proxy server. | ||
'''Note:''' The free trial version of ''Charles'' only allows for 30-minute sessions. After that time passes, you can reopen Charles to continue using it. | '''Note:''' The free trial version of ''Charles'' only allows for 30-minute sessions. After that time passes, you can reopen ''Charles'' to continue using it. | ||
# Go to https://www.charlesproxy.com/download/ on your computer, and download the version of ''Charles'' for your operating system. | # Go to https://www.charlesproxy.com/download/ on your computer, and download the version of ''Charles'' for your operating system. | ||
Line 19: | Line 19: | ||
# At the top bar, select the option ''Help > SSL Proxying > Install Charles Root Certificate on a Mobile Device or Remote Browser''.<br><br>[[File:Charles Proxy Screenshot SSL Proxying.png|thumb|600px|center|alt=Screenshot of Charles Proxy, selecting the option Help > SSL Proxying > Install Charles Root Certificate on a Mobile Device or Remote Browser.]]<br>This will show a message box with your computer's local IP address and a port. In the next step, we will use this information to connect the mobile device to the proxy server.<br><br>[[File:Charles Proxy Screenshot Install Charles Root Certificate on a Mobile Device or a Remote Browser Popup.png|thumb|600px|center|alt=Pop-up window, showing the local IP address and port of the proxy server. In this case: 192.168.3.57:8888.|In this example, the IP shown on the pop-up is: 192.168.3.57, and the port is: 8888.]] | # At the top bar, select the option ''Help > SSL Proxying > Install Charles Root Certificate on a Mobile Device or Remote Browser''.<br><br>[[File:Charles Proxy Screenshot SSL Proxying.png|thumb|600px|center|alt=Screenshot of Charles Proxy, selecting the option Help > SSL Proxying > Install Charles Root Certificate on a Mobile Device or Remote Browser.]]<br>This will show a message box with your computer's local IP address and a port. In the next step, we will use this information to connect the mobile device to the proxy server.<br><br>[[File:Charles Proxy Screenshot Install Charles Root Certificate on a Mobile Device or a Remote Browser Popup.png|thumb|600px|center|alt=Pop-up window, showing the local IP address and port of the proxy server. In this case: 192.168.3.57:8888.|In this example, the IP shown on the pop-up is: 192.168.3.57, and the port is: 8888.]] | ||
== | == Set up proxy settings on the mobile device == | ||
[[File:Proxy Settings Android Screenshot.jpg|thumb|x500px|right|alt=A screenshot showing proxy settings on Android.|In this example, we set the Host Name to 192.168.3.57, and the port to 8888 - the same values as shown in the Charles pop-up earlier.]] | [[File:Proxy Settings Android Screenshot.jpg|thumb|x500px|right|alt=A screenshot showing proxy settings on Android.|In this example, we set the Host Name to 192.168.3.57, and the port to 8888 - the same values as shown in the Charles pop-up earlier.]] | ||
Line 26: | Line 26: | ||
# On your mobile device, go to ''Settings > Wi-Fi'' and select your Wi-Fi network. | # On your mobile device, go to ''Settings > Wi-Fi'' and select your Wi-Fi network. | ||
# Under ''Advanced settings'', change ''Proxy'' to ''Manual'' | # Under ''Advanced settings'', change ''Proxy'' to ''Manual''. | ||
# Set the ''Host Name'' and ''Port'' settings to the IP address and port displayed in the ''Charles'' pop-up window in step 1. | # Set the ''Host Name'' and ''Port'' settings to the IP address and port displayed in the ''Charles'' pop-up window in step 1. | ||
# Save the settings. | # Save the settings. | ||
# If everything was done correctly, a pop-up should appear in ''Charles'', informing of a new connection. Click on "Allow" to allow the proxy connection. If you click "Deny" on accident, you can simply restart ''Charles'' and try to connect to the proxy again.<br><br>[[File:Charles Proxy Screenshot New Connection Popup.png|600px|thumb| | # If everything was done correctly, a pop-up should appear in ''Charles'', informing of a new connection. Click on "Allow" to allow the proxy connection. If you click "Deny" on accident, you can simply restart ''Charles'' and try to connect to the proxy again.<br><br>[[File:Charles Proxy Screenshot New Connection Popup.png|600px|thumb|center|alt=A pop-up informing the user of a new connection to the proxy.|This pop-up window should appear on your computer after saving proxy settings on the mobile device.]]<br> | ||
# <div style="clear:both;"></div> After clicking allow, you can see some network traffic going through. You can try opening apps on your phone, and new entries will appear.<br><br>[[File:Charles Proxy Screenshot Structure View.png|800px|thumb|center|alt=A screenshot of Charles, showing some network traffic as a structured tree-like view.|Network traffic from your mobile device, shown on your computer.]]<br>You can also enable ''Sequence view'' by clicking the ''Sequence'' tab on the top. This will show all of the network traffic in chronological order, with the most recent requests on the bottom.<br><br> | # <div style="clear:both;"></div> After clicking allow, you can see some network traffic going through. You can try opening apps on your phone, and new entries will appear.<br><br>[[File:Charles Proxy Screenshot Structure View.png|800px|thumb|center|alt=A screenshot of Charles, showing some network traffic as a structured tree-like view.|Network traffic from your mobile device, shown on your computer.]]<br>You can also enable ''Sequence view'' by clicking the ''Sequence'' tab on the top. This will show all of the network traffic in chronological order, with the most recent requests on the bottom.<br><br> | ||
[[File:Charles Proxy Screenshot Sequence View.png|900px|thumb|center|alt=A screenshot of Charles, showing some network traffic as a list of requests.|''Sequence view'' might be more helpful in some cases.]] | [[File:Charles Proxy Screenshot Sequence View.png|900px|thumb|center|alt=A screenshot of Charles, showing some network traffic as a list of requests.|''Sequence view'' might be more helpful in some cases.]] | ||
Line 43: | Line 43: | ||
In the next steps, we will install a custom certificate and modify an application, which will allow us to intercept HTTPS requests as well. | In the next steps, we will install a custom certificate and modify an application, which will allow us to intercept HTTPS requests as well. | ||
== | == Install a certificate to the mobile device == | ||
To look inside HTTPS requests, we need to install a certificate to our mobile device. | |||
[[File:Charles proxy downloadfile.crt Screenshot.jpg|x500px|thumb|right|After navigating to <code>chls.pro/ssl</code>, click on the "Download" button to download the certificate.]] | |||
[[File:User certificate safety popup Android Screenshot.jpg|x500px|thumb|alt=Screenshot of a safety warning that appears when installing a custom certificate on Android.|A screen warning you of the potential dangers of using a certificate that you don't trust.]] | |||
# On your mobile device, open your browser and type <code>chls.pro/ssl</code> into the URL bar, while connected to the proxy. This will allow you to download the certificate for your instance of ''Charles''. Tap on the "Download" button to confirm that you want to download the certificate file.<br>This URL is also shown in the ''Help'' pop-up window in ''Charles'' - it's in the same pop-up that we used to get the IP and port for the proxy settings. | |||
# Go to ''Settings'' and search for options about certificates. On my device, it is under ''Settings > Password & security > System security > Credential storage''. From here, you should be able to view, add, and remove certificates installed on the system.<br>[[File:Credential storage Android Screenshot.jpg|x300px|thumb|center|alt=Screenshot of the "Credential storage" menu in Android Settings|Here, you can view, install and remove certificates from your device.]]<br> | |||
# Select ''Install certificates from storage'', and then ''CA certificate''.<br>[[File:Install a certificate menu Android Screenshot.jpg|x300px|thumb|center|alt=Screenshot of the "Install a certificate" menu in Android Settings|Choose the "CA certificate" option on this screen.]]<br> | |||
# A pop-up may show up, warning you of the safety concerns related to adding custom certificates. Read it, and if you are sure you want to do this, tap on ''Install anyway''.<br>'''Remember!''' After you are done exploring network traffic from an app, you can remove the certificate by going into this settings menu, selecting ''Trusted certificates'', switching to the ''User'' tab, selecting the certificate and tapping on ''Uninstall''. | |||
# You may be asked to verify your identity. After confirming your identity, you will be asked to choose a file. Select the file you downloaded before - it should be named <code>downloadfile.crt</code> and it should be located in your <code>Downloads</code> folder. [[File:Downloadfile.crt screenshot.jpg|x300px|thumb|center|alt=Screenshot of an Android file picker, with a downloadfile.crt file visible. |Choose the downloaded certificate file (usually called <code>downloadfile.crt</code>)]] | |||
# After selecting the file, the certificate should be installed. You can verify that, by going into the ''Trusted certificates'' menu, and selecting the ''User'' tab - your certificate should be there. You can tap on it to view detailed information about the certificate or uninstall it if you don't need it anymore. | |||
[[File:Charles proxy certificate installed on Android screenshot.jpg|x300px|thumb|center|alt=Screenshot of the "Trusted certificates" menu in the Android settings, showing a Charles proxy certificate.|The certificate was installed successfully.]] | |||
The certificate should now be installed properly on the mobile device, however we still will not be able to see HTTPS traffic in ''Charles''. | |||
== Enable SSL Proxying in ''Charles'' == | |||
To enable SSL proxying in ''Charles'', do the following steps: | |||
# From the menu bar at the top, select ''Proxy > SSL Proxying Settings...''. [[File:Charles Proxy Screenshot Proxy SSL Proxying Settings.png|600px|thumb|center|alt=Screenshot of Charles Proxy, selecting the option Proxy > SSL Proxying Settings...]] | |||
# Make sure the ''Enable SSL Proxying'' checkbox is enabled. | |||
# Below the ''Include'' table, click on ''Add''. | |||
# In the pop-up, for the ''Host'' field, enter <code>*</code> and leave the ''Port'' field empty. This will make it so all hosts' HTTPS requests will be captured and attempted to be read by ''Charles''. | |||
# Click on ''OK'' on the pop-up, and ''OK'' on the "SSL Proxying Settings" window. | |||
[[File:YouTube Android app cannot connect to servers Screenshot.jpg|x500px|thumb|right|alt=Screenshot of the Android app for YouTube trying to connect to the servers, but failing, because it doesn't trust the certificate signed by an user-installed certificate authority.|Now, the YouTube app does not load.]] | |||
If you now try to open an application on your mobile device, you will see that it will not be able to connect to the servers. This is because all traffic is now captured by ''Charles''. Most apps do not accept user-installed certificates as valid, which means even though our certificate is installed, the applications are acting as if it is an unknown certificate, and therefore cannot connect to the server at all. | |||
[[File:Charles Proxy Screenshot SSL Connection Errors.png|900px|thumb|center|''Charles'' now shows many errors - applications do not trust the user-installed certificate authority.]] | |||
If you want to allow some hostnames to use SSL as normal, you can add them to the ''Exclude'' table in the "SSL Proxying Settings" window. This setting makes it so ''Charles'' just acts as a pass-through for that specific host, and doesn't attempt to read any data inside of the requests. Alternatively, you can add hosts to the ''Include'' table instead of the <code>*</code> wildcard. This will make it so only the hosts in the ''Include'' table are captured by ''Charles''. | |||
== Get APK files of the application that we will modify == | |||
We will modify the application slightly so that it will accept user-installed certificates. In this guide, we will be using ''[[Rizline:Rizline|Rizline]]'' as an example. | |||
=== Install tools === | |||
First we will need to download some tools: | |||
* To connect to the device via a USB cable, we will use [https://developer.android.com/tools/adb Android Debug Bridge (adb)] | |||
* To decompile and build Android applications, we will use [https://apktool.org/ Apktool]. To download and install Apktool, follow the instructions on this page: https://apktool.org/docs/install. | |||
* To optimize the built APK, we will use [https://developer.android.com/tools/zipalign zipalign]. | |||
* To sign the modified APK, we will use [https://developer.android.com/tools/apksigner apksigner]. | |||
If everything is installed correctly, you should be able to open a terminal and type <code>adb</code>, <code>apktool</code>, <code>zipalign</code> and <code>apksigner</code> commands without errors. | |||
=== Get APK files from the device === | |||
[[File:Android Allow USB debugging popup screenshot.jpg|x500px|thumb|right|alt=Screenshot of a pop-up asking the user to allow or deny USB debugging on Android.|A pop-up that appears after connecting the mobile device to your computer, with <code>adb</code> installed. If the pop-up doesn't appear, try typing <code>adb</code> in the terminal, or try using a different USB cable.]] | |||
To modify the application files, we first need to get them onto our computer. | |||
<ol> | |||
<li>Enable USB Debugging on your mobile device.</li> | |||
* To do that, go to ''Settings > Additional settings > Developer options > USB debugging'' (found in the ''Debugging'' section). | |||
* If you cannot find the "Developer options" button, you might need to enable Developer Mode by going into ''Settings > About device > Version'' and tapping on the ''Build number'' option seven times. You should get a message saying "You are now a developer!" | |||
* If you have any trouble with this, try following [https://developer.android.com/studio/debug/dev-options the official instructions from developer.android.com]. | |||
<li>Connect your Android device to your computer using a USB cable. Choose "Android Auto" on your device if prompted.</li> | |||
<li> | |||
On your mobile device, a pop-up should appear, asking for permission to allow USB debugging. Tap on allow; and if you plan on doing this often, you might want to tap the checkbox to always allow USB debugging from this computer. If the pop-up doesn't appear immediately, don't worry; it might appear after typing the command in the next step.</li> | |||
<li>On your computer, open up a terminal and type: | |||
<pre> | |||
adb shell | |||
</pre> | |||
You should now have access to your mobile device on your computer via the terminal. | |||
[[File:Adb shell Screenshot.png|x40px|thumb|center|alt=A screenshot showing the command "adb shell" typed in a terminal.|''*hacking noises*'' we're in.]] | |||
</li> | |||
<li> | |||
Now we need to find the package ID of the app that we are interested in. One way of doing that is finding the ID in the list of installed packages. In <code>adb</code>, type the following command to show the list of packages installed on the device: | |||
<pre> | |||
pm list packages | |||
</pre> | |||
[[File:Pm list packages Screenshot.png.png|400px|thumb|center|alt=A screenshot showing a few of the 443 package IDs.|On my device, this command shows 443 packages. Here is a few of them.]] | |||
This command will only show the package IDs, so you cannot search by name. If you have a lot of applications installed, you might want to try piping the command to <code>grep</code>. <code>grep</code> is a command line utility that will filter down results by showing only the lines that have a specified string of text inside of them. For example the following command will show applications that contain the word "Pigeon" in their ID: | |||
<pre> | |||
pm list packages | grep Pigeon | |||
</pre> | |||
[[File:Pm list packages with grep example Screenshot.png|x80px|thumb|center|alt=A screenshot showing the filtered results with only two package IDs.|This time, only applications made by Pigeon Games will be shown.]] | |||
<br><br> | |||
Another way of getting the ID of an application, is just searching the app on the Google Play Store website. When you go to an application page on Google Play, the ID of the package will be embedded in the URL. For ''Rizline'', the link is https://play.google.com/store/apps/details?id=com.PigeonGames.Rizline, and so the package ID is <code>com.PigeonGames.Rizline</code>. | |||
<br><br> | |||
</li> | |||
<li> | |||
The next step is to find the path of the APK files on the mobile device. Note that it is common for one application to have multiple APK files. Usually, there is one <code>base.apk</code> file, that is common for all devices, and several <code>split</code> APK files, that are device specific. For example, if your mobile device has a larger screen, it may download a <code>split</code> apk with extra high-quality assets. | |||
To find the paths to the APK files, you can use the <code>pm path <package_id></code> command. In our case, the command will be: | |||
<pre> | |||
pm path com.PigeonGames.Rizline | |||
</pre> | |||
[[File:Pm path example Screenshot.png|x80px|thumb|center|alt=A screenshot showing two paths to APK files.|''Rizline'' has two APK files - a <code>base.apk</code> file and a <code>split_config.arm64_v8a.apk</code> file.]] | |||
Now we know that the paths to our two APK files are: | |||
* <code>/data/app/~~tMHzIziIkD3B_oH7sbOphw==/com.PigeonGames.Rizline-P6NKIGPvbzqSbdVySK53MQ==/base.apk</code>, and | |||
* <code>/data/app/~~tMHzIziIkD3B_oH7sbOphw==/com.PigeonGames.Rizline-P6NKIGPvbzqSbdVySK53MQ==/split_config.arm64_v8a.apk</code>. We can use that information to download the files from the device to our computer. <br><br> | |||
</li> | |||
<li> | |||
Exit the <code>adb shell</code>: | |||
<pre> | |||
exit | |||
</pre> | |||
</li> | |||
<li> | |||
Create a new directory for our APK files. To do that, you can either create it using a GUI file explorer, or by typing the <code>mkdir</code> command. In my case, the directory name is <code>rizline_mod</code> | |||
<pre> | |||
mkdir rizline_mod | |||
</pre> | |||
</li> | |||
<li> | |||
Navigate to the new directory using the <code>cd</code> command. | |||
<pre> | |||
cd rizline_mod | |||
</pre> | |||
</li> | |||
<li> | |||
Now we can use the <code>adb pull</code> command to copy the files to the computer. | |||
<pre> | |||
adb pull "/data/app/~~tMHzIziIkD3B_oH7sbOphw==/com.PigeonGames.Rizline-P6NKIGPvbzqSbdVySK53MQ==/base.apk" "base.apk" | |||
adb pull "/data/app/~~tMHzIziIkD3B_oH7sbOphw==/com.PigeonGames.Rizline-P6NKIGPvbzqSbdVySK53MQ==/split_config.arm64_v8a.apk" "split_config.arm64_v8a.apk" | |||
</pre> | |||
The <code>adb pull</code> command takes two arguments: the first one is the path on the mobile device, and the second one is the destination path, on your computer. In this case, we just name the resulting files <code>base.apk</code> and <code>split_config.arm64_v8a.apk</code> respectively. | |||
<!--[[File:Adb pull example Screenshot.png|500px|thumb|center|Copying APK files from an Android device to a computer.]]--> | |||
</li> | |||
</ol> | |||
[[File:Adb get apk files full example screenshot.png|1200px|thumb|center|alt=Screenshot of a terminal with all commands used to get APK files from a mobile device.|In summary, here are all of the commands used to copy APK files from a mobile device to a computer]] | |||
== Decompile the APK files using apktool == | |||
[[File:Compressed AndroidManifest.xml screenshot.png|thumb|right|A screenshot of an [[AndroidManifest.xml]] file, when extracted from base.zip -- this doesn't look like an .xml file at all!]] | |||
To modify the files of an APK package, we will first need to extract individual files from the downloaded APK files. | |||
APK files are essentially just ZIP files in disguise. If you change the <code>.apk</code> file extension to <code>.zip</code>, you can open the file in any archiving software, just like a normal ZIP file. However, some files inside the APK file (such as [[AndroidManifest.xml]]) are in a weird, binary format. To read all of the files properly, we will use [https://apktool.org/ Apktool]. | |||
[[File:Uncompressed AndroidManifest.xml screenshot.png|thumb|right|A screenshot of an [[AndroidManifest.xml]] file, when extracted using apktool -- this looks much more familiar!]] | |||
<ol> | |||
<li>Open a terminal in the directory with your copied APK files.</li> | |||
<li> | |||
Type the following commands to decompile the APK files using Apktool: | |||
<pre> | |||
apktool d base.apk | |||
apktool d split_config.arm64_v8a.apk | |||
</pre> | |||
This will create new directories - <code>base</code> and <code>split_config.arm64_v8a</code> with the contents of the APK files. | |||
</li> | |||
</ol> | |||
You can now explore the application files freely using a file manager. | |||
== Modify the application to allow user-installed certificates == | |||
<ol> | |||
<li> | |||
Firstly, we will add a new file to our application. This file will allow the app to trust user-added certificate authorities. Create the file at <code>base/res/xml/network_security_config.xml</code> with the following contents: | |||
<br> | |||
'''<code>base/res/xml/network_security_config.xml</code>''': | |||
<pre><nowiki> | |||
<network-security-config> | |||
<debug-overrides> | |||
<trust-anchors> | |||
<!-- Trust user added CAs while debuggable only --> | |||
<certificates src="user" /> | |||
</trust-anchors> | |||
</debug-overrides> | |||
</network-security-config> | |||
</nowiki></pre> | |||
</li> | |||
<li> | |||
The next few changes we will make will occur in the <code>[[AndroidManifest.xml]]</code> file. Open <code>base/AndroidManifest.xml</code> with a text editor of your choice. | |||
</li> | |||
<li> | |||
Find the <code><nowiki><application></nowiki></code> tag. It is located within the main <code><nowiki><manifest></nowiki></code> tag. We will insert two new attributes into this tag:<br> | |||
<pre> | |||
android:debuggable="true" android:networkSecurityConfig="@xml/network_security_config" | |||
</pre> | |||
This will make the app "debuggable", and it will load the settings from the <code>network_security_config.xml</code> file we created before. | |||
[[File:AndroidManifest.xml adding android-networkSecurityConfig Screenshot.png|900px|thumb|center|alt=Screenshot highlighting where to add the two attributes.|We added two new attributes: <code>android:debuggable="true"</code> and <code>android:networkSecurityConfig="@xml/network_security_config"</code> to the <code><nowiki><application></nowiki></code> tag.]]<br> | |||
</li> | |||
<li> | |||
Find an attribute named <code>package="..."</code> in the top-most <code><nowiki><manifest></nowiki></code> tag, and replace the contents of this attribute with your own app ID. In this example, we will replace <code>com.PigeonGames.Rizline</code> with <code>rgwiki.rizline.example_mod</code>. This change will allow us to have both the original, unmodified version of ''Rizline'' as well as our modified version at the same time. | |||
[[File:AndroidManifest.xml package ID Screenshot.png|700px|thumb|center|alt=Screenshot of the AndroidManifest.xml file with the package attribute highlighted.|We will change the <code>com.PigeonGames.Rizline</code> ID, to our own, made-up one: <code>rgwiki.rizline.example_mod</code>.]]<br> | |||
</li> | |||
<li> | |||
Find other instances of the original package ID and change them to our new package ID as well. In the case of ''Rizline'', the <code>com.PigeonGames.Rizline</code> ID also appears later in the file, as part of another ID: | |||
[[File:AndroidManifest.xml package ID in a provider ID Screenshot.png|900px|thumb|center|alt=Screenshot highlighting the package ID found in a different place in the file|We need to replace this part of an ID with our new ID as well.]] | |||
This varies from application to application. In this case, the app cannot be installed unless this other ID is changed to a new one. Other apps may have more IDs that you have to replace; and in some cases, you don't have to replace every ID with a new one, only some.<br><br> | |||
</li> | |||
<li> | |||
There is one more ID we have to change. Open the <code>split_config.arm64_v8a/AndroidManifest.xml</code> file. This file also has a package ID, and it should match with the package ID from the <code>AndroidManifest.xml</code> in the <code>base</code> directory. | |||
[[File:AndroidManifest.xml split package ID Screenshot.png.png|900px|thumb|center|alt=A screenshot showing a short AndroidManifest.xml file for a split APK|This is the last ID we have to change in ''Rizline''. In other apps, there may be more. Try to search the directory for the original ID and find them all!]]<br> | |||
</li> | |||
<li> | |||
The last change we will make, is a change of the application name, to differentiate between the two applications on the device more easily. Open <code>base/res/values/strings.xml</code> in a text editor. Find an entry that has the attribute: <code>name="app_name"</code>, and modify the value to whatever you want. In this case we will change "Rizline" to "Rizline Modded". | |||
[[File:Values.xml app name Rizline Modded.png|500px|thumb|center]] | |||
</li> | |||
</ol> | |||
We have modified all the files we need. Now we have to build the modified app and install it on our device. | |||
== Build and sign the modified APKs == | |||
Building the app from a directory of files is simple. Unfortunately, creating an APK file is not enough to install it to a device. To actually install the application, we will need to ''sign'' the APK files as well. | |||
<ol> | |||
<li> | |||
To build the APKs from files, we will use [https://apktool.org/ Apktool] again. Open the terminal in the <code>rizline_mod</code> directory and type the following commands: | |||
<pre> | |||
apktool b "base" | |||
apktool b "split_config.arm64_v8a" | |||
</pre> | |||
This will combine all of the files in the <code>base</code> directory into an APK file, and separately, combine all of the files in the <code>split_config.arm64_v8a</code> directory into a second APK file. Those new APK files are stored in <code>base/dist/base.apk</code> and <code>split_config.arm64_v8a/dist/split_config.arm64_v8a.apk</code> respectively. | |||
</li> | |||
<li> | |||
Now we will use <code>zipalign</code> to optimize the APK. | |||
<pre> | |||
zipalign -P 16 -f -v 4 "base/dist/base.apk" "base/dist/base_signed.apk" | |||
zipalign -P 16 -f -v 4 "split_config.arm64_v8a/dist/split_config.arm64_v8a.apk" "split_config.arm64_v8a/dist/split_config.arm64_v8a_signed.apk" | |||
</pre> | |||
This will create new files named <code>base_signed.apk</code> and <code>split_config.arm64_v8a_signed.apk</code> in the same directory as the original files. | |||
</li> | |||
<li> | |||
Before signing the APK, we need to create a keystore. A keystore is a file that stores our key pair used to sign APKs. We only need to create a keystore file once, and then we can use it repeatedly. We will use <code>keytool</code> to create a new keystore. The command below will create a new keystore with the filename <code>keystore.jks</code>, and it will be valid for 99999 days. | |||
<pre> | |||
keytool -genkeypair -keystore "keystore.jks" -keyalg RSA -validity 99999 | |||
</pre> | |||
After entering this comand, you will be asked to set a password. In this guide, we will simply use the word "password" as the password. Don't forget the password you set - you will need it later. | |||
Then, you will be prompted to provide various pieces of information. You can skip all of the prompts by just pressing Enter - apart from the last one, where you have to type <code>yes</code>. | |||
[[File:Keytool create keystore example screenshot.png|800px|thumb|center|alt=Screenshot of a terminal with a basic keytool command.|You can just skip most of the prompts, and type "yes" at the end.]] | |||
</li> | |||
<li> | |||
Now it's time to sign the APK files. Use the commands below and type in the keystore password you set at the previous step to sign the APKs. | |||
<pre> | |||
apksigner sign --ks "keystore.jks" "base/dist/base_signed.apk" | |||
apksigner sign --ks "keystore.jks" "split_config.arm64_v8a/dist/split_config.arm64_v8a_signed.apk" | |||
</pre> | |||
</li> | |||
<li> | |||
We can verify that we've signed the files properly using <code>apksigner verify</code>: | |||
<pre> | |||
apksigner verify "base/dist/base_signed.apk" | |||
apksigner verify "split_config.arm64_v8a/dist/split_config.arm64_v8a_signed.apk" | |||
</pre> | |||
If there is no output, that means that we've done everything correctly! If there are some warnings, chances are you can probably ignore them. In the case of ''Rizline'', there are some warnings, but everything still works. If there are errors, the app will likely not work. | |||
These are the steps that you have to do every time you make a change to the app files. If you want to speed up the process of building in the future, you might want to consider creating a shell script to execute all of these commands for you. | |||
[[File:Apktool building and signing an APK file terminal screenshot.png|900px|thumb|center|alt=A screenshot of commands used to create an APK file and sign it.|All commands used to build and sign an APK file. In this example, we omitted the <code>-v</code> flag in <code>zipalign</code> to hide unnecesary output.]] | |||
</li> | |||
</ol> | |||
== Install the modified APKs to the device == | |||
To install the files to your device, open the terminal and type the following command: | |||
<pre> | |||
adb install-multiple "base/dist/base_signed.apk" "split_config.arm64_v8a/dist/split_config.arm64_v8a_signed.apk" | |||
</pre> | |||
You can now launch the app and observe the HTTPS traffic in ''Charles''! | |||
{{Todo| | |||
* Add download link to adb, zipalign and apksigner}} | |||
[[Category:Guides]] | [[Category:Guides]] |
Latest revision as of 17:19, 29 January 2025
To monitor and view network traffic in an Android application, you can use a proxy server. This guide will help set up your device and view network traffic from a specific Android app.
Prerequisites
[edit | edit source]To follow this guide, you have to have:
- an Android device (you do not need root access),
- a computer (with any operating system),
- a USB cable to connect your mobile device to the computer.
- access to a Wi-Fi network that you can connect to with the computer and the mobile device.
Install a proxy server
[edit | edit source]In this guide, we will use the Charles proxy server. There may be other, better alternatives that I have not tried using. Feel free to edit this guide if you feel like you have a better proxy server.
Note: The free trial version of Charles only allows for 30-minute sessions. After that time passes, you can reopen Charles to continue using it.
- Go to https://www.charlesproxy.com/download/ on your computer, and download the version of Charles for your operating system.
- Launch Charles.
- At the top bar, select the option Help > SSL Proxying > Install Charles Root Certificate on a Mobile Device or Remote Browser.
This will show a message box with your computer's local IP address and a port. In the next step, we will use this information to connect the mobile device to the proxy server.In this example, the IP shown on the pop-up is: 192.168.3.57, and the port is: 8888.
Set up proxy settings on the mobile device
[edit | edit source]
To make network traffic go from the device to your proxy server, you have to set proxy settings on your mobile device.
- On your mobile device, go to Settings > Wi-Fi and select your Wi-Fi network.
- Under Advanced settings, change Proxy to Manual.
- Set the Host Name and Port settings to the IP address and port displayed in the Charles pop-up window in step 1.
- Save the settings.
- If everything was done correctly, a pop-up should appear in Charles, informing of a new connection. Click on "Allow" to allow the proxy connection. If you click "Deny" on accident, you can simply restart Charles and try to connect to the proxy again.
This pop-up window should appear on your computer after saving proxy settings on the mobile device. - After clicking allow, you can see some network traffic going through. You can try opening apps on your phone, and new entries will appear.
Network traffic from your mobile device, shown on your computer.
You can also enable Sequence view by clicking the Sequence tab on the top. This will show all of the network traffic in chronological order, with the most recent requests on the bottom.

Now we have set-up our proxy server. However, even though we can see some host names and parts of requests, we cannot actually see the contents of most of the requests. This is because all modern applications use the HTTPS protocol to communicate; this protocol encrypts the data to prevent man-in-the-middle attacks.
This current setup will still work for HTTP requests. If you try to access a website via HTTP on the mobile device, you will be able to see the contents of the request, as well as the response in Charles. This is because, unlike HTTPS, HTTP is not encrypted, and the proxy server can read requests and responses sent via HTTP. You can try this yourself by opening an HTTP website (such as http://example.com/) in a web browser on your mobile device. You should see something similar to this:
(Note: You may need to scroll down to see the newest requests in Sequence view.)

In the next steps, we will install a custom certificate and modify an application, which will allow us to intercept HTTPS requests as well.
Install a certificate to the mobile device
[edit | edit source]To look inside HTTPS requests, we need to install a certificate to our mobile device.

chls.pro/ssl
, click on the "Download" button to download the certificate.
- On your mobile device, open your browser and type
chls.pro/ssl
into the URL bar, while connected to the proxy. This will allow you to download the certificate for your instance of Charles. Tap on the "Download" button to confirm that you want to download the certificate file.
This URL is also shown in the Help pop-up window in Charles - it's in the same pop-up that we used to get the IP and port for the proxy settings. - Go to Settings and search for options about certificates. On my device, it is under Settings > Password & security > System security > Credential storage. From here, you should be able to view, add, and remove certificates installed on the system.
Here, you can view, install and remove certificates from your device. - Select Install certificates from storage, and then CA certificate.
Choose the "CA certificate" option on this screen. - A pop-up may show up, warning you of the safety concerns related to adding custom certificates. Read it, and if you are sure you want to do this, tap on Install anyway.
Remember! After you are done exploring network traffic from an app, you can remove the certificate by going into this settings menu, selecting Trusted certificates, switching to the User tab, selecting the certificate and tapping on Uninstall. - You may be asked to verify your identity. After confirming your identity, you will be asked to choose a file. Select the file you downloaded before - it should be named
downloadfile.crt
and it should be located in yourDownloads
folder.Choose the downloaded certificate file (usually called downloadfile.crt
) - After selecting the file, the certificate should be installed. You can verify that, by going into the Trusted certificates menu, and selecting the User tab - your certificate should be there. You can tap on it to view detailed information about the certificate or uninstall it if you don't need it anymore.

The certificate should now be installed properly on the mobile device, however we still will not be able to see HTTPS traffic in Charles.
Enable SSL Proxying in Charles
[edit | edit source]To enable SSL proxying in Charles, do the following steps:
- From the menu bar at the top, select Proxy > SSL Proxying Settings....
- Make sure the Enable SSL Proxying checkbox is enabled.
- Below the Include table, click on Add.
- In the pop-up, for the Host field, enter
*
and leave the Port field empty. This will make it so all hosts' HTTPS requests will be captured and attempted to be read by Charles. - Click on OK on the pop-up, and OK on the "SSL Proxying Settings" window.

If you now try to open an application on your mobile device, you will see that it will not be able to connect to the servers. This is because all traffic is now captured by Charles. Most apps do not accept user-installed certificates as valid, which means even though our certificate is installed, the applications are acting as if it is an unknown certificate, and therefore cannot connect to the server at all.

If you want to allow some hostnames to use SSL as normal, you can add them to the Exclude table in the "SSL Proxying Settings" window. This setting makes it so Charles just acts as a pass-through for that specific host, and doesn't attempt to read any data inside of the requests. Alternatively, you can add hosts to the Include table instead of the *
wildcard. This will make it so only the hosts in the Include table are captured by Charles.
Get APK files of the application that we will modify
[edit | edit source]We will modify the application slightly so that it will accept user-installed certificates. In this guide, we will be using Rizline as an example.
Install tools
[edit | edit source]First we will need to download some tools:
- To connect to the device via a USB cable, we will use Android Debug Bridge (adb)
- To decompile and build Android applications, we will use Apktool. To download and install Apktool, follow the instructions on this page: https://apktool.org/docs/install.
- To optimize the built APK, we will use zipalign.
- To sign the modified APK, we will use apksigner.
If everything is installed correctly, you should be able to open a terminal and type adb
, apktool
, zipalign
and apksigner
commands without errors.
Get APK files from the device
[edit | edit source]
adb
installed. If the pop-up doesn't appear, try typing adb
in the terminal, or try using a different USB cable.To modify the application files, we first need to get them onto our computer.
- Enable USB Debugging on your mobile device.
- To do that, go to Settings > Additional settings > Developer options > USB debugging (found in the Debugging section).
- If you cannot find the "Developer options" button, you might need to enable Developer Mode by going into Settings > About device > Version and tapping on the Build number option seven times. You should get a message saying "You are now a developer!"
- If you have any trouble with this, try following the official instructions from developer.android.com.
- Connect your Android device to your computer using a USB cable. Choose "Android Auto" on your device if prompted.
- On your mobile device, a pop-up should appear, asking for permission to allow USB debugging. Tap on allow; and if you plan on doing this often, you might want to tap the checkbox to always allow USB debugging from this computer. If the pop-up doesn't appear immediately, don't worry; it might appear after typing the command in the next step.
- On your computer, open up a terminal and type:
adb shell
You should now have access to your mobile device on your computer via the terminal.
*hacking noises* we're in. -
Now we need to find the package ID of the app that we are interested in. One way of doing that is finding the ID in the list of installed packages. In
adb
, type the following command to show the list of packages installed on the device:pm list packages
On my device, this command shows 443 packages. Here is a few of them. This command will only show the package IDs, so you cannot search by name. If you have a lot of applications installed, you might want to try piping the command to
grep
.grep
is a command line utility that will filter down results by showing only the lines that have a specified string of text inside of them. For example the following command will show applications that contain the word "Pigeon" in their ID:pm list packages | grep Pigeon
This time, only applications made by Pigeon Games will be shown.
Another way of getting the ID of an application, is just searching the app on the Google Play Store website. When you go to an application page on Google Play, the ID of the package will be embedded in the URL. For Rizline, the link is https://play.google.com/store/apps/details?id=com.PigeonGames.Rizline, and so the package ID iscom.PigeonGames.Rizline
.
-
The next step is to find the path of the APK files on the mobile device. Note that it is common for one application to have multiple APK files. Usually, there is one
base.apk
file, that is common for all devices, and severalsplit
APK files, that are device specific. For example, if your mobile device has a larger screen, it may download asplit
apk with extra high-quality assets. To find the paths to the APK files, you can use thepm path <package_id>
command. In our case, the command will be:pm path com.PigeonGames.Rizline
Rizline has two APK files - a base.apk
file and asplit_config.arm64_v8a.apk
file.Now we know that the paths to our two APK files are:
/data/app/~~tMHzIziIkD3B_oH7sbOphw==/com.PigeonGames.Rizline-P6NKIGPvbzqSbdVySK53MQ==/base.apk
, and/data/app/~~tMHzIziIkD3B_oH7sbOphw==/com.PigeonGames.Rizline-P6NKIGPvbzqSbdVySK53MQ==/split_config.arm64_v8a.apk
. We can use that information to download the files from the device to our computer.
-
Exit the
adb shell
:exit
-
Create a new directory for our APK files. To do that, you can either create it using a GUI file explorer, or by typing the
mkdir
command. In my case, the directory name isrizline_mod
mkdir rizline_mod
-
Navigate to the new directory using the
cd
command.cd rizline_mod
-
Now we can use the
adb pull
command to copy the files to the computer.adb pull "/data/app/~~tMHzIziIkD3B_oH7sbOphw==/com.PigeonGames.Rizline-P6NKIGPvbzqSbdVySK53MQ==/base.apk" "base.apk" adb pull "/data/app/~~tMHzIziIkD3B_oH7sbOphw==/com.PigeonGames.Rizline-P6NKIGPvbzqSbdVySK53MQ==/split_config.arm64_v8a.apk" "split_config.arm64_v8a.apk"
The
adb pull
command takes two arguments: the first one is the path on the mobile device, and the second one is the destination path, on your computer. In this case, we just name the resulting filesbase.apk
andsplit_config.arm64_v8a.apk
respectively.

Decompile the APK files using apktool
[edit | edit source]
To modify the files of an APK package, we will first need to extract individual files from the downloaded APK files.
APK files are essentially just ZIP files in disguise. If you change the .apk
file extension to .zip
, you can open the file in any archiving software, just like a normal ZIP file. However, some files inside the APK file (such as AndroidManifest.xml) are in a weird, binary format. To read all of the files properly, we will use Apktool.

- Open a terminal in the directory with your copied APK files.
-
Type the following commands to decompile the APK files using Apktool:
apktool d base.apk apktool d split_config.arm64_v8a.apk
This will create new directories -
base
andsplit_config.arm64_v8a
with the contents of the APK files.
You can now explore the application files freely using a file manager.
Modify the application to allow user-installed certificates
[edit | edit source]-
Firstly, we will add a new file to our application. This file will allow the app to trust user-added certificate authorities. Create the file at
base/res/xml/network_security_config.xml
with the following contents:
base/res/xml/network_security_config.xml
:<network-security-config> <debug-overrides> <trust-anchors> <!-- Trust user added CAs while debuggable only --> <certificates src="user" /> </trust-anchors> </debug-overrides> </network-security-config>
-
The next few changes we will make will occur in the
AndroidManifest.xml
file. Openbase/AndroidManifest.xml
with a text editor of your choice. -
Find the
<application>
tag. It is located within the main<manifest>
tag. We will insert two new attributes into this tag:
android:debuggable="true" android:networkSecurityConfig="@xml/network_security_config"
This will make the app "debuggable", and it will load the settings from the
network_security_config.xml
file we created before.We added two new attributes: android:debuggable="true"
andandroid:networkSecurityConfig="@xml/network_security_config"
to the<application>
tag.
-
Find an attribute named
package="..."
in the top-most<manifest>
tag, and replace the contents of this attribute with your own app ID. In this example, we will replacecom.PigeonGames.Rizline
withrgwiki.rizline.example_mod
. This change will allow us to have both the original, unmodified version of Rizline as well as our modified version at the same time.We will change the com.PigeonGames.Rizline
ID, to our own, made-up one:rgwiki.rizline.example_mod
.
-
Find other instances of the original package ID and change them to our new package ID as well. In the case of Rizline, the
com.PigeonGames.Rizline
ID also appears later in the file, as part of another ID:We need to replace this part of an ID with our new ID as well. This varies from application to application. In this case, the app cannot be installed unless this other ID is changed to a new one. Other apps may have more IDs that you have to replace; and in some cases, you don't have to replace every ID with a new one, only some.
-
There is one more ID we have to change. Open the
split_config.arm64_v8a/AndroidManifest.xml
file. This file also has a package ID, and it should match with the package ID from theAndroidManifest.xml
in thebase
directory.This is the last ID we have to change in Rizline. In other apps, there may be more. Try to search the directory for the original ID and find them all!
-
The last change we will make, is a change of the application name, to differentiate between the two applications on the device more easily. Open
base/res/values/strings.xml
in a text editor. Find an entry that has the attribute:name="app_name"
, and modify the value to whatever you want. In this case we will change "Rizline" to "Rizline Modded".
We have modified all the files we need. Now we have to build the modified app and install it on our device.
Build and sign the modified APKs
[edit | edit source]Building the app from a directory of files is simple. Unfortunately, creating an APK file is not enough to install it to a device. To actually install the application, we will need to sign the APK files as well.
-
To build the APKs from files, we will use Apktool again. Open the terminal in the
rizline_mod
directory and type the following commands:apktool b "base" apktool b "split_config.arm64_v8a"
This will combine all of the files in the
base
directory into an APK file, and separately, combine all of the files in thesplit_config.arm64_v8a
directory into a second APK file. Those new APK files are stored inbase/dist/base.apk
andsplit_config.arm64_v8a/dist/split_config.arm64_v8a.apk
respectively. -
Now we will use
zipalign
to optimize the APK.zipalign -P 16 -f -v 4 "base/dist/base.apk" "base/dist/base_signed.apk" zipalign -P 16 -f -v 4 "split_config.arm64_v8a/dist/split_config.arm64_v8a.apk" "split_config.arm64_v8a/dist/split_config.arm64_v8a_signed.apk"
This will create new files named
base_signed.apk
andsplit_config.arm64_v8a_signed.apk
in the same directory as the original files. -
Before signing the APK, we need to create a keystore. A keystore is a file that stores our key pair used to sign APKs. We only need to create a keystore file once, and then we can use it repeatedly. We will use
keytool
to create a new keystore. The command below will create a new keystore with the filenamekeystore.jks
, and it will be valid for 99999 days.keytool -genkeypair -keystore "keystore.jks" -keyalg RSA -validity 99999
After entering this comand, you will be asked to set a password. In this guide, we will simply use the word "password" as the password. Don't forget the password you set - you will need it later.
Then, you will be prompted to provide various pieces of information. You can skip all of the prompts by just pressing Enter - apart from the last one, where you have to type
yes
.You can just skip most of the prompts, and type "yes" at the end. -
Now it's time to sign the APK files. Use the commands below and type in the keystore password you set at the previous step to sign the APKs.
apksigner sign --ks "keystore.jks" "base/dist/base_signed.apk" apksigner sign --ks "keystore.jks" "split_config.arm64_v8a/dist/split_config.arm64_v8a_signed.apk"
-
We can verify that we've signed the files properly using
apksigner verify
:apksigner verify "base/dist/base_signed.apk" apksigner verify "split_config.arm64_v8a/dist/split_config.arm64_v8a_signed.apk"
If there is no output, that means that we've done everything correctly! If there are some warnings, chances are you can probably ignore them. In the case of Rizline, there are some warnings, but everything still works. If there are errors, the app will likely not work.
These are the steps that you have to do every time you make a change to the app files. If you want to speed up the process of building in the future, you might want to consider creating a shell script to execute all of these commands for you.
All commands used to build and sign an APK file. In this example, we omitted the -v
flag inzipalign
to hide unnecesary output.
Install the modified APKs to the device
[edit | edit source]To install the files to your device, open the terminal and type the following command:
adb install-multiple "base/dist/base_signed.apk" "split_config.arm64_v8a/dist/split_config.arm64_v8a_signed.apk"
You can now launch the app and observe the HTTPS traffic in Charles!
This page has some work to do. Help the wiki by editing this page!
- Add download link to adb, zipalign and apksigner