Rentgendroid: swap ssh in favor of sockets. Added arcanist conf

Reviewers: kuba-orlik

Reviewed By: kuba-orlik

Subscribers: kuba-orlik

Differential Revision: https://hub.sealcode.org/D1335
This commit is contained in:
migueldar 2023-08-31 20:32:14 +02:00
parent f4552bf244
commit 47a889c2d9
16 changed files with 181 additions and 60 deletions

4
.arcconfig Normal file
View File

@ -0,0 +1,4 @@
{
"phabricator.uri": "https://hub.sealcode.org/",
"arc.land.onto.default": "master"
}

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ node_modules
TODO
certificates
images
*.png

View File

@ -5,9 +5,8 @@ ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/andro
RUN sdkmanager "system-images;android-33;google_apis;x86_64"
RUN echo no | avdmanager create avd -n virtual_dev -b google_apis/x86_64 -k "system-images;android-33;google_apis;x86_64"
#remove iproute2 ping
RUN apt-get update && apt-get install -y iproute2 iputils-ping iptables redsocks openssh-server
RUN apt-get update && apt-get install -y iproute2 iputils-ping iptables redsocks npm
EXPOSE 22
EXPOSE 3000
CMD bash /conf/docker-entrypoint.sh

25
android/code/index.js Normal file
View File

@ -0,0 +1,25 @@
const net = require("net");
const child_process = require("child_process");
const fs = require("fs");
const server = net.createServer();
//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"]);
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]]);
}
});
});
server.listen(3000, () => {
console.log("listening on 3000");
});

24
android/code/package-lock.json generated Normal file
View File

@ -0,0 +1,24 @@
{
"name": "code",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"dependencies": {
"net": "^1.0.2"
}
},
"node_modules/net": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz",
"integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ=="
}
},
"dependencies": {
"net": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz",
"integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ=="
}
}
}

View File

@ -0,0 +1,5 @@
{
"dependencies": {
"net": "^1.0.2"
}
}

View File

@ -1,12 +1,12 @@
hashed_name=`openssl x509 -inform PEM -subject_hash_old -in /ca-cert.cer | head -1`
npm i -C /code
cp /ca-cert.cer /$hashed_name.0
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
#wait for cert to be installed before being able to connect through ssh
echo root:toor | chpasswd
bash /conf/sshd_config.sh
#wait for cert to be installed before launching socket server
node /code/index.js
tail -f /dev/null
#tail -f /dev/null

View File

@ -1,3 +0,0 @@
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
service ssh start

56
diagram.md Normal file
View File

@ -0,0 +1,56 @@
RENTGEN_ANDROID docker structure
// Arrows show direction of requests
INTERNET
/|\
|
|
+--------------------------+---------------------------+
| MITMPROXY | |
| | |
| | |
| | |
| | |
| | |
| :1080 |
+--------------------------+---------------------------+
|
| SOCKS 5
|
+--------------------------+---------------------------+
| ANDROID_CONTAINER :12345 |
| | |
| +------------------+--------------------+ |
| | ANDROID | | |
| | | | |
| | | |
| | | |
| | /|\ | |
| | | | |
| +-------------------------+-------------+ |
| | |
| | ADB SHELL |
| | |
| :3000 |
+---------------------------------+--------------------+
|
| SOCKETS
|
+---------------------------------+--------------------+
| HTTP_SERVER | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| :8080 |
+---------------------------------+--------------------+
|
| HTTP: - GET /: screenshot
| - POST /: touch, query params x, y indicate position
|

View File

@ -20,6 +20,7 @@ services:
volumes:
- $PWD/android/conf:/conf
- $PWD/certificates/mitmproxy-ca-cert.cer:/ca-cert.cer
- $PWD/android/code:/code
http_server:
build: ./http_server/
container_name: http_server

View File

@ -1,6 +1,6 @@
FROM alpine:3.18.2
RUN apk add npm openssh sshpass
RUN apk add npm
RUN mkdir /images

View File

@ -1,13 +1,7 @@
#!/bin/bash
npm i -C /code
mkdir /root/.ssh
#for ssh not asking us to add to known_hosts
ssh-keyscan -H android >> /root/.ssh/known_hosts
while [ $? != 0 ]; do
sleep 2
ssh-keyscan -H android >> /root/.ssh/known_hosts
done
node /code/waitSocket.mjs
node /code/index.js
#tail -f /dev/null

View File

@ -1,34 +1,36 @@
const express = require("express");
const child_process = require("child_process");
const net = require("net");
const fs = require("fs");
const device_size_x = 320;
const device_size_y = 640;
let app = express();
const app = express();
const socket_client = net.createConnection({ port: 3000, host: "android" });
app.get("/", function (req, res) {
const screenshot_cmd_res = child_process.spawnSync("sshpass", [
"-p",
"toor",
"ssh",
"android",
"bash",
"/conf/screenshot.sh",
]);
if (screenshot_cmd_res.status === 0) {
const scp_cmd_res = child_process.spawnSync("sshpass", [
"-p",
"toor",
"scp",
"android:/screenshot.png",
"/images/screenshot.png",
]);
if (scp_cmd_res.status === 0) {
res.sendFile("/images/screenshot.png");
return;
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);
}
res.send("Screenshot event didnt happen\n");
});
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) {
@ -40,19 +42,9 @@ app.post("/", function (req, res) {
`the query params must be x <= ${device_size_x}, y <= ${device_size_y}\n`
);
} else {
const cmd_res = child_process.spawnSync("sshpass", [
"-p",
"toor",
"ssh",
"android",
"bash",
"/conf/touch.sh",
x,
y,
]);
if (cmd_res.status === 0) res.sendStatus(200);
else res.send("Touch event didnt happen\n");
socket_client.write(`touch ${x} ${y}`);
res.sendStatus(200);
}
});
app.listen(8080, () => console.log("Listening in port 8080\n"));
app.listen(8080, () => console.log("Listening in port 8080"));

View File

@ -5,7 +5,8 @@
"packages": {
"": {
"dependencies": {
"express": "^4.18.2"
"express": "^4.18.2",
"net": "^1.0.2"
}
},
"node_modules/accepts": {
@ -380,6 +381,11 @@
"node": ">= 0.6"
}
},
"node_modules/net": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz",
"integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ=="
},
"node_modules/object-inspect": {
"version": "1.12.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",

View File

@ -1,5 +1,6 @@
{
"dependencies": {
"express": "^4.18.2"
"express": "^4.18.2",
"net": "^1.0.2"
}
}

View File

@ -0,0 +1,16 @@
import net from "net";
import { exit } from "process";
async function sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
while (true) {
let socket = net.createConnection({ port: 3000, host: "android" });
socket.on("connect", () => {
exit(0);
});
socket.on("error", () => {});
await sleep(200);
}