Capturing https package of Flutter app for iOS

Jollier

Professional
Messages
1,128
Reputation
6
Reaction score
1,092
Points
113
# 0x1 Prepare tool: rvictl, Wireshark, Charles

# 0x2 1. After connecting the USB mobile phone to the Mac, use the rvictl -s (mobile UDID) command to open the rvi virtual network interface.

0328af2d-cd7c-47c6-9449-a944751f4a3b.png


2. MacOS uses a Wi-Fi network. Once the mobile phone is connected to the public Wi-Fi, access any interface of the Wireshark app to start capturing packets. This step is used to get the API domain name of the application.
7cbf2771-0386-469b-90d3-f11e8c176592.png


3. After obtaining the domain name, change the hosts of the mobile phone and resolve the domain name as macOS.
b4eac87b-207d-4c8f-b0cf-bf23e27a5398.png


4. Launch Charles on macOS, open Proxy-> Reverse Proxy Settings, open Reverse Proxy Settings and add the domain name that Wireshark intercepted before adding.
dba3f135-b085-44ad-b9ae-a05f596d8d46.png


5. Gladly start grabbing!
23897ac9-948a-4278-bf13-536bbde0fcae.png

# 0x3 frida script (no need to manually change hosts)

Code:
/*
*
* @creantan
*
* Example usage:
* # frida -U -f com.xxx.yyy -l flutter_connect_.js --no-pause
*
*/
var sIP = 'xxx.xxx.xxx.xxx' // recipient IP address
var xIP = '192.168.2.1' // IP address of the proxy computer

// IP String to int

function ipToInt(ip) {
var result = ip.split('.');
return (parseInt(result[3]) << 24 |
parseInt(result[2]) << 16 |
parseInt(result[1]) << 8 |
parseInt(result[0]));
}

//int в строку IP
function parseIp(number) {
var ip = ''
if (number <= 0) {
return ip
}
const ip3 = (number << 0) >>> 24
const ip2 = (number << 8) >>> 24
const ip1 = (number << 16) >>> 24
const ip0 = (number << 24) >>> 24
ip += ip0 + '.' + ip1 + '.' + ip2 + '.' + ip3
return ip
}

function parsePort(number) {
return ((number & 0xFF) << 8) | ((number & 0xFF00) >> 8);
}

Interceptor.attach(Module.findExportByName(null, "connect"), {
onEnter: function(args) {
var fd = args[0].toInt32()
if (Socket.type(fd) !== 'tcp')
            return;

        var ipAddr = args[1].add(4)
var ip = parseIp(Memory.readU32(ipAddr))
var portAddr = args[1].add(2)
        var port = parsePort(Memory.readUShort(portAddr));

// Determine If This Is The Target Address
if (ip === sIP) {
             console.log ("[+] connect:" + ip + ':' + port);

             // Replace the IP address with the proxy host
             Memory.writeU32 (ipAddr, ipToInt (xIP))
             // Print address after replacement

console.log(hexdump(ptr(args[1]), {
length: 32,
header: true,
ansi: true
}))
}
}
})
 
Top