-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
139 lines (116 loc) · 5.52 KB
/
index.js
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env node
const { Command } = require('commander');
const chalk = require('chalk');
const fs = require('fs').promises;
const fetch = require('node-fetch');
const lodash = require('lodash');
const program = new Command();
program
.name("Ghost_Dir")
.version('0.0.1')
.description(chalk.red(`
@@@@@@@@ @@@ @@@ @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@ @@@@@@@
@@@@@@@@@ @@@ @@@ @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@ @@@@@@@@
!@@ @@! @@@ @@! @@@ !@@ @@! @@! @@@ @@! @@! @@@
!@! !@! @!@ !@! @!@ !@! !@! !@! @!@ !@! !@! @!@
!@! @!@!@ @!@!@!@! @!@ !@! !!@@!! @!! @!@ !@! !!@ @!@!!@!
!!! !!@!! !!!@!!!! !@! !!! !!@!!! !!! !@! !!! !!! !!@!@!
:!! !!: !!: !!! !!: !!! !:! !!: !!: !!! !!: !!: :!!
:!: !:: :!: !:! :!: !:! !:! :!: :!: !:! :!: :!: !:!
::: :::: :: ::: ::::: :: :::: :: :: :::: :: :: :: :::
:: :: : : : : : : : :: : : : :: : : : : : :
Developed by Israel_Albuquerque
GitHub https://github.com/leoisrael
`));
program
.command('brute <target> <wordlist>')
.description('Scan subdirectories on a web page')
.option('-c, --concurrency <num>', 'Number of parallel requests', 10)
.option('-t, --timeout <ms>', 'Timeout for each request (in milliseconds)', 5000)
.action(async (target, wordlist, options) => {
try {
const subdirectories = await getSubdirectories(wordlist);
const results = await scanSubdirectories(target, subdirectories, options);
printResults(results);
} catch (error) {
console.error(chalk.red(`Error: ${error.message}`));
process.exit(1);
}
});
async function getSubdirectories(wordlistPath) {
try {
const wordlistContent = await fs.readFile(wordlistPath, 'utf-8');
return wordlistContent.trim().split('\n');
} catch (error) {
console.error(chalk.red(`Erro ao ler o arquivo de wordlist: ${error.message}`));
process.exit(1);
}
}
let targetUrlGlobal
async function scanSubdirectories(targetUrl, subdirectories, options) {
// Arrays para armazenar os subdiretórios válidos, inválidos e falhados
const validSubdirectories = [];
const invalidSubdirectories = [];
const failedSubdirectories = [];
// Expressão regular para verificar se a URL alvo começa com "http://" ou "https://"
const urlRegex = /^https?:\/\//;
if (!urlRegex.test(targetUrl)) {
targetUrl = `http://${targetUrl}`;
}
// Cria uma função de solicitação throttledFetch que limita o número de solicitações por segundo
const throttledFetch = lodash.throttle(fetch, options.requestsPerSecond * 1000);
// Cria um array de promessas para solicitar cada subdiretório com a função throttledFetch
const requests = subdirectories.map(async (subdir) => {
const url = `${targetUrl}/${subdir}`;
// Gera um atraso aleatório entre o intervalo de tempo mínimo e máximo para evitar sobrecarregar o site alvo
const delay = Math.floor(Math.random() * (options.maxDelay - options.minDelay + 1)) + options.minDelay;
// Aguarda o atraso antes de fazer a solicitação
await new Promise(resolve => setTimeout(resolve, delay));
// Faz a solicitação usando a função throttledFetch
return throttledFetch(url, { timeout: options.timeout })
.then((response) => {
if (response.status === 404) {
invalidSubdirectories.push(url);
} else {
validSubdirectories.push(url);
}
})
.catch((error) => {
failedSubdirectories.push({ url, error: error.message });
});
});
try {
// Espera que todas as solicitações sejam concluídas
await Promise.all(requests);
} catch (error) {
// Se ocorrer um erro, exibe uma mensagem de erro e sai do processo com um código de saída de 1
console.error(chalk.red(`Erro na varredura de subdiretórios: ${error.message}`));
process.exit(1);
}
// Se houver subdiretórios com falha, exibe uma mensagem de aviso com as URLs e erros
if (failedSubdirectories.length > 0) {
console.warn(chalk.yellow('Algumas solicitações falharam:'));
failedSubdirectories.forEach(({ url, error }) => {
console.warn(chalk.red(`==> ${url} (${error})`));
});
}
// Retorna os subdiretórios válidos, inválidos e falhados em um objeto
return { validSubdirectories, invalidSubdirectories, failedSubdirectories };
}
function printResults({ validSubdirectories, invalidSubdirectories, failedSubdirectories }) {
console.log(`Starting subdirectory scan on ${targetUrlGlobal} (${validSubdirectories.length + invalidSubdirectories.length} subdirectories found)...`);
console.log(chalk.green(`Scan completed: ${validSubdirectories.length} subdirectories found.`));
if (validSubdirectories.length > 0) {
console.log(chalk.yellow('Valid subdirectories:'));
validSubdirectories.forEach((url) => console.log(chalk.green(`==> ${url}`)));
}
if (invalidSubdirectories.length > 0) {
console.log(chalk.yellow('Invalid subdirectories(404):'));
invalidSubdirectories.forEach((url) => console.log(chalk.gray(`==> ${url}`)));
}
if (failedSubdirectories.length > 0) {
console.log(chalk.yellow('Failed subdirectories:'));
failedSubdirectories.forEach((result) => console.log(chalk.red(`==> ${result.url} (${result.error})`)));
}
}
program.parse(process.argv);