mitmproxy
This commit is contained in:
parent
e3f97f5488
commit
cab43f63ce
@ -12,11 +12,6 @@ WORKDIR /httptoolkit-server
|
|||||||
RUN git checkout 490b1b6f5180ad634b60997778c5f96b2f62bf0b \
|
RUN git checkout 490b1b6f5180ad634b60997778c5f96b2f62bf0b \
|
||||||
&& npm i && npm run build:src
|
&& 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
|
ADD entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
ARG PROXY_PORT
|
ARG PROXY_PORT
|
||||||
|
@ -68,44 +68,57 @@ function send_notification(socket, is_ok, context, message) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let screenshot_in_flight = false;
|
|
||||||
let gps_setting_in_progress = false;
|
let gps_setting_in_progress = false;
|
||||||
//maybe check output of child processes and send errors in some way
|
//maybe check output of child processes and send errors in some way
|
||||||
io.on("connection", (socket) => {
|
io.on("connection", (socket) => {
|
||||||
socket.onAny((ev, ...args) => {
|
socket.onAny((ev, ...args) => {
|
||||||
console.log("server got: ", ev, ...args);
|
console.log("server got: ", ev, ...args);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let screenshots_in_flight = 0;
|
||||||
socket.on("screenshot", async () => {
|
socket.on("screenshot", async () => {
|
||||||
if (screenshot_in_flight) return;
|
if (screenshots_in_flight > 1) return;
|
||||||
screenshot_in_flight = true;
|
screenshots_in_flight++;
|
||||||
let screen;
|
let screen;
|
||||||
try {
|
try {
|
||||||
screen = await fetch(
|
screen = await fetch(
|
||||||
"http://localhost:9987/v2/uiDevice/screenshot"
|
"http://localhost:9987/v2/uiDevice/screenshot"
|
||||||
);
|
);
|
||||||
|
let body = await screen.bytes();
|
||||||
|
socket.emit("screenshot_data", body);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(
|
console.error(
|
||||||
"Failed to get the screenshot from culebra, the emulator probably died",
|
"Failed to get the screenshot from culebra, the emulator probably died",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
screenshot_in_flight = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let body = await screen.bytes();
|
screenshots_in_flight--;
|
||||||
socket.emit("screenshot_data", body);
|
|
||||||
screenshot_in_flight = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let priv_data_requests_in_flight = 0;
|
||||||
socket.on("private_info_req", async () => {
|
socket.on("private_info_req", async () => {
|
||||||
|
if (priv_data_requests_in_flight > 3) return;
|
||||||
|
priv_data_requests_in_flight++;
|
||||||
|
|
||||||
await send_private_data();
|
await send_private_data();
|
||||||
|
priv_data_requests_in_flight--;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let port_requests_in_flight = 0;
|
||||||
socket.on("open_ports_req", async () => {
|
socket.on("open_ports_req", async () => {
|
||||||
|
if (port_requests_in_flight > 3) return;
|
||||||
|
port_requests_in_flight++;
|
||||||
await send_open_ports();
|
await send_open_ports();
|
||||||
|
port_requests_in_flight--;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let installed_apps_requests_in_flight = 0;
|
||||||
socket.on("installed_apps_req", async () => {
|
socket.on("installed_apps_req", async () => {
|
||||||
|
if (installed_apps_requests_in_flight > 3) return;
|
||||||
|
installed_apps_requests_in_flight++;
|
||||||
await send_installed_apps();
|
await send_installed_apps();
|
||||||
|
installed_apps_requests_in_flight--;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("start_frida_app", async (app_id) => {
|
socket.on("start_frida_app", async (app_id) => {
|
||||||
|
@ -7,7 +7,7 @@ apt-get install iptables -y
|
|||||||
|
|
||||||
# configuring the pinning / unpinning scripts
|
# 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|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 = true|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 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
|
perl -i -0777p -e 's|const PROXY_PORT = 8000|const PROXY_PORT = 8000|gsm' /frida-scripts/config.js
|
||||||
|
|
||||||
|
@ -15,4 +15,8 @@ emulator -avd virtual_dev -writable-system -no-window -no-audio -memory 4096 &
|
|||||||
adb wait-for-device
|
adb wait-for-device
|
||||||
adb emu avd snapshot load configured
|
adb emu avd snapshot load configured
|
||||||
|
|
||||||
|
# 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 "am broadcast -a android.intent.action.TIME_SET"
|
||||||
|
|
||||||
culebra_loop
|
culebra_loop
|
||||||
|
@ -5,11 +5,13 @@ cd /frida-scripts
|
|||||||
frida -U \
|
frida -U \
|
||||||
-l ./config.js \
|
-l ./config.js \
|
||||||
-l ./native-connect-hook.js \
|
-l ./native-connect-hook.js \
|
||||||
-l ./native-tls-hook.js \
|
|
||||||
-l ./android/android-proxy-override.js \
|
-l ./android/android-proxy-override.js \
|
||||||
-l ./android/android-system-certificate-injection.js \
|
-l ./android/android-system-certificate-injection.js \
|
||||||
-l ./android/android-certificate-unpinning.js \
|
-l ./android/android-certificate-unpinning.js \
|
||||||
-l ./android/android-certificate-unpinning-fallback.js \
|
-l ./android/android-certificate-unpinning-fallback.js \
|
||||||
-l ./android/android-disable-root-detection.js \
|
-l ./android/android-disable-root-detection.js \
|
||||||
-l ./android/android-disable-flutter-certificate-pinning.js \
|
-l ./android/android-disable-flutter-certificate-pinning.js \
|
||||||
-f $1
|
-f $1
|
||||||
|
|
||||||
|
#-l ./native-tls-hook.js \
|
||||||
|
# This is broken with mitmproxy
|
||||||
|
@ -1,23 +1,10 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
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 &
|
bash /conf/docker-entrypoint.sh &
|
||||||
ANDROID_PID=$!
|
ANDROID_PID=$!
|
||||||
|
|
||||||
function check_dead() {
|
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
|
if ! ps -p $ANDROID_PID > /dev/null; then
|
||||||
echo "[ERROR] The android emulator died, exiting...";
|
echo "[ERROR] The android emulator died, exiting...";
|
||||||
exit 1;
|
exit 1;
|
||||||
|
2665
android/proxy_cache_thing/package-lock.json
generated
2665
android/proxy_cache_thing/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"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": []
|
|
||||||
}
|
|
@ -1,188 +0,0 @@
|
|||||||
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);
|
|
||||||
})();
|
|
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"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/**/*"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "tslint:latest"
|
|
||||||
}
|
|
@ -1,9 +1,8 @@
|
|||||||
FROM node:22.14.0
|
# docker run --entrypoint sh --rm -it -v ./certificates:/certs alpine/openssl /certs/gen.sh
|
||||||
|
|
||||||
RUN git clone https://github.com/httptoolkit/httptoolkit-server
|
FROM alpine/openssl
|
||||||
|
|
||||||
WORKDIR /httptoolkit-server
|
COPY gen_certs.sh /gen_certs.sh
|
||||||
RUN git checkout 490b1b6f5180ad634b60997778c5f96b2f62bf0b \
|
|
||||||
&& npm i && npm run build:src
|
|
||||||
|
|
||||||
CMD /httptoolkit-server/bin/run start -c /certificates
|
ENTRYPOINT sh /gen_certs.sh
|
||||||
|
# CMD sh
|
||||||
|
20
certgen/gen_certs.sh
Executable file
20
certgen/gen_certs.sh
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/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
|
@ -18,6 +18,7 @@ services:
|
|||||||
- /dev/kvm
|
- /dev/kvm
|
||||||
networks:
|
networks:
|
||||||
- rent_gen_android
|
- rent_gen_android
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
- 45456:45459 # This cannot change
|
- 45456:45459 # This cannot change
|
||||||
- 45457:45459 # This cannot change
|
- 45457:45459 # This cannot change
|
||||||
@ -25,6 +26,7 @@ services:
|
|||||||
- 3000:3000 # android server port
|
- 3000:3000 # android server port
|
||||||
- 3001:3001 # Notifications server
|
- 3001:3001 # Notifications server
|
||||||
- 5556:5556 # emulator grpc port
|
- 5556:5556 # emulator grpc port
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- $PWD/shared_buffer:/shared_buffer
|
- $PWD/shared_buffer:/shared_buffer
|
||||||
- $PWD/android/conf:/conf
|
- $PWD/android/conf:/conf
|
||||||
@ -38,18 +40,6 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- $PWD/certificates:/root/.mitmproxy
|
- $PWD/certificates:/root/.mitmproxy
|
||||||
container_name: mitmproxy
|
container_name: 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
|
|
||||||
ports:
|
|
||||||
- 9080:9080
|
|
||||||
http_server:
|
http_server:
|
||||||
build: ./http_server/
|
build: ./http_server/
|
||||||
container_name: http_server
|
container_name: http_server
|
||||||
|
Binary file not shown.
@ -49,12 +49,6 @@
|
|||||||
|
|
||||||
<div class="tab-section">
|
<div class="tab-section">
|
||||||
<div class="tab">
|
<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')">
|
<button class="tablinks" onclick="main.open_tab(event, 'logs-tab')">
|
||||||
Logs
|
Logs
|
||||||
</button>
|
</button>
|
||||||
@ -89,14 +83,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="tabcontent" id="controls-tab">
|
||||||
<form id="set_coords" onsubmit="main.coords_handler(event)">
|
<form id="set_coords" onsubmit="main.coords_handler(event)">
|
||||||
<label>
|
<label>
|
||||||
|
@ -63,9 +63,11 @@ app.get("/", async function (req, res) {
|
|||||||
//POST
|
//POST
|
||||||
app.use(express.text({limit: "100mb"}));
|
app.use(express.text({limit: "100mb"}));
|
||||||
|
|
||||||
app.post("/inspect_har", upload.none(), function (req, res) {
|
app.post("/inspect_har", upload.none(), async function (req, res) {
|
||||||
let body = req.body;
|
let body = req.body;
|
||||||
let har = body.har;
|
let har_req = await fetch("http://mitmproxy:9111/get_har")
|
||||||
|
let har = await har_req.text();
|
||||||
|
|
||||||
let private_data;
|
let private_data;
|
||||||
if (body.private_data)
|
if (body.private_data)
|
||||||
private_data = JSON.parse(body.private_data);
|
private_data = JSON.parse(body.private_data);
|
||||||
@ -74,6 +76,20 @@ app.post("/inspect_har", upload.none(), function (req, res) {
|
|||||||
res.send(build_html(har, private_data));
|
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.use(fileUpload());
|
||||||
app.post("/upload_apk", async function (req, res) {
|
app.post("/upload_apk", async function (req, res) {
|
||||||
if (!req.files || Object.keys(req.files).length === 0) {
|
if (!req.files || Object.keys(req.files).length === 0) {
|
||||||
|
679
http_server/code/package-lock.json
generated
679
http_server/code/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -16,6 +16,7 @@ import {
|
|||||||
open_ports,
|
open_ports,
|
||||||
app_id_select,
|
app_id_select,
|
||||||
launch_app_form,
|
launch_app_form,
|
||||||
|
sleep,
|
||||||
} from "./shared";
|
} from "./shared";
|
||||||
|
|
||||||
import { start_notifications } from "./notifications";
|
import { start_notifications } from "./notifications";
|
||||||
@ -265,10 +266,6 @@ window.addEventListener("keydown", (event) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export async function sleep(time: number) {
|
|
||||||
return new Promise((resolve) => setTimeout(resolve, time));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function screenshot_loop() {
|
async function screenshot_loop() {
|
||||||
var before;
|
var before;
|
||||||
|
|
||||||
@ -294,4 +291,4 @@ installed_apps_loop();
|
|||||||
open_ports_loop();
|
open_ports_loop();
|
||||||
screenshot_loop();
|
screenshot_loop();
|
||||||
start_notifications();
|
start_notifications();
|
||||||
// start_traffic_log();
|
start_traffic_log();
|
||||||
|
@ -18,3 +18,8 @@ export const app_id_select = document.getElementById("app_id_select")!;
|
|||||||
export const launch_app_form = document.getElementById("launch_app_form")!;
|
export const launch_app_form = document.getElementById("launch_app_form")!;
|
||||||
|
|
||||||
export const socket = io();
|
export const socket = io();
|
||||||
|
|
||||||
|
export async function sleep(time: number) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, time));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,41 +1,38 @@
|
|||||||
import { Entry, Har, PostData, Request, Response } from "har-format";
|
|
||||||
import {
|
import {
|
||||||
adid_priv_info_table,
|
adid_priv_info_table,
|
||||||
lat_priv_info_table,
|
lat_priv_info_table,
|
||||||
lon_priv_info_table,
|
lon_priv_info_table,
|
||||||
|
sleep,
|
||||||
} from "./shared";
|
} from "./shared";
|
||||||
|
|
||||||
// Request + responce pairs: 0
|
// Request + responce pairs: 0
|
||||||
const req_res_pairs = document.getElementById("traffic-log-req-res-pairs")!;
|
const req_res_pairs = document.getElementById("traffic-log-req-res-pairs")!;
|
||||||
|
|
||||||
// Waiting for the responce: 0
|
export async function start_traffic_log() {
|
||||||
const waiting = document.getElementById("traffic-log-waiting")!;
|
|
||||||
|
|
||||||
const traffic_log_lines = document.getElementById("traffic-log-lines")!;
|
var before;
|
||||||
|
|
||||||
const inspect_har_form: HTMLFormElement = document.getElementById(
|
while (true) {
|
||||||
"inspect-har-form"
|
before = performance.now();
|
||||||
)! as HTMLFormElement;
|
let connections = "UNKNOWN";
|
||||||
|
try {
|
||||||
|
let req = await fetch("/get_intercept_stats");
|
||||||
|
|
||||||
const connection = new WebSocket("ws://localhost:10001");
|
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 unfinished_entries: Map<string, Entry> = new Map();
|
while (performance.now() - before < 1000) await sleep(500);
|
||||||
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 function download_har() {
|
export async function download_har() {
|
||||||
var tempLink = document.createElement("a");
|
var tempLink = document.createElement("a");
|
||||||
var taBlob = new Blob([JSON.stringify(export_har())], {
|
let res = await fetch("/download_har");
|
||||||
|
let res_text = await res.text()
|
||||||
|
var taBlob = new Blob([res_text], {
|
||||||
type: "text/plain",
|
type: "text/plain",
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -69,8 +66,6 @@ function launch_window_with_post(url: string, data: any) {
|
|||||||
|
|
||||||
export async function inspect_har() {
|
export async function inspect_har() {
|
||||||
let data = {
|
let data = {
|
||||||
har: JSON.stringify(export_har()),
|
|
||||||
|
|
||||||
private_data: JSON.stringify([
|
private_data: JSON.stringify([
|
||||||
{desc: "adid", data: adid_priv_info_table.textContent},
|
{desc: "adid", data: adid_priv_info_table.textContent},
|
||||||
{desc: "latitude", data: lat_priv_info_table.textContent },
|
{desc: "latitude", data: lat_priv_info_table.textContent },
|
||||||
@ -81,144 +76,5 @@ export async function inspect_har() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function update_stats() {
|
function update_stats() {
|
||||||
req_res_pairs.innerText = `Request + responce pairs: ${finished_entries.length}`;
|
// waiting.innerText = `Waiting for the responce: ${unfinished_entries.size}`;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int main () {
|
|
||||||
printf("%p", realloc(0, 10));
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
<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>
|
|
@ -1,23 +0,0 @@
|
|||||||
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
|
|
@ -3,6 +3,10 @@ FROM mitmproxy/mitmproxy
|
|||||||
USER root
|
USER root
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
|
|
||||||
# CMD bash -c 'echo hello from mitmproxy && mitmdump -w /root/.mitmproxy/dump --set mode="socks5@0.0.0.0:1080"'
|
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
||||||
cmd sleep 1000000000
|
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"
|
#--set mode="regular@0.0.0.0:8000"
|
||||||
|
6
mitmproxy/docker-entrypoint.sh
Executable file
6
mitmproxy/docker-entrypoint.sh
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
cd /root
|
||||||
|
script -c 'mitmdump -s /stats.py --set mode=regular@0.0.0.0:1080 -v'
|
81
mitmproxy/stats.py
Normal file
81
mitmproxy/stats.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
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()]
|
33
start.mjs
33
start.mjs
@ -5,10 +5,14 @@ async function sleep(time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function checkCertExistance() {
|
async function checkCertExistance() {
|
||||||
return await Promise.all([
|
try {
|
||||||
fs.access("./certificates/ca.key"),
|
return await Promise.all([
|
||||||
fs.access("./certificates/ca.pem", fs.constants.R_OK),
|
fs.access("./certificates/mitmproxy-ca-cert.pem"),
|
||||||
]);
|
fs.access("./certificates/mitmproxy-ca.pem", fs.constants.R_OK),
|
||||||
|
]);
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function generateCert() {
|
async function generateCert() {
|
||||||
@ -22,23 +26,12 @@ async function generateCert() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await $`docker build --tag certgen $PWD/certgen`
|
await $`docker build --tag certgen $PWD/certgen`;
|
||||||
// iniciate docker which will create certs
|
// generate certs
|
||||||
$`docker run --rm -v $PWD/certificates:/certificates --name certGenerator certgen &`;
|
await $`docker run --rm -v $PWD/certificates:/certificates --name certGenerator certgen`;
|
||||||
|
|
||||||
//wait for certs to generate
|
// clean up
|
||||||
let generated = false;
|
await $`docker rmi certgen`;
|
||||||
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() {
|
async function generatePreAndroid() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user