Compare commits
No commits in common. "77a459d64f97e49eb70f29be38788c2b4329d009" and "e23cac512ea54ec2b5805ab58ef3725a5a33a781" have entirely different histories.
77a459d64f
...
e23cac512e
@ -12,6 +12,11 @@ WORKDIR /httptoolkit-server
|
||||
RUN git checkout 490b1b6f5180ad634b60997778c5f96b2f62bf0b \
|
||||
&& npm i && npm run build:src
|
||||
|
||||
# Set up proxy_cache_thing
|
||||
ADD proxy_cache_thing /proxy_cache_thing
|
||||
WORKDIR /proxy_cache_thing
|
||||
RUN npm i && npm run build
|
||||
|
||||
ADD entrypoint.sh /entrypoint.sh
|
||||
|
||||
ARG PROXY_PORT
|
||||
|
@ -20,46 +20,13 @@ async function spawnPromise(program, args) {
|
||||
|
||||
let io = new Server();
|
||||
|
||||
import { get_screenshot } from "./screenshot.mjs";
|
||||
|
||||
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;
|
||||
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.trim().split(",");
|
||||
io.emit("private_info", {
|
||||
adid,
|
||||
latitude: gps_coords[0],
|
||||
longitude: gps_coords[1],
|
||||
});
|
||||
}
|
||||
|
||||
async function send_open_ports() {
|
||||
let ports = new Set(
|
||||
(await spawnPromise("bash", ["/conf/get_ports.sh"])).output
|
||||
.trim()
|
||||
.split(" ")
|
||||
);
|
||||
|
||||
let start_ports = fs.readFileSync("/ports").toString().trim().split(" ");
|
||||
for (let port of start_ports) {
|
||||
ports.delete(port);
|
||||
}
|
||||
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));
|
||||
gps_coords = gps_coords.trim().split(',');
|
||||
io.emit("private_info", {adid, latitude: gps_coords[0], longitude: gps_coords[1]})
|
||||
}
|
||||
|
||||
function send_notification(socket, is_ok, context, message) {
|
||||
@ -70,106 +37,59 @@ function send_notification(socket, is_ok, context, message) {
|
||||
});
|
||||
}
|
||||
|
||||
let screenshot_in_flight = false;
|
||||
let gps_setting_in_progress = false;
|
||||
//maybe check output of child processes and send errors in some way
|
||||
io.on("connection", (socket) => {
|
||||
socket.onAny((ev, ...args) => {
|
||||
console.log("server got: ", ev, ...args);
|
||||
});
|
||||
|
||||
let screenshots_in_flight = 0;
|
||||
socket.on("screenshot", async () => {
|
||||
if (screenshots_in_flight > 1) return;
|
||||
screenshots_in_flight++;
|
||||
if (screenshot_in_flight)
|
||||
return;
|
||||
screenshot_in_flight = true;
|
||||
let screen;
|
||||
try {
|
||||
screen = await get_screenshot();
|
||||
socket.emit("screenshot_data", screen);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
"Failed to get the screenshot. The emulator probably died",
|
||||
err
|
||||
);
|
||||
screen = await fetch("http://localhost:9987/v2/uiDevice/screenshot");
|
||||
} catch(err) {
|
||||
console.error("Failed to get the screenshot from culebra, the emulator probably died", err);
|
||||
screenshot_in_flight = false;
|
||||
return;
|
||||
}
|
||||
screenshots_in_flight--;
|
||||
let body = await screen.bytes();
|
||||
socket.emit("screenshot_data", body);
|
||||
screenshot_in_flight = false;
|
||||
});
|
||||
|
||||
let priv_data_requests_in_flight = 0;
|
||||
socket.on("private_info_req", async () => {
|
||||
if (priv_data_requests_in_flight > 3) return;
|
||||
priv_data_requests_in_flight++;
|
||||
|
||||
await send_private_data();
|
||||
priv_data_requests_in_flight--;
|
||||
});
|
||||
|
||||
let port_requests_in_flight = 0;
|
||||
socket.on("open_ports_req", async () => {
|
||||
if (port_requests_in_flight > 3) return;
|
||||
port_requests_in_flight++;
|
||||
await send_open_ports();
|
||||
port_requests_in_flight--;
|
||||
});
|
||||
|
||||
let installed_apps_requests_in_flight = 0;
|
||||
socket.on("installed_apps_req", async () => {
|
||||
if (installed_apps_requests_in_flight > 3) return;
|
||||
installed_apps_requests_in_flight++;
|
||||
await send_installed_apps();
|
||||
installed_apps_requests_in_flight--;
|
||||
});
|
||||
|
||||
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 () => {
|
||||
await spawnPromise("bash", ["/conf/reset_adid.sh"]);
|
||||
await send_private_data();
|
||||
});
|
||||
})
|
||||
|
||||
socket.on("back", async () => {
|
||||
if (gps_setting_in_progress) {
|
||||
send_notification(
|
||||
socket,
|
||||
false,
|
||||
"Interactions not allowed when setting gps coordinates",
|
||||
""
|
||||
);
|
||||
return;
|
||||
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", "");
|
||||
return ;
|
||||
}
|
||||
await spawnPromise("bash", ["/conf/back.sh"]);
|
||||
});
|
||||
|
||||
socket.on("recent", async () => {
|
||||
if (gps_setting_in_progress) {
|
||||
send_notification(
|
||||
socket,
|
||||
false,
|
||||
"Interactions not allowed when setting gps coordinates",
|
||||
""
|
||||
);
|
||||
return;
|
||||
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", "");
|
||||
return ;
|
||||
}
|
||||
await spawnPromise("bash", ["/conf/recent.sh"]);
|
||||
});
|
||||
|
||||
socket.on("home", async () => {
|
||||
if (gps_setting_in_progress) {
|
||||
send_notification(
|
||||
socket,
|
||||
false,
|
||||
"Interactions not allowed when setting gps coordinates",
|
||||
""
|
||||
);
|
||||
return;
|
||||
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", "");
|
||||
return ;
|
||||
}
|
||||
await spawnPromise("bash", ["/conf/home.sh"]);
|
||||
});
|
||||
@ -187,32 +107,22 @@ io.on("connection", (socket) => {
|
||||
// drag handles both drag and click
|
||||
socket.on("motionevent", async (data) => {
|
||||
if (gps_setting_in_progress) {
|
||||
send_notification(
|
||||
socket,
|
||||
false,
|
||||
"Interactions not allowed when setting gps coordinates",
|
||||
""
|
||||
);
|
||||
return;
|
||||
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", "");
|
||||
return ;
|
||||
}
|
||||
await spawnPromise("bash", [
|
||||
"/conf/motionevent.sh",
|
||||
data.motionType,
|
||||
data.x + "",
|
||||
data.y + "",
|
||||
data.y + ""
|
||||
]);
|
||||
});
|
||||
|
||||
// drag handles both drag and click
|
||||
socket.on("drag", async (data) => {
|
||||
if (gps_setting_in_progress) {
|
||||
send_notification(
|
||||
socket,
|
||||
false,
|
||||
"Interactions not allowed when setting gps coordinates",
|
||||
""
|
||||
);
|
||||
return;
|
||||
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", "");
|
||||
return ;
|
||||
}
|
||||
await spawnPromise("bash", [
|
||||
"/conf/drag.sh",
|
||||
@ -226,26 +136,19 @@ io.on("connection", (socket) => {
|
||||
|
||||
socket.on("key", async (data) => {
|
||||
if (gps_setting_in_progress) {
|
||||
send_notification(
|
||||
socket,
|
||||
false,
|
||||
"Interactions not allowed when setting gps coordinates",
|
||||
""
|
||||
);
|
||||
return;
|
||||
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", "");
|
||||
return ;
|
||||
}
|
||||
await spawnPromise("bash", ["/conf/press_key.sh", data.key]);
|
||||
await spawnPromise("bash", [
|
||||
"/conf/press_key.sh",
|
||||
data.key
|
||||
]);
|
||||
});
|
||||
|
||||
socket.on("setcoord", async (data) => {
|
||||
if (gps_setting_in_progress) {
|
||||
send_notification(
|
||||
socket,
|
||||
false,
|
||||
"Interactions not allowed when setting gps coordinates",
|
||||
""
|
||||
);
|
||||
return;
|
||||
send_notification(socket, false, "Interactions not allowed when setting gps coordinates", "");
|
||||
return ;
|
||||
}
|
||||
gps_setting_in_progress = true;
|
||||
const res = await spawnPromise("bash", [
|
||||
|
540
android/code/package-lock.json
generated
540
android/code/package-lock.json
generated
@ -5,116 +5,10 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "^1.14.0",
|
||||
"socket.io": "^4.8.1",
|
||||
"ws": "^8.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@grpc/grpc-js": {
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.0.tgz",
|
||||
"integrity": "sha512-N8Jx6PaYzcTRNzirReJCtADVoq4z7+1KQ4E70jTg/koQiMoUSN1kbNjPOqpPbhMFhfU1/l7ixspPl8dNY+FoUg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@grpc/proto-loader": "^0.8.0",
|
||||
"@js-sdsl/ordered-map": "^4.4.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@grpc/proto-loader": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz",
|
||||
"integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"long": "^5.0.0",
|
||||
"protobufjs": "^7.5.3",
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"bin": {
|
||||
"proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@js-sdsl/ordered-map": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz",
|
||||
"integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/js-sdsl"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/base64": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
||||
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/codegen": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
|
||||
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/eventemitter": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
|
||||
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/fetch": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
|
||||
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.1",
|
||||
"@protobufjs/inquire": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/float": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
||||
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/inquire": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
|
||||
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/path": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
||||
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/pool": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
||||
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@protobufjs/utf8": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@socket.io/component-emitter": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||
@ -152,30 +46,6 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/base64id": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||
@ -185,38 +55,6 @@
|
||||
"node": "^4.5.0 || >= 5.9"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||
@ -256,12 +94,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/engine.io": {
|
||||
"version": "6.6.4",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
|
||||
@ -312,45 +144,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
||||
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
@ -396,39 +189,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/protobufjs": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz",
|
||||
"integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.2",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
"@protobufjs/codegen": "^2.0.4",
|
||||
"@protobufjs/eventemitter": "^1.1.0",
|
||||
"@protobufjs/fetch": "^1.1.0",
|
||||
"@protobufjs/float": "^1.0.2",
|
||||
"@protobufjs/inquire": "^1.1.0",
|
||||
"@protobufjs/path": "^1.1.2",
|
||||
"@protobufjs/pool": "^1.1.0",
|
||||
"@protobufjs/utf8": "^1.1.0",
|
||||
"@types/node": ">=13.7.0",
|
||||
"long": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io": {
|
||||
"version": "4.8.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
|
||||
@ -491,32 +251,6 @@
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||
@ -532,23 +266,6 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||
@ -568,124 +285,9 @@
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": {
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.0.tgz",
|
||||
"integrity": "sha512-N8Jx6PaYzcTRNzirReJCtADVoq4z7+1KQ4E70jTg/koQiMoUSN1kbNjPOqpPbhMFhfU1/l7ixspPl8dNY+FoUg==",
|
||||
"requires": {
|
||||
"@grpc/proto-loader": "^0.8.0",
|
||||
"@js-sdsl/ordered-map": "^4.4.2"
|
||||
}
|
||||
},
|
||||
"@grpc/proto-loader": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz",
|
||||
"integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==",
|
||||
"requires": {
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"long": "^5.0.0",
|
||||
"protobufjs": "^7.5.3",
|
||||
"yargs": "^17.7.2"
|
||||
}
|
||||
},
|
||||
"@js-sdsl/ordered-map": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz",
|
||||
"integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw=="
|
||||
},
|
||||
"@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
|
||||
},
|
||||
"@protobufjs/base64": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
||||
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
|
||||
},
|
||||
"@protobufjs/codegen": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
|
||||
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
|
||||
},
|
||||
"@protobufjs/eventemitter": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
|
||||
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
|
||||
},
|
||||
"@protobufjs/fetch": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
|
||||
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
|
||||
"requires": {
|
||||
"@protobufjs/aspromise": "^1.1.1",
|
||||
"@protobufjs/inquire": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"@protobufjs/float": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
||||
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
|
||||
},
|
||||
"@protobufjs/inquire": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
|
||||
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
|
||||
},
|
||||
"@protobufjs/path": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
||||
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
|
||||
},
|
||||
"@protobufjs/pool": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
||||
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
|
||||
},
|
||||
"@protobufjs/utf8": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
||||
},
|
||||
"@socket.io/component-emitter": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||
@ -716,47 +318,11 @@
|
||||
"negotiator": "0.6.3"
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"base64id": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
|
||||
},
|
||||
"cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||
@ -779,11 +345,6 @@
|
||||
"ms": "^2.1.3"
|
||||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"engine.io": {
|
||||
"version": "6.6.4",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
|
||||
@ -813,31 +374,6 @@
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
|
||||
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q=="
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
|
||||
},
|
||||
"long": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
||||
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
@ -866,30 +402,6 @@
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
|
||||
},
|
||||
"protobufjs": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz",
|
||||
"integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==",
|
||||
"requires": {
|
||||
"@protobufjs/aspromise": "^1.1.2",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
"@protobufjs/codegen": "^2.0.4",
|
||||
"@protobufjs/eventemitter": "^1.1.0",
|
||||
"@protobufjs/fetch": "^1.1.0",
|
||||
"@protobufjs/float": "^1.0.2",
|
||||
"@protobufjs/inquire": "^1.1.0",
|
||||
"@protobufjs/path": "^1.1.2",
|
||||
"@protobufjs/pool": "^1.1.0",
|
||||
"@protobufjs/utf8": "^1.1.0",
|
||||
"@types/node": ">=13.7.0",
|
||||
"long": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
|
||||
},
|
||||
"socket.io": {
|
||||
"version": "4.8.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
|
||||
@ -930,24 +442,6 @@
|
||||
"debug": "~4.3.1"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"undici-types": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||
@ -958,45 +452,11 @@
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
|
||||
"requires": {}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"requires": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "^1.14.0",
|
||||
"socket.io": "^4.8.1",
|
||||
"ws": "^8.18.0"
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
import { loadPackageDefinition, credentials } from '@grpc/grpc-js';
|
||||
import { loadSync } from '@grpc/proto-loader';
|
||||
|
||||
let PROTO_PATH = '/opt/android-sdk-linux/emulator/lib/emulator_controller.proto';
|
||||
let packageDefinition = loadSync(
|
||||
PROTO_PATH,
|
||||
{keepCase: true,
|
||||
longs: String,
|
||||
enums: String,
|
||||
defaults: true,
|
||||
oneofs: true
|
||||
});
|
||||
|
||||
let emu_control = loadPackageDefinition(packageDefinition).android.emulation.control;
|
||||
|
||||
export async function get_screenshot() {
|
||||
let target = 'localhost:8888';
|
||||
let emu_controller = new emu_control.EmulatorController(target,
|
||||
credentials.createInsecure());
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
emu_controller.getScreenshot({}, function(err, response) {
|
||||
if (err === null) {
|
||||
resolve (response.image);
|
||||
} else {
|
||||
reject (err);
|
||||
}
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
}
|
@ -1,22 +1,6 @@
|
||||
bash /conf/startup.sh
|
||||
|
||||
bash /conf/wait_for_sd.sh
|
||||
|
||||
adb shell su root /tmp/frida-server &
|
||||
|
||||
apt-get install iptables -y
|
||||
|
||||
# configuring the pinning / unpinning scripts
|
||||
perl -i -0777p -e 's|CERT_PEM = .*?;|CERT_PEM = `'"$(cat /certificates/mitmproxy-ca-cert.pem | sed -z 's/\n/\\n/g')"'`;|gsm' /frida-scripts/config.js
|
||||
perl -i -0777p -e 's|const PROXY_SUPPORTS_SOCKS5 = false|const PROXY_SUPPORTS_SOCKS5 = false|gsm' /frida-scripts/config.js
|
||||
perl -i -0777p -e 's|const BLOCK_HTTP3 = true|const BLOCK_HTTP3 = true|gsm' /frida-scripts/config.js
|
||||
perl -i -0777p -e 's|const PROXY_PORT = 8000|const PROXY_PORT = 8000|gsm' /frida-scripts/config.js
|
||||
|
||||
# configuring forwarding the proxy info to mitmproxy
|
||||
adb reverse tcp:8000 tcp:8000
|
||||
|
||||
iptables -t nat -A OUTPUT -m addrtype --src-type LOCAL --dst-type LOCAL -p tcp --dport 8000 -j DNAT --to-destination $(getent hosts mitmproxy | awk '{ print $1 }'):1080
|
||||
iptables -t nat -A POSTROUTING -m addrtype --src-type LOCAL --dst-type UNICAST -j MASQUERADE
|
||||
|
||||
bash /conf/start_culebra.sh &
|
||||
npm i -C /code
|
||||
bash /conf/wait_for_sd.sh
|
||||
node /code/index.mjs
|
||||
|
||||
#tail -f /dev/null
|
||||
|
@ -1,2 +0,0 @@
|
||||
set -e
|
||||
frida-ps -Uai --json
|
@ -1,6 +0,0 @@
|
||||
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
|
||||
echo -n $out > /ports
|
||||
fi
|
||||
echo -n $out
|
18
android/conf/start_culebra.sh
Normal file
18
android/conf/start_culebra.sh
Normal file
@ -0,0 +1,18 @@
|
||||
set -x
|
||||
|
||||
function culebra_loop() {
|
||||
export PATH=$PATH:/root/culebraDependencies
|
||||
cd /root/culebra
|
||||
while true; do
|
||||
./culebratester2 start-server
|
||||
done
|
||||
}
|
||||
|
||||
rm -f /opt/android-sdk-linux/.android/avd/virtual_dev.avd/*.lock
|
||||
adb start-server
|
||||
|
||||
emulator -avd virtual_dev -writable-system -no-window -no-audio -memory 4096 &
|
||||
adb wait-for-device
|
||||
adb emu avd snapshot load configured
|
||||
|
||||
culebra_loop
|
@ -1,17 +0,0 @@
|
||||
set -e
|
||||
|
||||
cd /frida-scripts
|
||||
|
||||
frida -U \
|
||||
-l ./config.js \
|
||||
-l ./native-connect-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
|
||||
|
||||
# This is broken with mitmproxy
|
||||
#-l ./native-tls-hook.js \
|
@ -1,13 +0,0 @@
|
||||
set -x
|
||||
|
||||
rm -f /opt/android-sdk-linux/.android/avd/virtual_dev.avd/*.lock
|
||||
adb start-server
|
||||
|
||||
emulator -avd virtual_dev -writable-system -no-window -no-audio -memory 4096 -grpc 8888 &
|
||||
adb wait-for-device
|
||||
adb emu avd snapshot load configured
|
||||
adb wait-for-device
|
||||
|
||||
# set the date on the emulator for the ssl to work properly
|
||||
adb shell su root "date $(date +%m%d%H%M%G.%S)"
|
||||
adb shell su root "am broadcast -a android.intent.action.TIME_SET"
|
@ -1,10 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
node /proxy_cache_thing/dist/index.js &
|
||||
CACHE_PID=$!
|
||||
|
||||
/httptoolkit-server/bin/run start -c /certificates &
|
||||
HTTPTOOLKIT_SERVER_PID=$!
|
||||
|
||||
bash /conf/docker-entrypoint.sh &
|
||||
ANDROID_PID=$!
|
||||
|
||||
function check_dead() {
|
||||
if ! ps -p $CACHE_PID > /dev/null; then
|
||||
echo "[ERROR] The proxy cache died, exiting...";
|
||||
exit 1;
|
||||
fi
|
||||
if ! ps -p $HTTPTOOLKIT_SERVER_PID > /dev/null; then
|
||||
echo "[ERROR] The httptoolkit_server died, exiting...";
|
||||
exit 1;
|
||||
fi
|
||||
if ! ps -p $ANDROID_PID > /dev/null; then
|
||||
echo "[ERROR] The android emulator died, exiting...";
|
||||
exit 1;
|
||||
|
2665
android/proxy_cache_thing/package-lock.json
generated
Normal file
2665
android/proxy_cache_thing/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
35
android/proxy_cache_thing/package.json
Normal file
35
android/proxy_cache_thing/package.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "proxy_thing",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"license": "ISC",
|
||||
"author": "",
|
||||
"type": "commonjs",
|
||||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "tsc",
|
||||
"start": "tsc && node dist/index.js",
|
||||
"lint": "tslint -c tslint.json src/**/*.ts",
|
||||
"prepublish": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.21.2",
|
||||
"mockttp": "^3.16.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslint": "^5.20.1",
|
||||
"ws": "^8.18.1"
|
||||
},
|
||||
"files": [
|
||||
"./bin/*",
|
||||
"./lib/*"
|
||||
],
|
||||
"typings": "./lib/index.d.ts",
|
||||
"directories": {
|
||||
"lib": "lib"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.8.2"
|
||||
},
|
||||
"keywords": []
|
||||
}
|
188
android/proxy_cache_thing/src/index.ts
Normal file
188
android/proxy_cache_thing/src/index.ts
Normal file
@ -0,0 +1,188 @@
|
||||
import { getLocal } from "mockttp";
|
||||
import * as WebSock from "ws";
|
||||
|
||||
const mockServer = getLocal();
|
||||
|
||||
const wait_for_open = (socket: WebSock) => {
|
||||
if (socket.readyState === socket.OPEN) return;
|
||||
return new Promise((resolve, reject) => {
|
||||
const maxNumberOfAttempts = 20;
|
||||
const intervalTime = 100; //ms
|
||||
|
||||
let currentAttempt = 0;
|
||||
const interval = setInterval(() => {
|
||||
if (currentAttempt > maxNumberOfAttempts - 1) {
|
||||
clearInterval(interval);
|
||||
reject(new Error("Maximum number of attempts exceeded"));
|
||||
} else if (socket.readyState === socket.OPEN) {
|
||||
clearInterval(interval);
|
||||
resolve(undefined);
|
||||
} else if (socket.readyState == socket.CLOSED) {
|
||||
console.log(socket.url);
|
||||
reject(new Error("The server socket closed"));
|
||||
}
|
||||
currentAttempt++;
|
||||
}, intervalTime);
|
||||
});
|
||||
};
|
||||
|
||||
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
||||
function waitforhost(
|
||||
url: string,
|
||||
expected_status = 200,
|
||||
interval = 1000,
|
||||
attempts = 10
|
||||
): Promise<void> {
|
||||
let count = 1;
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
while (count < attempts) {
|
||||
await sleep(interval);
|
||||
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (response.status === expected_status) {
|
||||
resolve();
|
||||
break;
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
} catch {
|
||||
count++;
|
||||
console.log(`Still down, trying ${count} of ${attempts}`);
|
||||
}
|
||||
}
|
||||
|
||||
reject(new Error(`Server is down: ${count} attempts tried`));
|
||||
});
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const proxy_port = process.env.PROXY_PORT;
|
||||
const server_port = process.env.SERVER_PORT;
|
||||
const loopback_port = process.env.LOOPBACK_PORT; // internal only
|
||||
const monitoring_api_port = process.env.MONITORING_API_PORT;
|
||||
if (!proxy_port || !server_port || !monitoring_api_port || !loopback_port) {
|
||||
throw Error("Configuration env variables not set");
|
||||
}
|
||||
|
||||
// Expect 403 forbidden
|
||||
await waitforhost("http://127.0.0.1:" + server_port, 403);
|
||||
mockServer.start(+proxy_port);
|
||||
|
||||
let cached_resp: undefined | string = undefined;
|
||||
|
||||
const cors_headers = {
|
||||
"access-control-allow-origin": "*",
|
||||
"access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",
|
||||
"access-control-allow-headers": "Content-Type, Authorization",
|
||||
"access-control-max-age": "86400",
|
||||
"access-control-allow-credentials": "true",
|
||||
Origin: "http://127.0.0.1:8080", // Trick the server into thinking that it is accessed through localhost
|
||||
};
|
||||
await mockServer.forOptions().thenReply(200, "", cors_headers);
|
||||
|
||||
await mockServer.forPost("/start").thenPassThrough({
|
||||
beforeRequest: async (req) => {
|
||||
if (cached_resp) {
|
||||
return {
|
||||
response: { body: cached_resp, headers: cors_headers },
|
||||
};
|
||||
}
|
||||
// forward the request to the real server
|
||||
return {
|
||||
url: req.url,
|
||||
headers: req.headers,
|
||||
body: await req.body.getDecodedBuffer(),
|
||||
};
|
||||
},
|
||||
beforeResponse: async (resp, _req) => {
|
||||
// cache the response
|
||||
cached_resp = (await resp.body.getText()) as string;
|
||||
// set the cors headers, overwriting the prohibitive ones
|
||||
return { headers: { ...resp.headers, ...cors_headers } };
|
||||
},
|
||||
});
|
||||
|
||||
await mockServer.forPost("/stop").thenReply(200);
|
||||
|
||||
// forward everything to the real server
|
||||
await mockServer.forUnmatchedRequest().thenPassThrough({
|
||||
beforeRequest: async (req) => {
|
||||
return { url: req.url };
|
||||
},
|
||||
beforeResponse: async (resp, _req) => {
|
||||
return { headers: { ...resp.headers, ...cors_headers } };
|
||||
},
|
||||
});
|
||||
|
||||
await mockServer
|
||||
.forAnyWebSocket()
|
||||
.thenForwardTo("ws://127.0.0.1:" + loopback_port);
|
||||
|
||||
let wss = new WebSock.Server({ port: +loopback_port });
|
||||
|
||||
// this is append only
|
||||
let httptoolkit_server_messages: String[] = [];
|
||||
|
||||
let api_server = new WebSock.Server({ port: +monitoring_api_port });
|
||||
|
||||
api_server.on("connection", (ws) => {
|
||||
let curr_idx_to_send = 0;
|
||||
const interval = setInterval(() => {
|
||||
while (httptoolkit_server_messages[curr_idx_to_send] != undefined) {
|
||||
if (ws.readyState != ws.OPEN) {
|
||||
clearInterval(interval);
|
||||
ws.close();
|
||||
break;
|
||||
}
|
||||
ws.send(httptoolkit_server_messages[curr_idx_to_send]);
|
||||
curr_idx_to_send++;
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
wss.on("connection", (ws, req) => {
|
||||
let server_session_url = "ws://127.0.0.1:" + server_port + req.url;
|
||||
let httptoolkit_server_session: WebSock;
|
||||
console.log("ws connection:", ws.protocol, typeof ws.protocol);
|
||||
if (ws.protocol) {
|
||||
httptoolkit_server_session = new WebSock(
|
||||
server_session_url,
|
||||
ws.protocol,
|
||||
{ joinDuplicateHeaders: true, headers: req.headers }
|
||||
);
|
||||
} else {
|
||||
httptoolkit_server_session = new WebSock(server_session_url, {
|
||||
joinDuplicateHeaders: true,
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
httptoolkit_server_session.onerror = (_) => {
|
||||
ws.close();
|
||||
httptoolkit_server_session.close();
|
||||
return;
|
||||
};
|
||||
httptoolkit_server_session.onopen = () => {
|
||||
console.log("ws connected to the server");
|
||||
};
|
||||
|
||||
httptoolkit_server_session.onmessage = (msg) => {
|
||||
httptoolkit_server_messages.push(msg.data.toString());
|
||||
ws.send(msg.data);
|
||||
};
|
||||
|
||||
// Listening for messages from the client
|
||||
ws.on("message", async (message) => {
|
||||
await wait_for_open(httptoolkit_server_session);
|
||||
httptoolkit_server_session.send(message.toString());
|
||||
});
|
||||
|
||||
// Handling client disconnection
|
||||
ws.on("close", () => {
|
||||
httptoolkit_server_session.close();
|
||||
});
|
||||
});
|
||||
|
||||
console.log("WS Proxy started");
|
||||
console.log(mockServer.proxyEnv);
|
||||
})();
|
38
android/proxy_cache_thing/tsconfig.json
Normal file
38
android/proxy_cache_thing/tsconfig.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"lib": [
|
||||
"es2015"
|
||||
],
|
||||
|
||||
"rootDir": "src",
|
||||
"outDir": "dist",
|
||||
|
||||
"strict": true,
|
||||
"alwaysStrict": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictNullChecks": true,
|
||||
"strictPropertyInitialization": true,
|
||||
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"downlevelIteration": true,
|
||||
"declaration": true,
|
||||
|
||||
"pretty": true
|
||||
},
|
||||
"include": [
|
||||
"typings/**/*",
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
3
android/proxy_cache_thing/tslint.json
Normal file
3
android/proxy_cache_thing/tslint.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "tslint:latest"
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
# docker run --entrypoint sh --rm -it -v ./certificates:/certs alpine/openssl /certs/gen.sh
|
||||
FROM node:22.14.0
|
||||
|
||||
FROM alpine/openssl
|
||||
RUN git clone https://github.com/httptoolkit/httptoolkit-server
|
||||
|
||||
COPY gen_certs.sh /gen_certs.sh
|
||||
WORKDIR /httptoolkit-server
|
||||
RUN git checkout 490b1b6f5180ad634b60997778c5f96b2f62bf0b \
|
||||
&& npm i && npm run build:src
|
||||
|
||||
ENTRYPOINT sh /gen_certs.sh
|
||||
# CMD sh
|
||||
CMD /httptoolkit-server/bin/run start -c /certificates
|
||||
|
@ -1,20 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -xe
|
||||
|
||||
cd /certificates
|
||||
rm -rf *
|
||||
|
||||
cat > myconfig.cnf << EOF
|
||||
[mysection]
|
||||
keyUsage = critical, digitalSignature, nonRepudiation, keyCertSign, cRLSign
|
||||
basicConstraints = critical, CA:TRUE
|
||||
EOF
|
||||
|
||||
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -sha256 -days 365 -not_before $(date --date="@$(( $(date +%s) - 86400 * 7 ))" +%y%m%d%H%M%SZ) -nodes -subj "/C=XX/O=Sealcode/OU=CompanySectionName/CN=Do not trust, rentgendroid certificate" -config myconfig.cnf -extensions mysection
|
||||
|
||||
cat cert.pem key.pem > mitmproxy-ca.pem
|
||||
|
||||
mv cert.pem mitmproxy-ca-cert.pem
|
||||
|
||||
rm myconfig.cnf
|
@ -11,14 +11,12 @@ services:
|
||||
container_name: android
|
||||
sysctls:
|
||||
- net.ipv6.conf.all.disable_ipv6=1
|
||||
- net.ipv4.conf.all.route_localnet=1
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/kvm
|
||||
networks:
|
||||
- rent_gen_android
|
||||
|
||||
ports:
|
||||
- 45456:45459 # This cannot change
|
||||
- 45457:45459 # This cannot change
|
||||
@ -26,20 +24,24 @@ services:
|
||||
- 3000:3000 # android server port
|
||||
- 3001:3001 # Notifications server
|
||||
- 5556:5556 # emulator grpc port
|
||||
|
||||
volumes:
|
||||
- $PWD/shared_buffer:/shared_buffer
|
||||
- $PWD/android/conf:/conf
|
||||
- $PWD/certificates:/certificates
|
||||
- $PWD/android/code:/code
|
||||
|
||||
mitmproxy:
|
||||
build: ./mitmproxy
|
||||
httptoolkit_ui:
|
||||
build:
|
||||
context: ./httptoolkit_ui/
|
||||
args:
|
||||
# The ip / hostname using which,
|
||||
# the browser can reach this docker session
|
||||
DOCKER_HOST: "127.0.0.1"
|
||||
container_name: httptoolkit_ui
|
||||
networks:
|
||||
- rent_gen_android
|
||||
volumes:
|
||||
- $PWD/certificates:/root/.mitmproxy
|
||||
container_name: mitmproxy
|
||||
ports:
|
||||
- 9080:9080
|
||||
http_server:
|
||||
build: ./http_server/
|
||||
container_name: http_server
|
||||
|
@ -1,6 +1,6 @@
|
||||
FROM alpine:3.18.2
|
||||
|
||||
RUN apk add npm git openssh
|
||||
RUN apk add npm
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
|
1
http_server/code/dist/styles.css
vendored
1
http_server/code/dist/styles.css
vendored
@ -1 +0,0 @@
|
||||
../styles.css
|
@ -1,5 +1,4 @@
|
||||
#!/bin/bash
|
||||
set -xe
|
||||
|
||||
npm i
|
||||
npm run build
|
||||
|
@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>Rentgen android</title>
|
||||
<script src="/htmx.js"></script>
|
||||
<link rel="stylesheet" href="/styles.css" />
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<script src="/main.js" type="module"></script>
|
||||
</head>
|
||||
<body>
|
||||
@ -49,6 +49,12 @@
|
||||
|
||||
<div class="tab-section">
|
||||
<div class="tab">
|
||||
<button
|
||||
class="tablinks active"
|
||||
onclick="main.open_tab(event, 'httptoolkit-tab')"
|
||||
>
|
||||
HttpToolkit UI
|
||||
</button>
|
||||
<button class="tablinks" onclick="main.open_tab(event, 'logs-tab')">
|
||||
Logs
|
||||
</button>
|
||||
@ -60,13 +66,13 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="tabcontent active" id="logs-tab">
|
||||
<div class="tabcontent" id="logs-tab">
|
||||
<div id="logs">
|
||||
<p id="clicks-log" class="log-section"></p>
|
||||
<div id="traffic-log" class="log-section">
|
||||
<div>
|
||||
<button onclick="main.download_har()">Download HAR</button>
|
||||
<button onclick="main.inspect_har()">Inspect HAR</button>
|
||||
<button onClick="main.download_har()">Download HAR</button>
|
||||
<button onClick="main.inspect_har()">Inspect HAR</button>
|
||||
<div>
|
||||
<h2>stats:</h2>
|
||||
<p id="traffic-log-req-res-pairs">
|
||||
@ -83,6 +89,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tabcontent active" id="httptoolkit-tab">
|
||||
<iframe
|
||||
id="httptoolkit-frame"
|
||||
style="flex-grow: 1"
|
||||
src="http://localhost:9080/"
|
||||
title="httptoolkit"
|
||||
></iframe>
|
||||
</div>
|
||||
<div class="tabcontent" id="controls-tab">
|
||||
<form id="set_coords" onsubmit="main.coords_handler(event)">
|
||||
<label>
|
||||
@ -115,16 +129,6 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</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>
|
||||
<p id="open-ports"></p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
@ -63,11 +63,9 @@ app.get("/", async function (req, res) {
|
||||
//POST
|
||||
app.use(express.text({limit: "100mb"}));
|
||||
|
||||
app.post("/inspect_har", upload.none(), async function (req, res) {
|
||||
app.post("/inspect_har", upload.none(), function (req, res) {
|
||||
let body = req.body;
|
||||
let har_req = await fetch("http://mitmproxy:9111/get_har")
|
||||
let har = await har_req.text();
|
||||
|
||||
let har = body.har;
|
||||
let private_data;
|
||||
if (body.private_data)
|
||||
private_data = JSON.parse(body.private_data);
|
||||
@ -76,20 +74,6 @@ app.post("/inspect_har", upload.none(), async function (req, res) {
|
||||
res.send(build_html(har, private_data));
|
||||
});
|
||||
|
||||
app.get("/download_har", upload.none(), async function (req, res) {
|
||||
let har_req = await fetch("http://mitmproxy:9111/get_har")
|
||||
let har = await har_req.text();
|
||||
|
||||
res.status(200).send(har);
|
||||
});
|
||||
|
||||
app.get("/get_intercept_stats", upload.none(), async function (_req, res) {
|
||||
let req = await fetch("http://mitmproxy:9111/get_stats")
|
||||
let stats = await req.text();
|
||||
|
||||
res.status(200).send(stats);
|
||||
});
|
||||
|
||||
app.use(fileUpload());
|
||||
app.post("/upload_apk", async function (req, res) {
|
||||
if (!req.files || Object.keys(req.files).length === 0) {
|
||||
|
673
http_server/code/package-lock.json
generated
673
http_server/code/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -12,11 +12,7 @@ import {
|
||||
adid_priv_info_table,
|
||||
lat_priv_info_table,
|
||||
lon_priv_info_table,
|
||||
recentButton,
|
||||
open_ports,
|
||||
app_id_select,
|
||||
launch_app_form,
|
||||
sleep,
|
||||
recentButton,
|
||||
} from "./shared";
|
||||
|
||||
import { start_notifications } from "./notifications";
|
||||
@ -120,55 +116,6 @@ socket.on("private_info", (data) => {
|
||||
lon_priv_info_table.textContent = data.longitude;
|
||||
});
|
||||
|
||||
socket.on("open_ports", (data: string[]) => {
|
||||
console.log("open_ports");
|
||||
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.onAny((ev, ...args) => {
|
||||
@ -266,6 +213,10 @@ window.addEventListener("keydown", (event) => {
|
||||
}
|
||||
});
|
||||
|
||||
export async function sleep(time: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, time));
|
||||
}
|
||||
|
||||
async function screenshot_loop() {
|
||||
var before;
|
||||
|
||||
@ -276,19 +227,6 @@ async function screenshot_loop() {
|
||||
while (performance.now() - before < 100) await sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
async function open_ports_loop() {
|
||||
var before;
|
||||
|
||||
while (true) {
|
||||
before = performance.now();
|
||||
socket.emit("open_ports_req");
|
||||
while (performance.now() - before < 2000) await sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
installed_apps_loop();
|
||||
open_ports_loop();
|
||||
screenshot_loop();
|
||||
start_notifications();
|
||||
start_traffic_log();
|
||||
|
@ -12,14 +12,4 @@ export const adid_priv_info_table = document.getElementById("adid_priv_info_tabl
|
||||
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 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 async function sleep(time: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, time));
|
||||
}
|
||||
|
||||
|
@ -1,38 +1,41 @@
|
||||
import { Entry, Har, PostData, Request, Response } from "har-format";
|
||||
import {
|
||||
adid_priv_info_table,
|
||||
lat_priv_info_table,
|
||||
lon_priv_info_table,
|
||||
sleep,
|
||||
} from "./shared";
|
||||
|
||||
// Request + responce pairs: 0
|
||||
const req_res_pairs = document.getElementById("traffic-log-req-res-pairs")!;
|
||||
|
||||
export async function start_traffic_log() {
|
||||
// Waiting for the responce: 0
|
||||
const waiting = document.getElementById("traffic-log-waiting")!;
|
||||
|
||||
var before;
|
||||
const traffic_log_lines = document.getElementById("traffic-log-lines")!;
|
||||
|
||||
while (true) {
|
||||
before = performance.now();
|
||||
let connections = "UNKNOWN";
|
||||
try {
|
||||
let req = await fetch("/get_intercept_stats");
|
||||
const inspect_har_form: HTMLFormElement = document.getElementById(
|
||||
"inspect-har-form"
|
||||
)! as HTMLFormElement;
|
||||
|
||||
let req_text = await req.text();
|
||||
let json = JSON.parse(req_text);
|
||||
connections = json.connections.toString();
|
||||
} catch(_) {}
|
||||
req_res_pairs.innerText = `Request + responce pairs: ${connections}`;
|
||||
const connection = new WebSocket("ws://localhost:10001");
|
||||
|
||||
while (performance.now() - before < 1000) await sleep(500);
|
||||
}
|
||||
const unfinished_entries: Map<string, Entry> = new Map();
|
||||
const finished_entries: Entry[] = [];
|
||||
|
||||
export function start_traffic_log() {
|
||||
update_stats();
|
||||
connection.onmessage = (msg) => {
|
||||
process_msg(msg.data);
|
||||
update_stats();
|
||||
};
|
||||
connection.onclose = connection.onerror = () => {
|
||||
window.location.reload();
|
||||
};
|
||||
}
|
||||
|
||||
export async function download_har() {
|
||||
export function download_har() {
|
||||
var tempLink = document.createElement("a");
|
||||
let res = await fetch("/download_har");
|
||||
let res_text = await res.text()
|
||||
var taBlob = new Blob([res_text], {
|
||||
var taBlob = new Blob([JSON.stringify(export_har())], {
|
||||
type: "text/plain",
|
||||
});
|
||||
|
||||
@ -66,6 +69,8 @@ function launch_window_with_post(url: string, data: any) {
|
||||
|
||||
export async function inspect_har() {
|
||||
let data = {
|
||||
har: JSON.stringify(export_har()),
|
||||
|
||||
private_data: JSON.stringify([
|
||||
{desc: "adid", data: adid_priv_info_table.textContent},
|
||||
{desc: "latitude", data: lat_priv_info_table.textContent },
|
||||
@ -76,5 +81,144 @@ export async function inspect_har() {
|
||||
}
|
||||
|
||||
function update_stats() {
|
||||
// waiting.innerText = `Waiting for the responce: ${unfinished_entries.size}`;
|
||||
req_res_pairs.innerText = `Request + responce pairs: ${finished_entries.length}`;
|
||||
waiting.innerText = `Waiting for the responce: ${unfinished_entries.size}`;
|
||||
}
|
||||
|
||||
function process_msg(s: string) {
|
||||
let obj = JSON.parse(s);
|
||||
console.log(obj);
|
||||
|
||||
if (obj.type !== "data") return;
|
||||
if (obj.payload && obj.payload.data && obj.payload.data.requestReceived)
|
||||
process_req(obj.payload.data.requestReceived);
|
||||
if (obj.payload && obj.payload.data && obj.payload.data.responseCompleted)
|
||||
process_res(obj.payload.data.responseCompleted);
|
||||
}
|
||||
|
||||
function process_res(res: any) {
|
||||
let entry = unfinished_entries.get(res.id)!;
|
||||
|
||||
let content_type = "application/text";
|
||||
let headers = JSON.parse(res.rawHeaders).map((header: [string, string]) => {
|
||||
if (header[0].toLowerCase() === "content-type")
|
||||
content_type = header[1];
|
||||
return { name: header[0], value: header[1], comment: "" };
|
||||
});
|
||||
|
||||
//'{"startTime":1751745139334,
|
||||
// "startTimestamp":347666.762487,
|
||||
// "bodyReceivedTimestamp":347667.529477,
|
||||
// "headersSentTimestamp":347906.038202,
|
||||
// "responseSentTimestamp":347906.616067}'
|
||||
|
||||
let timing_events = JSON.parse(res.timingEvents);
|
||||
|
||||
let start_ts = timing_events.startTimestamp;
|
||||
let got_headers_ts = timing_events.headersSentTimestamp;
|
||||
let end_ts = timing_events.responseSentTimestamp;
|
||||
|
||||
let wait_time = got_headers_ts - start_ts;
|
||||
let recieve_time = end_ts - got_headers_ts;
|
||||
|
||||
let response: Response = {
|
||||
status: res.statusCode,
|
||||
statusText: res.statusMessage,
|
||||
httpVersion: entry.request.httpVersion,
|
||||
cookies: [],
|
||||
headers,
|
||||
content: {
|
||||
size: 0,
|
||||
mimeType: content_type,
|
||||
text: res.body,
|
||||
encoding: "base64",
|
||||
},
|
||||
redirectURL: "",
|
||||
headersSize: -1,
|
||||
bodySize: -1,
|
||||
};
|
||||
|
||||
entry.response = response;
|
||||
entry.timings.wait = wait_time;
|
||||
entry.timings.receive = recieve_time;
|
||||
unfinished_entries.delete(res.id);
|
||||
finished_entries.push(entry);
|
||||
|
||||
let el = document.createElement("span");
|
||||
el.innerHTML = `
|
||||
${entry.request.url}
|
||||
<br />`;
|
||||
traffic_log_lines.appendChild(el);
|
||||
}
|
||||
|
||||
function process_req(req: any) {
|
||||
let content_type = "application/text";
|
||||
|
||||
let headers = JSON.parse(req.rawHeaders).map((header: [string, string]) => {
|
||||
if (header[0].toLowerCase() === "Content-Type")
|
||||
content_type = header[1];
|
||||
return { name: header[0], value: header[1], comment: "" };
|
||||
});
|
||||
|
||||
let timing_events = JSON.parse(req.timingEvents);
|
||||
|
||||
let start_time: number = timing_events.startTime!;
|
||||
|
||||
let start_datetime = new Date(start_time).toISOString();
|
||||
|
||||
let request: Request = {
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
httpVersion: req.httpVersion,
|
||||
cookies: [],
|
||||
headers,
|
||||
queryString: [],
|
||||
postData: req.body
|
||||
? ({ text: req.body, mimeType: content_type } as PostData)
|
||||
: undefined,
|
||||
headersSize: -1,
|
||||
bodySize: -1,
|
||||
comment: "",
|
||||
};
|
||||
|
||||
//'{"startTime":1751745139334,"startTimestamp":347666.762487,"bodyReceivedTimestamp":347667.529477,"headersSentTimestamp":347906.038202,"responseSentTimestamp":347906.616067}'
|
||||
let entry: Entry = {
|
||||
startedDateTime: start_datetime,
|
||||
time: 0,
|
||||
request: request,
|
||||
response: {
|
||||
status: 0,
|
||||
statusText: "",
|
||||
httpVersion: "",
|
||||
cookies: [],
|
||||
headers: [],
|
||||
content: {
|
||||
size: 0,
|
||||
mimeType: "",
|
||||
},
|
||||
redirectURL: "",
|
||||
headersSize: 0,
|
||||
bodySize: 0,
|
||||
},
|
||||
cache: {},
|
||||
timings: {
|
||||
wait: 0,
|
||||
receive: 0,
|
||||
},
|
||||
};
|
||||
unfinished_entries.set(req.id, entry);
|
||||
}
|
||||
|
||||
function export_har(): Har {
|
||||
let ret: Har = {
|
||||
log: {
|
||||
version: "1.2",
|
||||
creator: {
|
||||
name: "Rentgendroid",
|
||||
version: "0.0.1",
|
||||
},
|
||||
entries: [...finished_entries, ...unfinished_entries.values()],
|
||||
},
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
15
http_server/code/test.html
Normal file
15
http_server/code/test.html
Normal file
@ -0,0 +1,15 @@
|
||||
<script type="text/javascript">
|
||||
function randomlinks(){
|
||||
var myrandom=Math.round(Math.random()*3)
|
||||
var links=new Array()
|
||||
links[0]="https://www.DemiCardGame.com"
|
||||
links[1]="https://www.games.xyphienllc.com"
|
||||
links[2]="https://www.htcg.news"
|
||||
links[3]="https://www.eTableCon.com"
|
||||
|
||||
window.open(links[myrandom], '_blank');
|
||||
}
|
||||
</script>
|
||||
<form>
|
||||
<input type="button" value="random link!" onClick="randomlinks()">
|
||||
</form>
|
23
httptoolkit_ui/Dockerfile
Normal file
23
httptoolkit_ui/Dockerfile
Normal file
@ -0,0 +1,23 @@
|
||||
FROM node:20.18.1
|
||||
|
||||
# Set up node
|
||||
RUN npm install -g n && n install 22.14.0 && n use 22.14.0 && hash -r
|
||||
|
||||
# If iproute2 is not installed,
|
||||
# node can't figure out what address to bind 0.0.0.0 to
|
||||
RUN apt-get update && apt-get install iproute2 python3 --yes \
|
||||
&& git clone https://github.com/httptoolkit/httptoolkit-ui
|
||||
|
||||
WORKDIR httptoolkit-ui
|
||||
RUN git checkout ac44f8e6e1f5f41be988a32eb89c98f57723d005 \
|
||||
&& npm i && npm run server:setup
|
||||
|
||||
ARG DOCKER_HOST=localhost
|
||||
|
||||
# This gets sent to the browser as a server URL,
|
||||
# so it is important that it is set to the domain / ip of the server.
|
||||
|
||||
RUN sed -i "s/127.0.0.1/${DOCKER_HOST}/" src/model/proxy-store.ts \
|
||||
&& npm run build:default # Can take a long time
|
||||
|
||||
CMD npm exec static-server ./dist -o
|
@ -1,12 +0,0 @@
|
||||
FROM mitmproxy/mitmproxy
|
||||
|
||||
USER root
|
||||
WORKDIR /root
|
||||
|
||||
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
||||
COPY stats.py /stats.py
|
||||
|
||||
# CMD bash -c 'mitmdump -w ~/.mitmproxy/dump --set mode="socks5@0.0.0.0:1080"'
|
||||
ENTRYPOINT /docker-entrypoint.sh
|
||||
# cmd sleep 1000000000
|
||||
#--set mode="regular@0.0.0.0:8000"
|
@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -xe
|
||||
|
||||
cd /root
|
||||
script -c 'mitmdump -s /stats.py --set mode=regular@0.0.0.0:1080 -v'
|
@ -1,81 +0,0 @@
|
||||
from typing import Optional
|
||||
import mitmproxy.addons.savehar
|
||||
from mitmproxy import http
|
||||
from mitmproxy.types import Path
|
||||
from mitmproxy.addonmanager import Loader
|
||||
import threading
|
||||
import time
|
||||
import json
|
||||
from http import HTTPStatus
|
||||
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
|
||||
class SaveHar2:
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.save_har = mitmproxy.addons.savehar.SaveHar()
|
||||
self.counter = 0
|
||||
|
||||
server_address = ('', 9111)
|
||||
parr = self
|
||||
|
||||
class HTTPRequestHandler(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
|
||||
if self.path == '/get_har':
|
||||
print(parr.save_har.flows);
|
||||
self.send_response(HTTPStatus.OK)
|
||||
self.send_header("Content-type", "application/json")
|
||||
self.end_headers()
|
||||
har = parr.get_har_json()
|
||||
self.wfile.write(har)
|
||||
|
||||
if self.path == '/get_stats':
|
||||
self.send_response(HTTPStatus.OK)
|
||||
self.send_header("Content-type", "application/json")
|
||||
self.end_headers()
|
||||
har = parr.get_har_json()
|
||||
self.wfile.write(("{\"connections\": " + str(len(parr.save_har.flows)) +" }\n").encode("utf8"))
|
||||
|
||||
self.httpd = HTTPServer(server_address, HTTPRequestHandler)
|
||||
print("Server started ...")
|
||||
|
||||
self.httpd_thread = threading.Thread(target=self.httpd.serve_forever)
|
||||
self.httpd_thread.start()
|
||||
|
||||
def save_har_to_file(self):
|
||||
self.save_har.export_har(self.save_har.flows, Path("output.har"))
|
||||
|
||||
def get_har_json(self) -> bytes:
|
||||
return json.dumps(self.save_har.make_har(self.save_har.flows), indent=4).encode()
|
||||
|
||||
def configure(self, updated):
|
||||
self.save_har.configure(updated);
|
||||
|
||||
def _save_flow(self, flow: http.HTTPFlow) -> None:
|
||||
self.save_har.flows.append(flow)
|
||||
|
||||
def response(self, flow: http.HTTPFlow) -> None:
|
||||
# websocket flows will receive a websocket_end,
|
||||
# we don't want to persist them here already
|
||||
if flow.websocket is None:
|
||||
self._save_flow(flow)
|
||||
|
||||
if flow.websocket is None:
|
||||
self._save_flow(flow)
|
||||
|
||||
self.counter += 1
|
||||
if (self.counter == 5):
|
||||
print("Outputing har")
|
||||
print(self.save_har.flows)
|
||||
self.save_har_to_file()
|
||||
self.counter = 0
|
||||
|
||||
|
||||
def error(self, flow: http.HTTPFlow) -> None:
|
||||
self.response(flow)
|
||||
|
||||
def websocket_end(self, flow: http.HTTPFlow) -> None:
|
||||
self._save_flow(flow)
|
||||
|
||||
addons = [SaveHar2()]
|
@ -4,7 +4,6 @@ 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" \
|
||||
&& 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 iptables 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
|
||||
&& apt-get update && apt-get install -y iproute2 iputils-ping npm git libxml2-utils telnet bc
|
||||
|
||||
CMD bash /preconf/docker-entrypoint.sh
|
||||
|
@ -2,9 +2,8 @@ adb start-server
|
||||
|
||||
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_culebra.sh
|
||||
|
||||
# Open google maps once, skip all the screens, and give it gps permissions
|
||||
adb shell am start-activity com.google.android.apps.maps
|
||||
|
11
pre_android/preconf/install_culebra.sh
Normal file
11
pre_android/preconf/install_culebra.sh
Normal file
@ -0,0 +1,11 @@
|
||||
adb wait-for-device
|
||||
cd /root
|
||||
git clone https://github.com/dtmilano/CulebraTester2-public culebra
|
||||
git clone https://gist.github.com/dtmilano/4537110 culebraDependencies
|
||||
export PATH=$PATH:/root/culebraDependencies
|
||||
|
||||
cd culebra
|
||||
git checkout 4ce1987e7ec6ae627d8f33a1a3b59f684aff90c0
|
||||
echo "/opt/android-sdk-linux" >> local.properties
|
||||
./culebratester2 install
|
||||
|
@ -1,11 +0,0 @@
|
||||
#!/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'
|
27
start.mjs
27
start.mjs
@ -5,8 +5,10 @@ async function sleep(time) {
|
||||
}
|
||||
|
||||
async function checkCertExistance() {
|
||||
await fs.access("./certificates/mitmproxy-ca-cert.pem");
|
||||
await fs.access("./certificates/mitmproxy-ca.pem", fs.constants.R_OK);
|
||||
return await Promise.all([
|
||||
fs.access("./certificates/ca.key"),
|
||||
fs.access("./certificates/ca.pem", fs.constants.R_OK),
|
||||
]);
|
||||
}
|
||||
|
||||
async function generateCert() {
|
||||
@ -20,12 +22,23 @@ async function generateCert() {
|
||||
);
|
||||
}
|
||||
|
||||
await $`docker build --tag certgen $PWD/certgen`;
|
||||
// generate certs
|
||||
await $`docker run --rm -v $PWD/certificates:/certificates --name certGenerator certgen`;
|
||||
await $`docker build --tag certgen $PWD/certgen`
|
||||
// iniciate docker which will create certs
|
||||
$`docker run --rm -v $PWD/certificates:/certificates --name certGenerator certgen &`;
|
||||
|
||||
// clean up
|
||||
await $`docker rmi certgen`;
|
||||
//wait for certs to generate
|
||||
let generated = false;
|
||||
while (!generated) {
|
||||
try {
|
||||
await checkCertExistance();
|
||||
await $`sleep 1`;
|
||||
generated = true;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
//kill docker container
|
||||
await $`docker stop certGenerator`;
|
||||
await $`docker rmi certgen`
|
||||
}
|
||||
|
||||
async function generatePreAndroid() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user