Manuall frida

This commit is contained in:
Andrii Dokhniak 2025-08-14 18:04:12 +02:00
parent 178c65be34
commit 2a836ea6cb
13 changed files with 212 additions and 39 deletions

View File

@ -21,24 +21,45 @@ async function spawnPromise(program, args) {
let io = new Server(); let io = new Server();
async function send_private_data() { async function send_private_data() {
let adid = await spawnPromise("bash", ["/conf/get_adid.sh"]) let adid = await spawnPromise("bash", ["/conf/get_adid.sh"]);
adid = adid.output; adid = adid.output;
let gps_coords = await spawnPromise("bash", ["/conf/get_location.sh"]) let gps_coords = await spawnPromise("bash", ["/conf/get_location.sh"]);
gps_coords = gps_coords.output; gps_coords = gps_coords.output;
gps_coords = gps_coords.trim().split(','); gps_coords = gps_coords.trim().split(",");
io.emit("private_info", {adid, latitude: gps_coords[0], longitude: gps_coords[1]}) io.emit("private_info", {
adid,
latitude: gps_coords[0],
longitude: gps_coords[1],
});
} }
async function send_open_ports() { async function send_open_ports() {
let ports = new Set((await spawnPromise("bash", ["/conf/get_ports.sh"])).output.trim().split(' ')); let ports = new Set(
(await spawnPromise("bash", ["/conf/get_ports.sh"])).output
.trim()
.split(" ")
);
let start_ports = fs.readFileSync("/ports").toString().trim().split(' '); let start_ports = fs.readFileSync("/ports").toString().trim().split(" ");
for (let port of start_ports) { for (let port of start_ports) {
ports.delete(port); ports.delete(port);
} }
io.emit("open_ports", [...ports]); io.emit("open_ports", [...ports]);
} }
async function send_installed_apps() {
let out = await spawnPromise("bash", ["/conf/get_installed_apps.sh"]);
if (out.code != 0) {
send_notification(
io,
false,
"Listing installed apps with frida",
out.output
);
}
io.emit("installed_apps", JSON.parse(out.output));
}
function send_notification(socket, is_ok, context, message) { function send_notification(socket, is_ok, context, message) {
socket.emit("notification", { socket.emit("notification", {
is_ok, is_ok,
@ -55,14 +76,18 @@ io.on("connection", (socket) => {
console.log("server got: ", ev, ...args); console.log("server got: ", ev, ...args);
}); });
socket.on("screenshot", async () => { socket.on("screenshot", async () => {
if (screenshot_in_flight) if (screenshot_in_flight) return;
return;
screenshot_in_flight = true; screenshot_in_flight = true;
let screen; let screen;
try { try {
screen = await fetch("http://localhost:9987/v2/uiDevice/screenshot"); screen = await fetch(
"http://localhost:9987/v2/uiDevice/screenshot"
);
} catch (err) { } catch (err) {
console.error("Failed to get the screenshot from culebra, the emulator probably died", err); console.error(
"Failed to get the screenshot from culebra, the emulator probably died",
err
);
screenshot_in_flight = false; screenshot_in_flight = false;
return; return;
} }
@ -73,20 +98,39 @@ io.on("connection", (socket) => {
socket.on("private_info_req", async () => { socket.on("private_info_req", async () => {
await send_private_data(); await send_private_data();
}) });
socket.on("open_ports_req", async () => { socket.on("open_ports_req", async () => {
await send_open_ports(); await send_open_ports();
}) });
socket.on("installed_apps_req", async () => {
await send_installed_apps();
});
socket.on("start_frida_app", async (app_id) => {
await spawnPromise("bash", ["/conf/start_frida_app.sh", app_id]);
send_notification(
socket,
true,
"Frida intercepting stopped",
"the traffic of " + app_id + " is no longer being intercepted"
);
});
socket.on("reset_adid", async () => { socket.on("reset_adid", async () => {
await spawnPromise("bash", ["/conf/reset_adid.sh"]); await spawnPromise("bash", ["/conf/reset_adid.sh"]);
await send_private_data(); await send_private_data();
}) });
socket.on("back", async () => { socket.on("back", async () => {
if (gps_setting_in_progress) { if (gps_setting_in_progress) {
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", ""); send_notification(
socket,
false,
"Interactions not allowed when setting gps coordinates",
""
);
return; return;
} }
await spawnPromise("bash", ["/conf/back.sh"]); await spawnPromise("bash", ["/conf/back.sh"]);
@ -94,7 +138,12 @@ io.on("connection", (socket) => {
socket.on("recent", async () => { socket.on("recent", async () => {
if (gps_setting_in_progress) { if (gps_setting_in_progress) {
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", ""); send_notification(
socket,
false,
"Interactions not allowed when setting gps coordinates",
""
);
return; return;
} }
await spawnPromise("bash", ["/conf/recent.sh"]); await spawnPromise("bash", ["/conf/recent.sh"]);
@ -102,7 +151,12 @@ io.on("connection", (socket) => {
socket.on("home", async () => { socket.on("home", async () => {
if (gps_setting_in_progress) { if (gps_setting_in_progress) {
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", ""); send_notification(
socket,
false,
"Interactions not allowed when setting gps coordinates",
""
);
return; return;
} }
await spawnPromise("bash", ["/conf/home.sh"]); await spawnPromise("bash", ["/conf/home.sh"]);
@ -121,21 +175,31 @@ io.on("connection", (socket) => {
// drag handles both drag and click // drag handles both drag and click
socket.on("motionevent", async (data) => { socket.on("motionevent", async (data) => {
if (gps_setting_in_progress) { if (gps_setting_in_progress) {
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", ""); send_notification(
socket,
false,
"Interactions not allowed when setting gps coordinates",
""
);
return; return;
} }
await spawnPromise("bash", [ await spawnPromise("bash", [
"/conf/motionevent.sh", "/conf/motionevent.sh",
data.motionType, data.motionType,
data.x + "", data.x + "",
data.y + "" data.y + "",
]); ]);
}); });
// drag handles both drag and click // drag handles both drag and click
socket.on("drag", async (data) => { socket.on("drag", async (data) => {
if (gps_setting_in_progress) { if (gps_setting_in_progress) {
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", ""); send_notification(
socket,
false,
"Interactions not allowed when setting gps coordinates",
""
);
return; return;
} }
await spawnPromise("bash", [ await spawnPromise("bash", [
@ -150,18 +214,25 @@ io.on("connection", (socket) => {
socket.on("key", async (data) => { socket.on("key", async (data) => {
if (gps_setting_in_progress) { if (gps_setting_in_progress) {
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", ""); send_notification(
socket,
false,
"Interactions not allowed when setting gps coordinates",
""
);
return; return;
} }
await spawnPromise("bash", [ await spawnPromise("bash", ["/conf/press_key.sh", data.key]);
"/conf/press_key.sh",
data.key
]);
}); });
socket.on("setcoord", async (data) => { socket.on("setcoord", async (data) => {
if (gps_setting_in_progress) { if (gps_setting_in_progress) {
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", ""); send_notification(
socket,
false,
"Interactions not allowed when setting gps coordinates",
""
);
return; return;
} }
gps_setting_in_progress = true; gps_setting_in_progress = true;

View File

@ -1,6 +1,10 @@
bash /conf/start_culebra.sh & bash /conf/start_culebra.sh &
npm i -C /code npm i -C /code
bash /conf/wait_for_sd.sh bash /conf/wait_for_sd.sh
node /code/index.mjs
#tail -f /dev/null adb shell su root /tmp/frida-server &
cd /frida-scripts && perl -i -0777p -e 's|CERT_PEM = .*?;|CERT_PEM = `'"$(cat /certificates/ca.pem | sed -z 's/\n/\\n/g')"'`;|gsm' config.js
adb reverse tcp:8000 tcp:8000
node /code/index.mjs

View File

@ -0,0 +1,2 @@
set -e
frida-ps -Uai --json

View File

@ -1,4 +1,4 @@
out=$(adb shell su root "ss -tunlp | tail -n+2 | awk -F \" \" '{print \$5}' | awk -F ':' '{print \$NF}' | sort -n | uniq") out=$(adb shell su root "ss -tunlp | tail -n+2 | grep -v users:\(\(\\\"frida-server | awk -F \" \" '{print \$5}' | awk -F ':' '{print \$NF}' | sort -n | uniq")
if [ ! -f /ports ]; then if [ ! -f /ports ]; then
echo -n $out > /ports echo -n $out > /ports

View File

@ -0,0 +1,15 @@
set -e
cd /frida-scripts
frida -U \
-l ./config.js \
-l ./native-connect-hook.js \
-l ./native-tls-hook.js \
-l ./android/android-proxy-override.js \
-l ./android/android-system-certificate-injection.js \
-l ./android/android-certificate-unpinning.js \
-l ./android/android-certificate-unpinning-fallback.js \
-l ./android/android-disable-root-detection.js \
-l ./android/android-disable-flutter-certificate-pinning.js \
-f $1

BIN
http_server/code/a.out Executable file

Binary file not shown.

View File

@ -129,6 +129,14 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<h2>Lanuch app</h2>
<form id="launch_app_form">
<select name="appid" id="app_id_select">
</select>
<button type="submit">Launch app</button>
</form>
<h2>Open ports</h2> <h2>Open ports</h2>
<p id="open-ports"></p> <p id="open-ports"></p>
</div> </div>

View File

@ -14,6 +14,8 @@ import {
lon_priv_info_table, lon_priv_info_table,
recentButton, recentButton,
open_ports, open_ports,
app_id_select,
launch_app_form,
} from "./shared"; } from "./shared";
import { start_notifications } from "./notifications"; import { start_notifications } from "./notifications";
@ -122,6 +124,50 @@ socket.on("open_ports", (data: string[]) => {
open_ports.textContent = data.toString(); open_ports.textContent = data.toString();
}); });
async function installed_apps_loop() {
var before;
while (true) {
before = performance.now();
socket.emit("installed_apps_req");
while (performance.now() - before < 2000) await sleep(100);
}
}
socket.on("installed_apps", (data) => {
let all_ids = new Set();
let all_inserted_ids = new Set();
for (let app of data) {
all_ids.add(app.identifier);
}
// remove all the elements that are no longer in the set
for (const el of app_id_select.children) {
const opt = el as HTMLOptionElement;
if (!all_ids.has(opt.value)) opt.remove();
else all_inserted_ids.add(opt.value);
}
for (let app of data) {
if (all_inserted_ids.has(app.identifier))
continue;
let app_opt = document.createElement("option");
app_opt.value = app.identifier;
app_opt.innerText = app.name;
app_id_select.appendChild(app_opt);
}
});
(launch_app_form as HTMLFormElement).addEventListener("submit", (event) => {
event.preventDefault();
event.stopImmediatePropagation();
const form_data = new FormData(event.target as HTMLFormElement);
socket.emit("start_frida_app", form_data.get("appid"));
})
socket.emit("private_info_req"); socket.emit("private_info_req");
socket.onAny((ev, ...args) => { socket.onAny((ev, ...args) => {
@ -244,6 +290,7 @@ async function open_ports_loop() {
} }
} }
installed_apps_loop();
open_ports_loop(); open_ports_loop();
screenshot_loop(); screenshot_loop();
start_notifications(); start_notifications();

View File

@ -13,4 +13,8 @@ export const lat_priv_info_table = document.getElementById("lat_priv_info_table"
export const lon_priv_info_table = document.getElementById("lon_priv_info_table")!; export const lon_priv_info_table = document.getElementById("lon_priv_info_table")!;
export const open_ports = document.getElementById("open-ports")!; export const open_ports = document.getElementById("open-ports")!;
export const app_id_select = document.getElementById("app_id_select")!;
export const launch_app_form = document.getElementById("launch_app_form")!;
export const socket = io(); export const socket = io();

6
http_server/code/test.c Normal file
View File

@ -0,0 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
int main () {
printf("%p", realloc(0, 10));
}

View File

@ -4,6 +4,7 @@ ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/andro
RUN sdkmanager --channel=2 "system-images;android-35;google_apis;x86_64" \ RUN sdkmanager --channel=2 "system-images;android-35;google_apis;x86_64" \
&& echo no | avdmanager create avd -n virtual_dev -b google_apis/x86_64 -k "system-images;android-35;google_apis;x86_64" \ && echo no | avdmanager create avd -n virtual_dev -b google_apis/x86_64 -k "system-images;android-35;google_apis;x86_64" \
&& apt-get update && apt-get install -y iproute2 iputils-ping npm git libxml2-utils telnet bc && apt-get update && apt-get install -y iproute2 iputils-ping npm git libxml2-utils telnet bc aapt python3 python3-pip \
&& pip install frida-tools && git clone https://github.com/httptoolkit/frida-interception-and-unpinning /frida-scripts
CMD bash /preconf/docker-entrypoint.sh CMD bash /preconf/docker-entrypoint.sh

View File

@ -2,6 +2,8 @@ adb start-server
emulator -avd virtual_dev -writable-system -no-window -no-audio -memory 4096 & emulator -avd virtual_dev -writable-system -no-window -no-audio -memory 4096 &
adb wait-for-device
bash /preconf/install_frida.sh
bash /preconf/install_adidreader.sh bash /preconf/install_adidreader.sh
bash /preconf/install_culebra.sh bash /preconf/install_culebra.sh

View File

@ -0,0 +1,13 @@
#!/bin/bash
set -xe
cd /tmp
wget https://github.com/frida/frida/releases/download/17.2.15/frida-server-17.2.15-android-x86_64.xz
xz -d frida-server-17.2.15-android-x86_64.xz
adb push frida-server-17.2.15-android-x86_64 /tmp/frida-server
adb shell su root 'chmod +x /tmp/frida-server'
cd /frida-scripts && perl -i -0777p -e 's|CERT_PEM = .*?;|CERT_PEM = `'"$(cat /certificates/ca.pem | sed -z 's/\n/\\n/g')"'`;|gsm' config.js