# 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.
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.
3. After obtaining the domain name, change the hosts of the mobile phone and resolve the domain name as macOS.
4. Launch Charles on macOS, open Proxy-> Reverse Proxy Settings, open Reverse Proxy Settings and add the domain name that Wireshark intercepted before adding.
5. Gladly start grabbing!
# 0x3 frida script (no need to manually change hosts)
# 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.
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.
3. After obtaining the domain name, change the hosts of the mobile phone and resolve the domain name as macOS.
4. Launch Charles on macOS, open Proxy-> Reverse Proxy Settings, open Reverse Proxy Settings and add the domain name that Wireshark intercepted before adding.
5. Gladly start grabbing!
# 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
}))
}
}
})