added gui
Reviewers: #testers, kuba-orlik Reviewed By: #testers, kuba-orlik Subscribers: kuba-orlik Maniphest Tasks: T2741 Differential Revision: https://hub.sealcode.org/D1354
This commit is contained in:
parent
c8fddb7987
commit
1ea7b42e29
3
.gitignore
vendored
3
.gitignore
vendored
@ -4,3 +4,6 @@ TODO
|
||||
certificates
|
||||
images
|
||||
*.png
|
||||
bundleTrafficLog.js
|
||||
/http_server/code/dist/
|
||||
log
|
25
README.md
25
README.md
@ -1,10 +1,27 @@
|
||||
# RENTGEN ANDROID
|
||||
|
||||
## INTRODUCTION
|
||||
|
||||
The aim of this project is to be able to visualize all the data that a given android app ~~steals~~ sends to third parties.
|
||||
|
||||
We are currently in v1, the environment, which is made up of a mitmproxy machine, a http server and an ubuntu machine with android emulator was created using docker, and all the tcp traffic from the android machine is redirected through the proxy. In future versions the [rentgen](https://github.com/internet-czas-dzialac/rentgen) firefox extension will be adapted to interpret the traffic from the proxy and display it in a user-friendly way.
|
||||
We are currently in v1, the environment, which is made up of a mitmproxy
|
||||
machine, a http server and an ubuntu machine with android emulator was created
|
||||
using docker, and all the tcp traffic from the android machine is redirected
|
||||
through the proxy. In future versions the
|
||||
[rentgen](https://github.com/internet-czas-dzialac/rentgen) firefox extension
|
||||
will be adapted to interpret the traffic from the proxy and display it in a
|
||||
user-friendly way.
|
||||
|
||||
## COMMANDS
|
||||
To get started, run `npm install` and `npx zx start.mjs up`
|
||||
And then, to check the proxy's logs you can do `docker exec -it proxy tail -f /log` and to go into the android `docker exec -it android bash`.
|
||||
To see the android screen, go to localhost:8080 in a browser. The endpoint takes a while to be enabled (because the tls certificate has to install in the android), but it will show in the output of `npx zx start.mjs up` whenever it is. To execute touch events, run a post request with query params x and y for the coordinates where the touch will happen (the screen size is 320x640). The way to do it with curl would be `curl -X POST "localhost:8080?x=$coordinate_x&y=$coordinate_y"`.
|
||||
|
||||
To get started, run `npm install` and `npm start`
|
||||
|
||||
If you get a time out after "Waiting for full boot..." your machine may be to slow to run the software comfortably, however, you can change the delay between screenshots in ./http_server/Dockerfile, changing "ENV screenshotDelayMs 1000" with as much time as you want to have between screenshots. The time is measured in miliseconds.
|
||||
|
||||
And then, to check the proxy's logs you can do `docker exec -it proxy tail -f
|
||||
/log` and to go into the android `docker exec -it android bash`.
|
||||
|
||||
To control the android device, go to localhost:8080 in a browser. The endpoint
|
||||
takes a while to be enabled (because the tls certificate has to install in the
|
||||
android), but it will show in the output of `npm start` whenever it
|
||||
is.
|
||||
|
@ -4,20 +4,36 @@ const fs = require("fs");
|
||||
|
||||
const server = net.createServer();
|
||||
|
||||
async function spawnPromise(program, args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const process = child_process.spawn(program, args);
|
||||
process.on("close", (_) => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//maybe check output of child processe and send errors in some way
|
||||
server.on("connection", (socket) => {
|
||||
socket.on("data", async (dataBuf) => {
|
||||
data = dataBuf.toString();
|
||||
if (data === "screenshot") {
|
||||
socket.write("start");
|
||||
child_process.spawnSync("bash", ["/conf/screenshot.sh"]);
|
||||
await spawnPromise("bash", ["/conf/screenshot.sh"]);
|
||||
socket.write(fs.readFileSync("/screenshot.png"));
|
||||
socket.write("ENDOFMSG");
|
||||
} else if (data.includes("touch")) {
|
||||
dataSplit = data.split(" ");
|
||||
child_process.spawnSync("bash", ["/conf/touch.sh", dataSplit[1], dataSplit[2]]);
|
||||
await spawnPromise("bash", [
|
||||
"/conf/touch.sh",
|
||||
dataSplit[1],
|
||||
dataSplit[2],
|
||||
]);
|
||||
}
|
||||
});
|
||||
socket.on("close", (_) => {
|
||||
socket.end();
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(3000, () => {
|
||||
|
@ -6,6 +6,7 @@ bash /conf/iptables_conf.sh
|
||||
redsocks -c /conf/redsocks.conf &
|
||||
emulator -avd virtual_dev -writable-system -no-window -no-audio &
|
||||
bash /conf/install_cert.sh $hashed_name.0
|
||||
bash /conf/wait_for_sd.sh
|
||||
#wait for cert to be installed before launching socket server
|
||||
node /code/index.js
|
||||
|
||||
|
@ -11,11 +11,13 @@ wait-for-offline
|
||||
adb wait-for-device
|
||||
adb shell avbctl disable-verification
|
||||
|
||||
#here may be the issue with the bypass (start)
|
||||
adb wait-for-device
|
||||
adb reboot
|
||||
|
||||
adb wait-for-device
|
||||
adb root
|
||||
#(end)
|
||||
|
||||
wait-for-offline
|
||||
adb wait-for-device
|
||||
|
5
android/conf/wait_for_sd.sh
Normal file
5
android/conf/wait_for_sd.sh
Normal file
@ -0,0 +1,5 @@
|
||||
/opt/android-sdk-linux/platform-tools/adb shell screencap /sdcard/screenshot.png 2> /dev/null
|
||||
while [ "$?" != 0 ]; do
|
||||
sleep 0.5
|
||||
/opt/android-sdk-linux/platform-tools/adb shell screencap /sdcard/screenshot.png 2> /dev/null
|
||||
done
|
@ -51,6 +51,7 @@ RENTGEN_ANDROID docker structure
|
||||
| :8080 |
|
||||
+---------------------------------+--------------------+
|
||||
|
|
||||
| HTTP: - GET /: screenshot
|
||||
| - POST /: touch, query params x, y indicate position
|
||||
| HTTP: - GET /: gui
|
||||
| - GET /screen: screenshot
|
||||
| - POST /touch: touch, body params x, y indicate position
|
||||
|
|
||||
|
@ -6,6 +6,7 @@ services:
|
||||
- rent_gen_android
|
||||
volumes:
|
||||
- $PWD/certificates:/root/.mitmproxy
|
||||
- $PWD/log:/log
|
||||
android:
|
||||
build: ./android/
|
||||
container_name: android
|
||||
@ -28,6 +29,7 @@ services:
|
||||
- rent_gen_android
|
||||
volumes:
|
||||
- $PWD/http_server/code:/code
|
||||
- $PWD/log:/log
|
||||
ports:
|
||||
- 8080:8080
|
||||
|
||||
|
@ -2,6 +2,10 @@ FROM alpine:3.18.2
|
||||
|
||||
RUN apk add npm
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
RUN mkdir /images
|
||||
|
||||
ENV screenshotDelayMs 1000
|
||||
|
||||
CMD sh /code/docker-entrypoint.sh
|
@ -1,7 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
npm i -C /code
|
||||
node /code/waitSocket.mjs
|
||||
node /code/index.js
|
||||
npm i
|
||||
npm run build
|
||||
node waitSocket.mjs
|
||||
node index.mjs
|
||||
|
||||
#tail -f /dev/null
|
BIN
http_server/code/favicon.ico
Normal file
BIN
http_server/code/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
86
http_server/code/index.html
Normal file
86
http_server/code/index.html
Normal file
@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Rentgen android</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<img id="screen" src="" style="display: inline-block" />
|
||||
<p
|
||||
id="clicks-log"
|
||||
style="
|
||||
height: 600px;
|
||||
width: 300px;
|
||||
overflow-y: auto;
|
||||
display: inline-block;
|
||||
margin-left: 20px;
|
||||
"
|
||||
></p>
|
||||
<p
|
||||
id="traffic-log"
|
||||
style="
|
||||
height: 600px;
|
||||
width: 500px;
|
||||
overflow-y: auto;
|
||||
display: inline-block;
|
||||
margin-left: 20px;
|
||||
"
|
||||
></p>
|
||||
</div>
|
||||
<script>
|
||||
var screen = document.getElementById("screen");
|
||||
var clicksLog = document.getElementById("clicks-log");
|
||||
|
||||
async function displayImage() {
|
||||
try {
|
||||
const response = await fetch("screen");
|
||||
const blob = await response.blob();
|
||||
screen.src = URL.createObjectURL(blob);
|
||||
} catch (error) {
|
||||
console.error("Error fetching image: ", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleTouchEvent(event) {
|
||||
var phoneX = event.offsetX;
|
||||
var phoneY = event.offsetY;
|
||||
if (
|
||||
phoneX <= 320 &&
|
||||
phoneX >= 0 &&
|
||||
phoneY <= 640 &&
|
||||
phoneY >= 0
|
||||
) {
|
||||
clicksLog.innerText += `await click(${phoneX}, ${phoneY});\n`;
|
||||
await fetch("touch", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: `x=${phoneX}&y=${phoneY}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function sleep(time) {
|
||||
return new Promise((resolve) => setTimeout(resolve, time));
|
||||
}
|
||||
|
||||
async function screenshot_loop() {
|
||||
var before;
|
||||
|
||||
while (true) {
|
||||
before = performance.now();
|
||||
await displayImage();
|
||||
while (performance.now() - before < ___screenshotDelayMs___)
|
||||
await sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
screen.addEventListener("click", handleTouchEvent);
|
||||
|
||||
screenshot_loop();
|
||||
</script>
|
||||
<script src="/trafficLog.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,50 +0,0 @@
|
||||
const express = require("express");
|
||||
const net = require("net");
|
||||
const fs = require("fs");
|
||||
|
||||
const device_size_x = 320;
|
||||
const device_size_y = 640;
|
||||
|
||||
const app = express();
|
||||
const socket_client = net.createConnection({ port: 3000, host: "android" });
|
||||
|
||||
async function sleep(time) {
|
||||
return new Promise((resolve) => setTimeout(resolve, time));
|
||||
}
|
||||
|
||||
let doneWrite = 0;
|
||||
let fd;
|
||||
socket_client.on("data", (dataBuf) => {
|
||||
if (dataBuf.toString() === "start")
|
||||
fd = fs.openSync("/code/screenshot.png", "w");
|
||||
else {
|
||||
if (dataBuf.toString().includes("ENDOFMSG")) {
|
||||
fs.writeSync(fd, dataBuf);
|
||||
fs.close(fd);
|
||||
doneWrite = 1;
|
||||
} else fs.writeSync(fd, dataBuf);
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/", async function (req, res) {
|
||||
socket_client.write("screenshot");
|
||||
while (!doneWrite) await sleep(15);
|
||||
res.sendFile("/code/screenshot.png");
|
||||
doneWrite = 0;
|
||||
});
|
||||
|
||||
app.post("/", function (req, res) {
|
||||
const x = parseInt(req.query.x);
|
||||
const y = parseInt(req.query.y);
|
||||
|
||||
if (isNaN(x) || isNaN(y) || x > device_size_x || y > device_size_y) {
|
||||
res.send(
|
||||
`the query params must be x <= ${device_size_x}, y <= ${device_size_y}\n`
|
||||
);
|
||||
} else {
|
||||
socket_client.write(`touch ${x} ${y}`);
|
||||
res.sendStatus(200);
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(8080, () => console.log("Listening in port 8080"));
|
114
http_server/code/index.mjs
Normal file
114
http_server/code/index.mjs
Normal file
@ -0,0 +1,114 @@
|
||||
import express from "express";
|
||||
import net from "net";
|
||||
import fs from "fs";
|
||||
import { readFile } from "node:fs/promises";
|
||||
|
||||
const device_size_x = 320;
|
||||
const device_size_y = 640;
|
||||
|
||||
const app = express();
|
||||
app.use(express.urlencoded({ extended: false }));
|
||||
const socket_client = net.createConnection({ port: 3000, host: "android" });
|
||||
|
||||
async function sleep(time) {
|
||||
return new Promise((resolve) => setTimeout(resolve, time));
|
||||
}
|
||||
|
||||
let doneWrite = 0;
|
||||
let screenshotPromise = null;
|
||||
|
||||
async function screenshot() {
|
||||
socket_client.write("screenshot");
|
||||
while (!doneWrite) await sleep(15);
|
||||
doneWrite = 0;
|
||||
screenshotPromise = null;
|
||||
}
|
||||
|
||||
async function guardedScreenshot() {
|
||||
if (!screenshotPromise) {
|
||||
screenshotPromise = screenshot();
|
||||
}
|
||||
return screenshotPromise;
|
||||
}
|
||||
|
||||
async function waitFullBoot() {
|
||||
var start = performance.now();
|
||||
var counter = 0;
|
||||
|
||||
//will timeout after 10 min
|
||||
while (performance.now() - start < 600 * 1000) {
|
||||
var before = performance.now();
|
||||
await screenshot();
|
||||
var after = performance.now();
|
||||
if (after - before < process.env.screenshotDelayMs) counter++;
|
||||
else counter = 0;
|
||||
|
||||
if (counter === 10) return;
|
||||
}
|
||||
|
||||
throw new Error("wait for screenshot time to be less than 0.5s timed out");
|
||||
}
|
||||
|
||||
let fd;
|
||||
socket_client.on("data", (dataBuf) => {
|
||||
if (dataBuf.toString() === "start")
|
||||
fd = fs.openSync("/code/screenshot.png", "w");
|
||||
else {
|
||||
if (dataBuf.toString().includes("ENDOFMSG")) {
|
||||
fs.writeSync(fd, dataBuf);
|
||||
fs.close(fd);
|
||||
doneWrite = 1;
|
||||
} else fs.writeSync(fd, dataBuf);
|
||||
}
|
||||
});
|
||||
|
||||
console.log("Waiting for full boot...");
|
||||
await waitFullBoot();
|
||||
console.log("Boot detected! activating endpoints");
|
||||
|
||||
app.get("/screen", async function (req, res) {
|
||||
await guardedScreenshot();
|
||||
res.sendFile("/code/screenshot.png");
|
||||
});
|
||||
|
||||
app.get("/favicon.ico", function (req, res) {
|
||||
res.sendFile("/code/favicon.ico");
|
||||
});
|
||||
|
||||
app.get("/trafficLog.js", function (req, res) {
|
||||
res.sendFile("/code/dist/trafficLog.js");
|
||||
});
|
||||
|
||||
app.get("/trafficLog", async function (req, res) {
|
||||
res.sendFile("/log/trafficLog");
|
||||
});
|
||||
|
||||
app.post("/touch", function (req, res) {
|
||||
const x = parseInt(req.body.x);
|
||||
const y = parseInt(req.body.y);
|
||||
|
||||
if (isNaN(x) || isNaN(y) || x > device_size_x || y > device_size_y) {
|
||||
res.send(
|
||||
`the query params must be x <= ${device_size_x}, y <= ${device_size_y}\n`
|
||||
);
|
||||
} else {
|
||||
socket_client.write(`touch ${x} ${y}`);
|
||||
res.sendStatus(200);
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/", async function (req, res) {
|
||||
let fileData = (await readFile("/code/index.html")).toString();
|
||||
|
||||
fileData = fileData.replace(
|
||||
"___screenshotDelayMs___",
|
||||
process.env.screenshotDelayMs
|
||||
);
|
||||
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
res.setHeader("Content-Disposition", "inline");
|
||||
|
||||
res.send(fileData);
|
||||
});
|
||||
|
||||
app.listen(8080, () => console.log("Listening in port 8080"));
|
404
http_server/code/package-lock.json
generated
404
http_server/code/package-lock.json
generated
@ -6,7 +6,363 @@
|
||||
"": {
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"net": "^1.0.2"
|
||||
"net": "^1.0.2",
|
||||
"preact": "^10.18.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.19.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz",
|
||||
"integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz",
|
||||
"integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz",
|
||||
"integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz",
|
||||
"integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz",
|
||||
"integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz",
|
||||
"integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz",
|
||||
"integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz",
|
||||
"integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz",
|
||||
"integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz",
|
||||
"integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz",
|
||||
"integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz",
|
||||
"integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz",
|
||||
"integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz",
|
||||
"integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz",
|
||||
"integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz",
|
||||
"integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz",
|
||||
"integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz",
|
||||
"integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz",
|
||||
"integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz",
|
||||
"integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz",
|
||||
"integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz",
|
||||
"integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
@ -139,6 +495,43 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz",
|
||||
"integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/android-arm": "0.19.5",
|
||||
"@esbuild/android-arm64": "0.19.5",
|
||||
"@esbuild/android-x64": "0.19.5",
|
||||
"@esbuild/darwin-arm64": "0.19.5",
|
||||
"@esbuild/darwin-x64": "0.19.5",
|
||||
"@esbuild/freebsd-arm64": "0.19.5",
|
||||
"@esbuild/freebsd-x64": "0.19.5",
|
||||
"@esbuild/linux-arm": "0.19.5",
|
||||
"@esbuild/linux-arm64": "0.19.5",
|
||||
"@esbuild/linux-ia32": "0.19.5",
|
||||
"@esbuild/linux-loong64": "0.19.5",
|
||||
"@esbuild/linux-mips64el": "0.19.5",
|
||||
"@esbuild/linux-ppc64": "0.19.5",
|
||||
"@esbuild/linux-riscv64": "0.19.5",
|
||||
"@esbuild/linux-s390x": "0.19.5",
|
||||
"@esbuild/linux-x64": "0.19.5",
|
||||
"@esbuild/netbsd-x64": "0.19.5",
|
||||
"@esbuild/openbsd-x64": "0.19.5",
|
||||
"@esbuild/sunos-x64": "0.19.5",
|
||||
"@esbuild/win32-arm64": "0.19.5",
|
||||
"@esbuild/win32-ia32": "0.19.5",
|
||||
"@esbuild/win32-x64": "0.19.5"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
@ -418,6 +811,15 @@
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
||||
},
|
||||
"node_modules/preact": {
|
||||
"version": "10.18.1",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.18.1.tgz",
|
||||
"integrity": "sha512-mKUD7RRkQQM6s7Rkmi7IFkoEHjuFqRQUaXamO61E6Nn7vqF/bo7EZCmSyrUnp2UWHw0O7XjZ2eeXis+m7tf4lg==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/preact"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
@ -1,6 +1,13 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "esbuild --sourcemap --bundle src/trafficLog.jsx --outfile=dist/trafficLog.js --jsx-factory=h --jsx-fragment=Fragment"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"net": "^1.0.2"
|
||||
"net": "^1.0.2",
|
||||
"preact": "^10.18.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.19.5"
|
||||
}
|
||||
}
|
||||
|
38
http_server/code/src/trafficLog.jsx
Normal file
38
http_server/code/src/trafficLog.jsx
Normal file
@ -0,0 +1,38 @@
|
||||
import { h, render, Component } from "preact";
|
||||
|
||||
const refreshRate = 1000;
|
||||
|
||||
class TrafficLog extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = { content: "" };
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.intervalSetter = setInterval(async () => {
|
||||
var log = await (await fetch("trafficLog")).text();
|
||||
this.setState({ content: log });
|
||||
}, refreshRate);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.intervalSetter);
|
||||
}
|
||||
|
||||
render() {
|
||||
const contentWithLineBreaks = this.state.content
|
||||
.split("\n")
|
||||
.map((line, _) => {
|
||||
return (
|
||||
<span>
|
||||
{line}
|
||||
<br />
|
||||
</span>
|
||||
);
|
||||
});
|
||||
|
||||
return <span>{contentWithLineBreaks}</span>;
|
||||
}
|
||||
}
|
||||
|
||||
render(<TrafficLog />, document.getElementById("traffic-log"));
|
12
http_server/code/tsconfig.json
Normal file
12
http_server/code/tsconfig.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
"module": "commonjs" /* Specify what module code is generated. */,
|
||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */,
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "preact"
|
||||
}
|
||||
}
|
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "rentGenAndroid",
|
||||
"name": "rentgendroid",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
@ -1,4 +1,9 @@
|
||||
{
|
||||
"scripts": {
|
||||
"start": "zx start.mjs up",
|
||||
"stop": "zx start.mjs down"
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"zx": "^7.2.2"
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
FROM mitmproxy/mitmproxy:9.0.1
|
||||
|
||||
CMD mitmdump --mode socks5 > /log
|
||||
CMD mitmdump --mode socks5 > /log/trafficLog
|
Loading…
x
Reference in New Issue
Block a user