@shriyanss/js-recon 1.0.0 → 1.1.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/build-and-prettify.yaml +65 -0
- package/.github/workflows/npm-publish.yml +35 -0
- package/.prettierignore +2 -0
- package/.prettierrc +4 -0
- package/CHANGELOG.md +50 -0
- package/README.md +35 -139
- package/build/api_gateway/checkFeasibility.js +32 -0
- package/build/api_gateway/checkFeasibility.js.map +1 -0
- package/build/api_gateway/checkFireWallBlocking.js +24 -0
- package/build/api_gateway/checkFireWallBlocking.js.map +1 -0
- package/build/api_gateway/genReq.js +199 -0
- package/build/api_gateway/genReq.js.map +1 -0
- package/build/api_gateway/index.js +275 -0
- package/build/api_gateway/index.js.map +1 -0
- package/build/endpoints/gen_report/gen_json.js +22 -0
- package/build/endpoints/gen_report/gen_json.js.map +1 -0
- package/build/endpoints/gen_report/gen_markdown.js +66 -0
- package/build/endpoints/gen_report/gen_markdown.js.map +1 -0
- package/build/endpoints/gen_report/utility/iterate_n_store.js +46 -0
- package/build/endpoints/gen_report/utility/iterate_n_store.js.map +1 -0
- package/build/endpoints/index.js +89 -0
- package/build/endpoints/index.js.map +1 -0
- package/build/endpoints/next_js/client_jsFilesHref.js +91 -0
- package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -0
- package/build/endpoints/next_js/client_jsonParse.js +78 -0
- package/build/endpoints/next_js/client_jsonParse.js.map +1 -0
- package/build/endpoints/next_js/client_subsequentRequests.js +199 -0
- package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -0
- package/build/endpoints/next_js/getWebpacks.js +45 -0
- package/build/endpoints/next_js/getWebpacks.js.map +1 -0
- package/build/globalConfig.js +11 -0
- package/build/globalConfig.js.map +1 -0
- package/build/index.js +166 -0
- package/build/index.js.map +1 -0
- package/build/lazyLoad/downloadFilesUtil.js +128 -0
- package/build/lazyLoad/downloadFilesUtil.js.map +1 -0
- package/build/lazyLoad/downloadLoadedJsUtil.js +51 -0
- package/build/lazyLoad/downloadLoadedJsUtil.js.map +1 -0
- package/build/lazyLoad/globals.js +22 -0
- package/build/lazyLoad/globals.js.map +1 -0
- package/build/lazyLoad/index.js +170 -0
- package/build/lazyLoad/index.js.map +1 -0
- package/build/lazyLoad/next_js/next_GetJSScript.js +94 -0
- package/build/lazyLoad/next_js/next_GetJSScript.js.map +1 -0
- package/build/lazyLoad/next_js/next_GetLazyResources.js +202 -0
- package/build/lazyLoad/next_js/next_GetLazyResources.js.map +1 -0
- package/build/lazyLoad/next_js/next_SubsequentRequests.js +120 -0
- package/build/lazyLoad/next_js/next_SubsequentRequests.js.map +1 -0
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js +188 -0
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -0
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +75 -0
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -0
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +94 -0
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -0
- package/build/lazyLoad/svelte/svelte_getFromPageSource.js +68 -0
- package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -0
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +95 -0
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -0
- package/build/map/index.js +58 -0
- package/build/map/index.js.map +1 -0
- package/build/map/next_js/getFetchInstances.js +108 -0
- package/build/map/next_js/getFetchInstances.js.map +1 -0
- package/build/map/next_js/getWebpackConnections.js +227 -0
- package/build/map/next_js/getWebpackConnections.js.map +1 -0
- package/build/map/next_js/interactive.js +32 -0
- package/build/map/next_js/interactive.js.map +1 -0
- package/build/map/next_js/interactive_helpers/commandHandler.js +190 -0
- package/build/map/next_js/interactive_helpers/commandHandler.js.map +1 -0
- package/build/map/next_js/interactive_helpers/commandHelpers.js +91 -0
- package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -0
- package/build/map/next_js/interactive_helpers/helpMenu.js +11 -0
- package/build/map/next_js/interactive_helpers/helpMenu.js.map +1 -0
- package/build/map/next_js/interactive_helpers/keybindings.js +80 -0
- package/build/map/next_js/interactive_helpers/keybindings.js.map +1 -0
- package/build/map/next_js/interactive_helpers/printer.js +17 -0
- package/build/map/next_js/interactive_helpers/printer.js.map +1 -0
- package/build/map/next_js/interactive_helpers/ui.js +81 -0
- package/build/map/next_js/interactive_helpers/ui.js.map +1 -0
- package/build/map/next_js/resolveFetch.js +201 -0
- package/build/map/next_js/resolveFetch.js.map +1 -0
- package/build/run/index.js +62 -0
- package/build/run/index.js.map +1 -0
- package/build/strings/index.js +238 -0
- package/build/strings/index.js.map +1 -0
- package/build/strings/openapi.js +55 -0
- package/build/strings/openapi.js.map +1 -0
- package/build/strings/permutate.js +55 -0
- package/build/strings/permutate.js.map +1 -0
- package/build/strings/secrets.js +89 -0
- package/build/strings/secrets.js.map +1 -0
- package/build/techDetect/index.js +229 -0
- package/build/techDetect/index.js.map +1 -0
- package/build/utility/ai.js +69 -0
- package/build/utility/ai.js.map +1 -0
- package/build/utility/globals.js +84 -0
- package/build/utility/globals.js.map +1 -0
- package/build/utility/interfaces.js +2 -0
- package/build/utility/interfaces.js.map +1 -0
- package/build/utility/makeReq.js +265 -0
- package/build/utility/makeReq.js.map +1 -0
- package/build/utility/resolvePath.js +44 -0
- package/build/utility/resolvePath.js.map +1 -0
- package/{utility → build/utility}/runSandboxed.js +10 -13
- package/build/utility/runSandboxed.js.map +1 -0
- package/{utility → build/utility}/urlUtils.js +9 -11
- package/build/utility/urlUtils.js.map +1 -0
- package/docs/CNAME +1 -0
- package/docs/README.md +20 -0
- package/docs/api-gateway.md +68 -0
- package/docs/endpoints.md +49 -0
- package/docs/example-scenario.md +258 -0
- package/docs/interactive-mode.md +76 -0
- package/docs/lazyload.md +56 -0
- package/docs/map.md +53 -0
- package/docs/run.md +54 -0
- package/docs/strings.md +75 -0
- package/package.json +50 -38
- package/api_gateway/checkFeasibility.js +0 -25
- package/api_gateway/checkFireWallBlocking.js +0 -17
- package/api_gateway/genReq.js +0 -214
- package/api_gateway/index.js +0 -325
- package/endpoints/index.js +0 -7
- package/globalConfig.js +0 -12
- package/index.js +0 -69
- package/lazyLoad/downloadFilesUtil.js +0 -122
- package/lazyLoad/downloadLoadedJsUtil.js +0 -54
- package/lazyLoad/globals.js +0 -15
- package/lazyLoad/index.js +0 -167
- package/lazyLoad/next_js/next_GetJSScript.js +0 -99
- package/lazyLoad/next_js/next_GetLazyResources.js +0 -201
- package/lazyLoad/next_js/next_SubsequentRequests.js +0 -138
- package/lazyLoad/nuxt_js/nuxt_astParse.js +0 -194
- package/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +0 -77
- package/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +0 -99
- package/research/firewall_bypass.md +0 -38
- package/research/next_js.md +0 -116
- package/research/nuxt_js.md +0 -125
- package/research/vue_js.md +0 -9
- package/strings/index.js +0 -145
- package/techDetect/index.js +0 -156
- package/utility/globals.js +0 -6
- package/utility/makeReq.js +0 -179
- package/utility/resolvePath.js +0 -43
package/package.json
CHANGED
|
@@ -1,40 +1,52 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
2
|
+
"name": "@shriyanss/js-recon",
|
|
3
|
+
"version": "1.1.0-beta.2",
|
|
4
|
+
"description": "JS Recon Tool",
|
|
5
|
+
"main": "build/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"js-recon": "build/index.js"
|
|
9
|
+
},
|
|
10
|
+
"types": "build/index.d.ts",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "rm -rf build/ && tsc",
|
|
13
|
+
"start": "node build/index.js",
|
|
14
|
+
"test": "node build/index.js -h"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"author": "Shriyans Sudhi",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@aws-sdk/client-api-gateway": "^3.829.0",
|
|
21
|
+
"@babel/parser": "^7.27.4",
|
|
22
|
+
"@babel/traverse": "^7.27.4",
|
|
23
|
+
"@babel/types": "^7.27.6",
|
|
24
|
+
"@types/chalk": "^0.4.31",
|
|
25
|
+
"blessed": "^0.1.81",
|
|
26
|
+
"chalk": "^5.4.1",
|
|
27
|
+
"cheerio": "^1.0.0",
|
|
28
|
+
"cli-highlight": "^2.1.11",
|
|
29
|
+
"commander": "^14.0.0",
|
|
30
|
+
"fs": "^0.0.2",
|
|
31
|
+
"inquirer": "^12.6.3",
|
|
32
|
+
"md5": "^2.3.0",
|
|
33
|
+
"ollama": "^0.5.16",
|
|
34
|
+
"openai": "^5.8.2",
|
|
35
|
+
"path": "^0.12.7",
|
|
36
|
+
"prettier": "^3.5.3",
|
|
37
|
+
"puppeteer": "^24.11.2",
|
|
38
|
+
"ses": "^1.13.0"
|
|
39
|
+
},
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/shriyanss/js-recon.git"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/shriyanss/js-recon/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/shriyanss/js-recon#readme",
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"ts-node": "^10.9.2",
|
|
50
|
+
"tsconfig-paths": "^4.2.0"
|
|
51
|
+
}
|
|
40
52
|
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { get } from "./genReq.js";
|
|
2
|
-
import chalk from "chalk";
|
|
3
|
-
import checkFireWallBlocking from "./checkFireWallBlocking.js";
|
|
4
|
-
|
|
5
|
-
const checkFeasibility = async (url) => {
|
|
6
|
-
console.log(chalk.cyan(`[i] Checking feasibility of API Gateway with ${url}`));
|
|
7
|
-
try {
|
|
8
|
-
// send 10 requests, and check if any of those contain any signs of blocking
|
|
9
|
-
for (let i = 0; i < 10; i++) {
|
|
10
|
-
const response = await get(url);
|
|
11
|
-
const isFireWallBlocking = await checkFireWallBlocking(response);
|
|
12
|
-
if (isFireWallBlocking) {
|
|
13
|
-
console.log(chalk.magenta("[!] Please try again without API Gateway"));
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
console.log(chalk.green("[✓] Feasibility check passed."), chalk.dim("However, this doesn't represent the true nature of the firewall used."));
|
|
18
|
-
} catch (error) {
|
|
19
|
-
console.log(
|
|
20
|
-
chalk.red(`[!] An error occured in feasibility check: ${error}`),
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export default checkFeasibility;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
|
|
3
|
-
const checkFireWallBlocking = async (body) => {
|
|
4
|
-
|
|
5
|
-
// check common signs of CF first
|
|
6
|
-
if (body.includes("<title>Just a moment...</title>")) {
|
|
7
|
-
console.log(chalk.red("[!] Cloudflare detected"));
|
|
8
|
-
return true;
|
|
9
|
-
} else if (body.includes("<title>Attention Required! | Cloudflare</title>")) {
|
|
10
|
-
console.log(chalk.red("[!] Cloudflare detected"));
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return false;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export default checkFireWallBlocking;
|
package/api_gateway/genReq.js
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
APIGatewayClient,
|
|
3
|
-
CreateResourceCommand,
|
|
4
|
-
GetResourcesCommand,
|
|
5
|
-
PutMethodCommand,
|
|
6
|
-
PutIntegrationCommand,
|
|
7
|
-
// CreateDeploymentCommand,
|
|
8
|
-
// CreateStageCommand,
|
|
9
|
-
PutIntegrationResponseCommand,
|
|
10
|
-
PutMethodResponseCommand,
|
|
11
|
-
TestInvokeMethodCommand,
|
|
12
|
-
DeleteResourceCommand,
|
|
13
|
-
} from "@aws-sdk/client-api-gateway";
|
|
14
|
-
import fs from "fs";
|
|
15
|
-
import md5 from "md5";
|
|
16
|
-
import chalk from "chalk";
|
|
17
|
-
import * as globals from "../utility/globals.js";
|
|
18
|
-
import checkFireWallBlocking from "./checkFireWallBlocking.js";
|
|
19
|
-
|
|
20
|
-
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Given a URL, generates a new API Gateway for it and returns the response of the URL.
|
|
24
|
-
* @param {string} url The URL to generate an API Gateway for.
|
|
25
|
-
* @param {object} [headers] The headers to include in the request.
|
|
26
|
-
* @returns {Promise<string>} The response of the URL.
|
|
27
|
-
*/
|
|
28
|
-
const get = async (url, headers) => {
|
|
29
|
-
// read the config file
|
|
30
|
-
let config = JSON.parse(fs.readFileSync(globals.apiGatewayConfigFile));
|
|
31
|
-
// select a random api gateway
|
|
32
|
-
let apiGateway =
|
|
33
|
-
Object.keys(config)[Math.floor(Math.random() * Object.keys(config).length)];
|
|
34
|
-
|
|
35
|
-
const client = new APIGatewayClient({
|
|
36
|
-
region: config[apiGateway].region,
|
|
37
|
-
credentials: {
|
|
38
|
-
accessKeyId: config[apiGateway].access_key,
|
|
39
|
-
secretAccessKey: config[apiGateway].secret_key,
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// get the root resource id
|
|
44
|
-
const getResourceCommand = new GetResourcesCommand({
|
|
45
|
-
restApiId: config[apiGateway].id,
|
|
46
|
-
limit: 999999999,
|
|
47
|
-
});
|
|
48
|
-
const getResourceResponse = await client.send(getResourceCommand);
|
|
49
|
-
await sleep(200);
|
|
50
|
-
|
|
51
|
-
// before creating a resource, check if the resource already exists
|
|
52
|
-
const resourceExists = getResourceResponse.items.find(
|
|
53
|
-
(item) => item.pathPart === md5(url),
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
let newResourceResponse;
|
|
57
|
-
if (resourceExists) {
|
|
58
|
-
// console.log(chalk.yellow("[!] Resource already exists"));
|
|
59
|
-
newResourceResponse = {
|
|
60
|
-
id: resourceExists.id,
|
|
61
|
-
};
|
|
62
|
-
} else {
|
|
63
|
-
// create a new resource
|
|
64
|
-
let rootId;
|
|
65
|
-
if (getResourceResponse.items.find((item) => item.path === "/")) {
|
|
66
|
-
rootId = getResourceResponse.items.find((item) => item.path === "/").id;
|
|
67
|
-
} else {
|
|
68
|
-
rootId = getResourceResponse.items[0].parentId;
|
|
69
|
-
}
|
|
70
|
-
const newResourceCommand = new CreateResourceCommand({
|
|
71
|
-
restApiId: config[apiGateway].id,
|
|
72
|
-
parentId: rootId,
|
|
73
|
-
pathPart: md5(url), // md5 of the url
|
|
74
|
-
});
|
|
75
|
-
newResourceResponse = await client.send(newResourceCommand);
|
|
76
|
-
await sleep(200);
|
|
77
|
-
|
|
78
|
-
// add a new method
|
|
79
|
-
const newMethodCommand = new PutMethodCommand({
|
|
80
|
-
restApiId: config[apiGateway].id,
|
|
81
|
-
resourceId: newResourceResponse.id,
|
|
82
|
-
httpMethod: "GET",
|
|
83
|
-
authorizationType: "NONE",
|
|
84
|
-
requestParameters: {
|
|
85
|
-
"method.request.header.RSC": false,
|
|
86
|
-
"method.request.header.User-Agent": false,
|
|
87
|
-
"method.request.header.Referer": false,
|
|
88
|
-
"method.request.header.Accept": false,
|
|
89
|
-
"method.request.header.Accept-Language": false,
|
|
90
|
-
"method.request.header.Accept-Encoding": false,
|
|
91
|
-
"method.request.header.Content-Type": false,
|
|
92
|
-
"method.request.header.Content-Length": false,
|
|
93
|
-
"method.request.header.Origin": false,
|
|
94
|
-
"method.request.header.X-Forwarded-For": false,
|
|
95
|
-
"method.request.header.X-Forwarded-Host": false,
|
|
96
|
-
"method.request.header.X-IP": false,
|
|
97
|
-
"method.request.header.X-Forwarded-Proto": false,
|
|
98
|
-
"method.request.header.X-Forwarded-Port": false,
|
|
99
|
-
"method.request.header.Sec-Fetch-Site": false,
|
|
100
|
-
"method.request.header.Sec-Fetch-Mode": false,
|
|
101
|
-
"method.request.header.Sec-Fetch-Dest": false,
|
|
102
|
-
},
|
|
103
|
-
integrationHttpMethod: "GET",
|
|
104
|
-
type: "HTTP",
|
|
105
|
-
timeoutInMillis: 29000,
|
|
106
|
-
});
|
|
107
|
-
const newMethodResponse = await client.send(newMethodCommand);
|
|
108
|
-
await sleep(100);
|
|
109
|
-
|
|
110
|
-
// create new integration
|
|
111
|
-
const newIntegrationCommand = new PutIntegrationCommand({
|
|
112
|
-
restApiId: config[apiGateway].id,
|
|
113
|
-
resourceId: newResourceResponse.id,
|
|
114
|
-
httpMethod: "GET",
|
|
115
|
-
integrationHttpMethod: "GET",
|
|
116
|
-
type: "HTTP",
|
|
117
|
-
timeoutInMillis: 29000,
|
|
118
|
-
uri: url,
|
|
119
|
-
});
|
|
120
|
-
const newIntegrationResponse = await client.send(newIntegrationCommand);
|
|
121
|
-
await sleep(100);
|
|
122
|
-
|
|
123
|
-
// create a new method response
|
|
124
|
-
const newMethodResponseCommand = new PutMethodResponseCommand({
|
|
125
|
-
httpMethod: "GET",
|
|
126
|
-
resourceId: newResourceResponse.id,
|
|
127
|
-
restApiId: config[apiGateway].id,
|
|
128
|
-
statusCode: "200",
|
|
129
|
-
});
|
|
130
|
-
const newMethodResponseResponse = await client.send(
|
|
131
|
-
newMethodResponseCommand,
|
|
132
|
-
);
|
|
133
|
-
await sleep(100);
|
|
134
|
-
|
|
135
|
-
// put integration response
|
|
136
|
-
const putIntegrationResponseCommand = new PutIntegrationResponseCommand({
|
|
137
|
-
httpMethod: "GET",
|
|
138
|
-
resourceId: newResourceResponse.id,
|
|
139
|
-
restApiId: config[apiGateway].id,
|
|
140
|
-
statusCode: "200",
|
|
141
|
-
});
|
|
142
|
-
const putIntegrationResponseResponse = await client.send(
|
|
143
|
-
putIntegrationResponseCommand,
|
|
144
|
-
);
|
|
145
|
-
await sleep(100);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Generate dynamic stage name
|
|
149
|
-
// const dynamicStageName = `prod-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`;
|
|
150
|
-
// console.log(chalk.blue(`[*] Using dynamic stage name: ${dynamicStageName}`));
|
|
151
|
-
|
|
152
|
-
// Create a deployment
|
|
153
|
-
// const createDeploymentCommand = new CreateDeploymentCommand({
|
|
154
|
-
// restApiId: config[apiGateway].id,
|
|
155
|
-
// stageName: dynamicStageName,
|
|
156
|
-
// description: `Deployment for ${url} at ${new Date().toISOString()} to stage ${dynamicStageName}`,
|
|
157
|
-
// });
|
|
158
|
-
// const deploymentResponse = await client.send(createDeploymentCommand);
|
|
159
|
-
// console.log(chalk.green("[+] Deployment created:"), deploymentResponse.id);
|
|
160
|
-
// await sleep(100);
|
|
161
|
-
|
|
162
|
-
const testInvokeMethodQuery = new TestInvokeMethodCommand({
|
|
163
|
-
httpMethod: "GET",
|
|
164
|
-
resourceId: newResourceResponse.id,
|
|
165
|
-
restApiId: config[apiGateway].id,
|
|
166
|
-
headers: headers || {},
|
|
167
|
-
});
|
|
168
|
-
const testInvokeMethodResponse = await client.send(testInvokeMethodQuery);
|
|
169
|
-
await sleep(100);
|
|
170
|
-
|
|
171
|
-
const body = await testInvokeMethodResponse.body;
|
|
172
|
-
|
|
173
|
-
// check if any firewall is there in the way
|
|
174
|
-
const isFireWallBlocking = await checkFireWallBlocking(body);
|
|
175
|
-
|
|
176
|
-
// delete the resource
|
|
177
|
-
const deleteResourceCommand = new DeleteResourceCommand({
|
|
178
|
-
restApiId: config[apiGateway].id,
|
|
179
|
-
resourceId: newResourceResponse.id,
|
|
180
|
-
});
|
|
181
|
-
try {
|
|
182
|
-
await client.send(deleteResourceCommand);
|
|
183
|
-
} catch {}
|
|
184
|
-
|
|
185
|
-
if (isFireWallBlocking) {
|
|
186
|
-
console.log(chalk.magenta("[!] Please try again without API Gateway"));
|
|
187
|
-
process.exit(1);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return body;
|
|
191
|
-
|
|
192
|
-
// create a new stage
|
|
193
|
-
// dynamicStageName = `prod-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`;
|
|
194
|
-
// const newStageCommand = new CreateStageCommand({
|
|
195
|
-
// restApiId: config[apiGateway].id,
|
|
196
|
-
// stageName: dynamicStageName, // Use dynamic stage name
|
|
197
|
-
// deploymentId: deploymentResponse.id, // Use the ID from the deployment
|
|
198
|
-
// cacheClusterEnabled: false,
|
|
199
|
-
// // cacheClusterSize: "0", // Removed as cacheClusterEnabled is false
|
|
200
|
-
// methodSettings: [
|
|
201
|
-
// {
|
|
202
|
-
// httpMethod: "*",
|
|
203
|
-
// // resourceId: "*", // This might need to be more specific if you don't want it for all resources
|
|
204
|
-
// throttlingBurstLimit: 5,
|
|
205
|
-
// throttlingRateLimit: 10,
|
|
206
|
-
// },
|
|
207
|
-
// ],
|
|
208
|
-
// });
|
|
209
|
-
// const newStageResponse = await client.send(newStageCommand);
|
|
210
|
-
// await sleep(100);
|
|
211
|
-
// console.log(newStageResponse);
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
export { get };
|
package/api_gateway/index.js
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import {
|
|
3
|
-
APIGatewayClient,
|
|
4
|
-
CreateRestApiCommand,
|
|
5
|
-
DeleteRestApiCommand,
|
|
6
|
-
} from "@aws-sdk/client-api-gateway";
|
|
7
|
-
import fs from "fs";
|
|
8
|
-
import checkFeasibility from "./checkFeasibility.js";
|
|
9
|
-
|
|
10
|
-
// read the docs for all the methods for api gateway at https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/api-gateway/
|
|
11
|
-
// for the rate limits, refer to https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html
|
|
12
|
-
|
|
13
|
-
const randomRegion = () => {
|
|
14
|
-
const apiGatewayRegions = [
|
|
15
|
-
"us-east-2", // US East (Ohio)
|
|
16
|
-
"us-east-1", // US East (N. Virginia)
|
|
17
|
-
"us-west-1", // US West (N. California)
|
|
18
|
-
"us-west-2", // US West (Oregon)
|
|
19
|
-
"af-south-1", // Africa (Cape Town)
|
|
20
|
-
"ap-east-1", // Asia Pacific (Hong Kong)
|
|
21
|
-
"ap-south-2", // Asia Pacific (Hyderabad)
|
|
22
|
-
"ap-southeast-3", // Asia Pacific (Jakarta)
|
|
23
|
-
"ap-southeast-5", // Asia Pacific (Malaysia)
|
|
24
|
-
"ap-southeast-4", // Asia Pacific (Melbourne)
|
|
25
|
-
"ap-south-1", // Asia Pacific (Mumbai)
|
|
26
|
-
"ap-northeast-3", // Asia Pacific (Osaka)
|
|
27
|
-
"ap-northeast-2", // Asia Pacific (Seoul)
|
|
28
|
-
"ap-southeast-1", // Asia Pacific (Singapore)
|
|
29
|
-
"ap-southeast-2", // Asia Pacific (Sydney)
|
|
30
|
-
"ap-east-2", // Asia Pacific (Taipei)
|
|
31
|
-
"ap-southeast-7", // Asia Pacific (Thailand)
|
|
32
|
-
"ap-northeast-1", // Asia Pacific (Tokyo)
|
|
33
|
-
"ca-central-1", // Canada (Central)
|
|
34
|
-
"ca-west-1", // Canada West (Calgary)
|
|
35
|
-
"eu-central-1", // Europe (Frankfurt)
|
|
36
|
-
"eu-west-1", // Europe (Ireland)
|
|
37
|
-
"eu-west-2", // Europe (London)
|
|
38
|
-
"eu-south-1", // Europe (Milan)
|
|
39
|
-
"eu-west-3", // Europe (Paris)
|
|
40
|
-
"eu-south-2", // Europe (Spain)
|
|
41
|
-
"eu-north-1", // Europe (Stockholm)
|
|
42
|
-
"eu-central-2", // Europe (Zurich)
|
|
43
|
-
"il-central-1", // Israel (Tel Aviv)
|
|
44
|
-
"mx-central-1", // Mexico (Central)
|
|
45
|
-
"me-south-1", // Middle East (Bahrain)
|
|
46
|
-
"me-central-1", // Middle East (UAE)
|
|
47
|
-
"sa-east-1", // South America (São Paulo)
|
|
48
|
-
];
|
|
49
|
-
return apiGatewayRegions[
|
|
50
|
-
Math.floor(Math.random() * apiGatewayRegions.length)
|
|
51
|
-
];
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
let aws_access_key;
|
|
55
|
-
let aws_secret_key;
|
|
56
|
-
let region;
|
|
57
|
-
let configFile;
|
|
58
|
-
|
|
59
|
-
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Create a new API Gateway.
|
|
63
|
-
*
|
|
64
|
-
* @async
|
|
65
|
-
* @returns {Promise<void>}
|
|
66
|
-
*/
|
|
67
|
-
const createGateway = async () => {
|
|
68
|
-
console.log(chalk.cyan("[i] Creating API Gateway"));
|
|
69
|
-
const client = new APIGatewayClient({
|
|
70
|
-
region,
|
|
71
|
-
credentials: {
|
|
72
|
-
accessKeyId: aws_access_key,
|
|
73
|
-
secretAccessKey: aws_secret_key,
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
const apigw_created_at = Date.now();
|
|
78
|
-
const apigw_name = `js_recon-${apigw_created_at}-${Math.floor(Math.random() * 1000)}`;
|
|
79
|
-
const command = new CreateRestApiCommand({
|
|
80
|
-
name: apigw_name,
|
|
81
|
-
description: `API Gateway for JS Recon created at ${new Intl.DateTimeFormat(
|
|
82
|
-
"en-US",
|
|
83
|
-
{
|
|
84
|
-
year: "numeric",
|
|
85
|
-
month: "long",
|
|
86
|
-
day: "2-digit",
|
|
87
|
-
hour: "2-digit",
|
|
88
|
-
minute: "2-digit",
|
|
89
|
-
second: "2-digit",
|
|
90
|
-
timeZoneName: "short",
|
|
91
|
-
},
|
|
92
|
-
).format(apigw_created_at)}`,
|
|
93
|
-
endpointConfiguration: {
|
|
94
|
-
ipAddressType: "dualstack",
|
|
95
|
-
types: ["REGIONAL"],
|
|
96
|
-
},
|
|
97
|
-
});
|
|
98
|
-
const response = await client.send(command);
|
|
99
|
-
await sleep(3000);
|
|
100
|
-
console.log(chalk.green(`[✓] Created API Gateway`));
|
|
101
|
-
console.log(chalk.bgGreen("ID:"), chalk.green(response.id));
|
|
102
|
-
console.log(chalk.bgGreen("Name:"), chalk.green(apigw_name));
|
|
103
|
-
console.log(chalk.bgGreen("Region:"), chalk.green(region));
|
|
104
|
-
|
|
105
|
-
// load the config file if any. Else, create a new one
|
|
106
|
-
let config = {};
|
|
107
|
-
try {
|
|
108
|
-
config = JSON.parse(fs.readFileSync(configFile));
|
|
109
|
-
} catch (e) {
|
|
110
|
-
config = {};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
config[apigw_name] = {
|
|
114
|
-
id: response.id,
|
|
115
|
-
name: apigw_name,
|
|
116
|
-
description: response.description,
|
|
117
|
-
created_at: apigw_created_at,
|
|
118
|
-
region: region,
|
|
119
|
-
access_key: aws_access_key,
|
|
120
|
-
secret_key: aws_secret_key,
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
|
|
124
|
-
console.log(chalk.green(`[✓] Config saved to ${configFile}`));
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Destroy an API Gateway.
|
|
129
|
-
*
|
|
130
|
-
* @async
|
|
131
|
-
* @param {string} id - The ID of the API Gateway to destroy.
|
|
132
|
-
* @returns {Promise<void>}
|
|
133
|
-
*/
|
|
134
|
-
const destroyGateway = async (id) => {
|
|
135
|
-
console.log(chalk.cyan("[i] Destroying API Gateway"));
|
|
136
|
-
if (!id) {
|
|
137
|
-
console.log(chalk.red("[!] Please provide an API Gateway ID"));
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
// read the config file
|
|
141
|
-
let config = JSON.parse(fs.readFileSync(configFile));
|
|
142
|
-
// get the name of the api gateway
|
|
143
|
-
let name = Object.keys(config).find((key) => config[key].id === id);
|
|
144
|
-
|
|
145
|
-
console.log(chalk.bgGreen("Name:"), chalk.green(name));
|
|
146
|
-
console.log(chalk.bgGreen("ID:"), chalk.green(id));
|
|
147
|
-
console.log(chalk.bgGreen("Region:"), chalk.green(config[name].region));
|
|
148
|
-
region = config[name].region;
|
|
149
|
-
|
|
150
|
-
const client = new APIGatewayClient({
|
|
151
|
-
region,
|
|
152
|
-
credentials: {
|
|
153
|
-
accessKeyId: aws_access_key,
|
|
154
|
-
secretAccessKey: aws_secret_key,
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
const command = new DeleteRestApiCommand({
|
|
159
|
-
restApiId: id,
|
|
160
|
-
});
|
|
161
|
-
await client.send(command);
|
|
162
|
-
|
|
163
|
-
// remove from the config file
|
|
164
|
-
delete config[name];
|
|
165
|
-
fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
|
|
166
|
-
|
|
167
|
-
await sleep(30000);
|
|
168
|
-
|
|
169
|
-
console.log(chalk.green(`[✓] Destroyed API Gateway: ${id}`));
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Destroy all API Gateways.
|
|
174
|
-
*
|
|
175
|
-
* @async
|
|
176
|
-
* @returns {Promise<void>}
|
|
177
|
-
*/
|
|
178
|
-
const destroyAllGateways = async () => {
|
|
179
|
-
console.log(chalk.cyan("[i] Destroying all API Gateways"));
|
|
180
|
-
// read the config file
|
|
181
|
-
let config = JSON.parse(fs.readFileSync(configFile));
|
|
182
|
-
|
|
183
|
-
// destroy all the gateways
|
|
184
|
-
for (const [key, value] of Object.entries(config)) {
|
|
185
|
-
const client = new APIGatewayClient({
|
|
186
|
-
region: value.region,
|
|
187
|
-
credentials: {
|
|
188
|
-
accessKeyId: aws_access_key,
|
|
189
|
-
secretAccessKey: aws_secret_key,
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
console.log(
|
|
193
|
-
chalk.cyan(
|
|
194
|
-
`[i] Destroying API Gateway: ${key} : ${value.id} : ${value.region}`,
|
|
195
|
-
),
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
const command = new DeleteRestApiCommand({
|
|
199
|
-
restApiId: value.id,
|
|
200
|
-
});
|
|
201
|
-
await sleep(30000);
|
|
202
|
-
await client.send(command);
|
|
203
|
-
console.log(
|
|
204
|
-
chalk.green(
|
|
205
|
-
`[✓] Destroyed API Gateway: ${key} : ${value.id} : ${value.region}`,
|
|
206
|
-
),
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// nullify the config file
|
|
211
|
-
fs.writeFileSync(configFile, JSON.stringify({}, null, 2));
|
|
212
|
-
console.log(chalk.green("[✓] Destroyed all API Gateways"));
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* List all API Gateways.
|
|
217
|
-
*
|
|
218
|
-
* @async
|
|
219
|
-
* @returns {Promise<void>}
|
|
220
|
-
*/
|
|
221
|
-
const listGateways = async () => {
|
|
222
|
-
console.log(chalk.cyan("[i] Listing all API Gateways"));
|
|
223
|
-
|
|
224
|
-
// read the config file, and list these
|
|
225
|
-
|
|
226
|
-
// check if the config file exists
|
|
227
|
-
if (!fs.existsSync(configFile)) {
|
|
228
|
-
console.log(chalk.red("[!] Config file does not exist"));
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const config = JSON.parse(fs.readFileSync(configFile));
|
|
233
|
-
|
|
234
|
-
// if list is empty
|
|
235
|
-
if (Object.keys(config).length === 0) {
|
|
236
|
-
console.log(chalk.red("[!] No API Gateways found"));
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
console.log(chalk.green("[✓] List of API Gateways"));
|
|
241
|
-
|
|
242
|
-
for (const [key, value] of Object.entries(config)) {
|
|
243
|
-
console.log(chalk.bgGreen("Name:"), chalk.green(key));
|
|
244
|
-
console.log(chalk.bgGreen("ID:"), chalk.green(value.id));
|
|
245
|
-
console.log(chalk.bgGreen("Region:"), chalk.green(value.region));
|
|
246
|
-
console.log("\n");
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Main function for API Gateway.
|
|
252
|
-
*
|
|
253
|
-
* @async
|
|
254
|
-
* @param {boolean} initInput - Whether to initialize the API Gateway.
|
|
255
|
-
* @param {string} destroyInput - The ID of the API Gateway to destroy.
|
|
256
|
-
* @param {boolean} destroyAllInput - Whether to destroy all API Gateways.
|
|
257
|
-
* @param {boolean} listInput - Whether to list all API Gateways.
|
|
258
|
-
* @param {string} regionInput - The region to use.
|
|
259
|
-
* @param {string} accessKey - The access key to use.
|
|
260
|
-
* @param {string} secretKey - The secret key to use.
|
|
261
|
-
* @param {string} configInput - The config file to use.
|
|
262
|
-
* @returns {Promise<void>}
|
|
263
|
-
*/
|
|
264
|
-
const apiGateway = async (
|
|
265
|
-
initInput,
|
|
266
|
-
destroyInput,
|
|
267
|
-
destroyAllInput,
|
|
268
|
-
listInput,
|
|
269
|
-
regionInput,
|
|
270
|
-
accessKey,
|
|
271
|
-
secretKey,
|
|
272
|
-
configInput,
|
|
273
|
-
feasibilityInput,
|
|
274
|
-
feasibilityUrlInput,
|
|
275
|
-
) => {
|
|
276
|
-
console.log(chalk.cyan("[i] Loading 'API Gateway' module"));
|
|
277
|
-
|
|
278
|
-
// if feasibility is true, check feasibility
|
|
279
|
-
if (feasibilityInput) {
|
|
280
|
-
if (!feasibilityUrlInput) {
|
|
281
|
-
console.log(chalk.red("[!] Please provide a URL to check feasibility of"));
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
await checkFeasibility(feasibilityUrlInput);
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// configure the access and secret key
|
|
289
|
-
aws_access_key = accessKey || process.env.AWS_ACCESS_KEY_ID || undefined;
|
|
290
|
-
aws_secret_key = secretKey || process.env.AWS_SECRET_ACCESS_KEY || undefined;
|
|
291
|
-
region = regionInput || randomRegion();
|
|
292
|
-
configFile = configInput || "config.json";
|
|
293
|
-
|
|
294
|
-
if (!aws_access_key || !aws_secret_key) {
|
|
295
|
-
console.log(chalk.red("[!] AWS Access Key or Secret Key not found"));
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
console.log(chalk.cyan(`[i] Using region: ${region}`));
|
|
300
|
-
|
|
301
|
-
const keyMask = (key) => {
|
|
302
|
-
if (key.length < 6) return key;
|
|
303
|
-
return key.slice(0, 4) + "..." + key.slice(-4);
|
|
304
|
-
};
|
|
305
|
-
console.log(chalk.cyan(`[i] Using access key: ${keyMask(aws_access_key)}`));
|
|
306
|
-
|
|
307
|
-
// create a new API gateway
|
|
308
|
-
if (initInput) {
|
|
309
|
-
await createGateway();
|
|
310
|
-
} else if (destroyInput) {
|
|
311
|
-
await destroyGateway(destroyInput);
|
|
312
|
-
} else if (destroyAllInput) {
|
|
313
|
-
await destroyAllGateways();
|
|
314
|
-
} else if (listInput) {
|
|
315
|
-
await listGateways();
|
|
316
|
-
} else {
|
|
317
|
-
console.log(
|
|
318
|
-
chalk.red(
|
|
319
|
-
"[!] Please provide a valid action (-i/--init or -d/--destroy or --destroy-all)",
|
|
320
|
-
),
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
|
|
325
|
-
export default apiGateway;
|