Truncate reverse engineering post, move some stuff for part two
[web-hugo.git] / content / posts / reverse-engineering-mobile-apps-part-two.md
1 ---
2 title: "Reverse Engineering Mobile Apps Part Two"
3 date: 2024-05-15T23:21:00+03:00
4 description: ""
5 tags: []
6 type: blog
7 draft: true
8 ---
9
10 ## Note to the git snooper - I moved these here due to revalations made later, I will deep-dive these topics at a later date.
11
12 ## The smoke-test
13
14 So we have a potential API endpoint, let's put it to the test. We're not going to recompile anything yet or do any byte-patching,
15 let's try a quick smoke-test.
16
17 **UPDATE 15/05/2024: It turns out this old app version uses HTTP only, instead of HTTPS. You will only need to perform the AdAway instruction here.
18 As this information is still vastly useful for reverse engineering most apps, I will be leaving this section intact.**
19
20 Ensure your phone is rooted and you have a variant of Xposed Framework installed (I used LSPosed).
21 We will need to unarm the SSL pinning present in most apps, including this one, I used [io.github.tehcneko.sslunpinning](https://github.com/Xposed-Modules-Repo/io.github.tehcneko.sslunpinning) module.
22 (NOTE: Users without root might want to skip to end of article where I showcase unpinning the app manually)
23
24 Next, install [AdAway app from F-Droid](https://f-droid.org/packages/org.adaway/) so we can setup a redirection on any network we are on.
25 Inside AdAway, add a redirection rule for the address we just found and point it to an IP address in your LAN that will run the API server.
26
27 Generate a self-signed certificate authority and a certificate signed by it and run a webserver with both HTTP and HTTPS on the API server machine.
28 ```
29 # Create an ext file containing the Subject Alternative Name (SAN)
30 # DNS.1 should correspond to the API endpoint of the app.
31 # NOTE! If you are changing the API endpoint to a public domain, you can just use a public cert, no need for any of this.
32 cat > auxbrain.ext << EOF
33 authorityKeyIdentifier=keyid,issuer
34 basicConstraints=CA:FALSE
35 keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
36 subjectAltName = @alt_names
37
38 [alt_names]
39 DNS.1 = www.auxbrain.com
40 EOF
41
42 # Create your own Certificate Authority
43 openssl genrsa -des3 -out myCA.key 2048
44 openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem
45 # Create a CSR and lets have the new CA sign it
46 openssl genrsa -out auxbrain.key 2048
47 openssl req -new -key auxbrain.key -out auxbrain.csr -nodes
48 openssl x509 -req -in auxbrain.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out auxbrain.crt -days 825 -sha256 -extfile auxbrain.ext
49 cat auxbrain.crt myCA.pem > auxbrain.pem
50 # You now have:
51 # myCA.pem - the public certificate of your root CA
52 # auxbrain.key - the private key for your webserver
53 # auxbrain.pem - the public cert for your webserver.
54 ```
55
56 Use the generated `auxbrain.pem` and `auxbrain.key` files for your webserver SSL/TLS configuration. For nginx, append following values to your server directive:
57 ```
58 listen 443 ssl;
59 ssl_certificate /path/to/auxbrain.pem;
60 ssl_certificate_key /path/to/auxbrain.key;
61 ssl_session_cache shared:SSL:1m;
62 ssl_session_timeout 5m;
63 ssl_ciphers HIGH:!aNULL:!MD5;
64 ssl_prefer_server_ciphers on;
65 ```
66
67 Import the self-signed CA (myCA.pem) to your phone's truststore (Check under your phone's Security/Encryption settings). Once all of that is done, run the app for first time.
68
69
70 ## Rootless SSL Unpinning + Endpoint URL patching
71 Let's make the app not require a VPN or root privileges - let's make user CAs work and the endpoint URL something we control on the public net.
72 Start off by pulling the following repository
73 ```
74 git clone https://github.com/ilya-kozyr/android-ssl-pinning-bypass.git
75 python3 -m venv .venv
76 source .venv/bin/activate
77 pip install -r requirements.txt
78 cp /path/to/your/apk .
79 python3 apk-rebuild.py egginc.apk --pause
80 ```
81
82 **NOTE!** IF you do not intend to patch the API endpoint and just want to proceed with AdAway redirecting traffic, you can stop here and press ENTER!
83 Proceed only if you own a domain in your control (that is equal or less in length to www.auxbrain.com) and want to use the app without a VPN/redirection.
84
85 Open a new terminal window, the script will wait for us to perform modifications, enter the created folder `egginc.apk-decompiled` and `lib`.
86
87 We have two folders here now, `arm64-v8a` and `armeabi-v7a`, just as we saw when we pulled the .so file out of the apk earlier. Let's tackle
88 the 64-bit build first.
89
90 For arm64 build it was really simple to perform bytepatch on the said endpoint. We already know it's supposed to look as `G?www.auxbrain.com` - let's probe the .so library a bit.
91 ```
92 $> hexdump -C libegginc.so | grep "ww.auxbrain.co" -A2 -B2
93 00b02b40 cd cc 4c 3f 00 00 00 00 00 00 00 00 00 00 80 3f |..L?...........?|
94 00b02b50 00 00 00 00 00 00 00 00 00 00 00 00 14 ae 47 3f |..............G?|
95 00b02b60 77 77 77 2e 61 75 78 62 72 61 69 6e 2e 63 6f 6d |www.auxbrain.com|
96 00b02b70 00 48 54 54 50 20 52 45 51 3a 20 25 64 00 64 61 |.HTTP REQ: %d.da|
97 00b02b80 74 61 3d 00 65 69 2f 66 69 72 73 74 5f 63 6f 6e |ta=.ei/first_con
98 ```
99
100 We seem to have nothing blocking our way, let's create hex representations of `G?www.auxbrain.com` and a target domain of equal length, for example `G?eggs.based.quest`.
101
102 (Note: You can choose a shorter name as well, if you null-terminate the extra bytes as padding)
103 ```
104 $> echo "G?www.auxbrain.com" | hexdump -ve '1/1 "%.2X"'
105 473F7777772E617578627261696E2E636F6D0A
106 $> echo "G?eggs.based.quest" | hexdump -ve '1/1 "%.2X"'
107 473F656767732E62617365642E71756573740A
108 ```
109
110 Remove the trailing `0A` from end of both hex strings and now proceed as follows:
111 ```
112 # Place the source in first bracket of sed and the new URL at second bracket.
113 hexdump -ve '1/1 "%.2X"' libegginc.so | sed "s/473F7777772E617578627261696E2E636F6D/473F656767732E62617365642E7175657374/g" | xxd -r -p > patched.so
114 ```
115
116 Huzzah! We now have a patched linked-library for the arm64 build. Let's also patch the 32-bit version.
117 ```
118 $> hexdump -C libegginc.so | grep "ww.auxbrain.co" -A2 -B2
119 0087b770 69 67 68 5f 74 6f 6f 5f 6d 61 6e 79 5f 70 78 00 |igh_too_many_px.|
120 0087b780 74 61 62 6c 65 74 5f 68 64 70 69 00 00 00 00 00 |tablet_hdpi.....|
121 0087b790 77 77 77 2e 61 75 78 62 72 61 69 6e 2e 63 6f 6d |www.auxbrain.com|
122 0087b7a0 00 00 00 00 00 00 00 00 65 69 2f 66 69 72 73 74 |........ei/first|
123 0087b7b0 5f 63 6f 6e 74 61 63 74 00 00 00 00 00 00 00 00 |_contact........|
124 ```
125 This one lacks the `G?` prefix on API endpoint, but we still have null terminators we can rely on. Let's replace the `473F` from our previous strings with `0000`.
126 ```
127 # Place the source in first bracket of sed and the new URL at second bracket.
128 hexdump -ve '1/1 "%.2X"' libegginc.so | sed "s/00007777772E617578627261696E2E636F6D/0000656767732E62617365642E7175657374/g" | xxd -r -p > patched.so
129 ```
130
131 Replace both of the libegginc.so files with the patched.so files. Move back to main terminal window and press ENTER.
132
133 We now have a patched and debug signed apk for the game that isn't SSL pinned and contains a custom API endpoint we control without a VPN.
134