shell

Since I have analyzed the APP in advance and added shell, it should be peeled first.

Run the adb shell dumpsys activity activities | grep mResumedActivity for current an activity

Then use FRIDADEX_DUMP to unshell and filter, grep -ril “PassWordLoginActivity” to get the dex file we want

caught

The following uses the login page as an example to analyze packet capture

Run python r0capture. Py -u com.caratlover-p kllr.pcap to save the file to pcap and open it for analysis with Wireshark. You can see that the body of post is encrypted

Analysis of the

Open it with JADX and follow the headers field to see if anything is found.

If you search for gPS_city, there is only one result. If you follow up, there is only one result

Go straight to the back and see what this method does, follow up with method C, okay

C method and call b method, obviously AES encryption, that f87210E0ED3079D8 is the key

\

Here we have to prove our guess is correct, hook into our object files

Using the objection

Hook the c method just now, and you can see that the parameters are the mobile phone number and password filled in, so it really goes through this method. By comparing the package caught just now, it can be found that the encrypted package is body

\

Restore the body

Go back and analyze method B, analyze how it is encrypted

In order to prove the analysis right, can be in chinabaiker.com/cyberchef.h… Compare operations. You can see that it’s the same thing, the body part is solved, so let’s analyze the headers field.

\

Analysis of the headers

The code is confused, and you can assume that method a is something like addheader. What are we adding to A from the top down

As you can see, we added these fields to the header first. Just like the requested fields, the values of the following fields can be fixed.

The remaining fields can be analyzed based on the code, or the approximate meaning can be guessed based on their fields

To prove the conjecture, it is decoded base64

I’m just going to show you one, all the others are the same

Simulation of the request

Now that you’re done with body and headers, try the mock request

import base64 from Crypto.Cipher 
import AES import requests x
import time 

Use AES symmetric encryption algorithm. 
# STR is not a multiple of 32, so it is a multiple of 16
def add_to_32(value) : 
    while len(value) % 32! =0: 
        value += '\ 0' 
    return str.encode(value) # returns bytes
    
def add_to_16(value) : 
    while len(value) % 16! =0: 
        value += '\ 0' 
    return str.encode(value) # returns bytes

# encryption method
def encrypt_oracle(text) : 
    # the secret key
    key = 'f87210e0ed3079d8' 
    Text to be encrypted
    Initialize the encryptor
    aes = AES.new(add_to_16(key), AES.MODE_ECB) 
    Use AES encryption first
    encrypt_aes = aes.encrypt(add_to_16(text))
    Convert base64 to a string
    encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8') Perform encryption and transcode to return bytes
    # print(encrypted_text) 
    return encrypted_text 
    
# decryption method
def decrypt_oralce(text) : 
    # the secret key
    key = 'f87210e0ed3079d8' 
    # cipher
    Initialize the encryptor
    aes = AES.new(add_to_16(key), AES.MODE_ECB) 
    Decrypt base64 into bytes first
    base64_decrypted = base64.decodebytes(text.encode(encoding='utf-8')) 
    # Perform decryption and transcode to return STR
    decrypted_text = str(aes.decrypt(base64_decrypted),encoding='utf-8').replace('\ 0'.' ') 
    # print('decrypted_text',decrypted_text) 
    return decrypted_text 
    
if __name__ == '__main__': 
    text = '{"verifyValue":"123456","openInvite":"","phoneNumber":"12345678910","verifyMode":"2","openChannel":""}' 
    entrypted_text = encrypt_oracle(text) 
    url = "http://uc.pairui1.com:8668/auth/login" 
    headers = { 
        "device_system": "8.1.0"."device_name": "aos"."device_model": "Nexus 6P"."device_brand": "google"."package_name": "com.caratlover"."imei": "867686020207104"."api_version": "4600"."client_version": "4600"."post_time": str(int(time.time())), 
        "app_market": "uc"."oaid": ""."mac": 
        "A0:8D:16:F3:87:76"."gps": ""."gps_city": ""."gps_province": ""."area": ""."township": ""."number": ""."Content-Type": "text/plain; charset=utf-8"."Host": "uc.pairui1.com:8668"."Connection": "Keep-Alive"."Accept-Encoding": "gzip"."User-Agent": "Okhttp / 3.12.0", 
    } 
    response = requests.post(url, data=entrypted_text, headers=headers) 
    # print(response.status_code) 
    # print(response.text) 
    print(decrypt_oralce(response.text))
Copy the code

You can see that the request was sent successfully, and you can test it if you have registered an account.