-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🎉 deploy(vestigo): Fully functional first version
- Loading branch information
1 parent
43590d3
commit f724c60
Showing
8 changed files
with
473 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,77 @@ | ||
# vestigo | ||
A tool for exploring and investigating APIs. | ||
# Vestigo | ||
|
||
A tool for exploring and investigating APIs and websites. | ||
|
||
# Installation | ||
|
||
You can install it globally with: | ||
|
||
``` | ||
yarn global add vestigo | ||
``` | ||
|
||
``` | ||
npm i -g vestigo | ||
``` | ||
|
||
``` | ||
homebrew vestigo | ||
``` | ||
|
||
# Running | ||
|
||
Example: | ||
|
||
``` | ||
scan --target="https://127.0.0.1/" --method="GET" --no-shortlist | ||
--report="HTML" | ||
``` | ||
|
||
# Options | ||
|
||
``` | ||
-h, --help | ||
``` | ||
Show CLI help. | ||
|
||
``` | ||
-t, --target=target | ||
``` | ||
The target that Vestigo will scan | ||
|
||
``` | ||
-m, --method=(GET|POST|BOTH) [default: POST] | ||
``` | ||
Requet methods can be: GET, POST, BOTH. | ||
|
||
``` | ||
-p, --no-parameters | ||
``` | ||
Don't use extra parameters on endpoints (default on). Vestigo will try to connect to urls adding get parameters example: https://myurl.com/privacy/2 | ||
|
||
``` | ||
-r, --report=(MD|HTML) [default: MD] | ||
``` | ||
Type of report to generate | ||
|
||
``` | ||
-s, --no-shortlist | ||
``` | ||
Use to use the long enpoint list (default on). If the shortlist is disabled Vestigo will use a long list of potential endpoints. | ||
|
||
# Report | ||
|
||
Vestigo will by default generate a mardown report. You can use parameters to set the report format to HTML. | ||
|
||
# To Do | ||
|
||
- [ ] Get path disclosures for basic get | ||
- [ ] Set the ssl header on a flag | ||
- [ ] Detect and render in the report if bad ssl check | ||
- [ ] Add whois | ||
- [ ] Add OS analysis from path disclosure | ||
- [ ] Add port scan (known ports) | ||
- [ ] Add verbose parameters | ||
- [ ] Make a request queuing + proxy | ||
- [ ] Add https://www.npmjs.com/package/listr for better logging | ||
- [ ] Add parameter for choosing report save location |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,86 @@ | ||
import { AxiosResponse } from 'axios'; | ||
import IntenseScan from './intenseScan'; | ||
import { formatDate } from '../tools/dateFormatter'; | ||
import * as fs from 'fs'; | ||
|
||
export enum ReportType { | ||
MARKDOWN, | ||
HTML | ||
} | ||
export default class Report { | ||
target: string; | ||
poweredBy: string; | ||
cors: string; | ||
lastModified: string; | ||
contentType: string; | ||
|
||
intenseScan: IntenseScan; | ||
flags: any; | ||
startDate: Date; | ||
endDate: Date; | ||
elapsedSeconds: number; | ||
constructor(response: AxiosResponse) { | ||
this.poweredBy = (response.headers['x-powered-by']) ? response.headers['x-powered-by'] : ''; | ||
this.cors = (response.headers['access-control-allow-origin']) ? response.headers['access-control-allow-origin'] : ''; | ||
this.lastModified = (response.headers['last-modified']) ? response.headers['last-modified'] : ''; | ||
this.contentType = (response.headers['content-type']) ? response.headers['content-type'] : ''; | ||
this.intenseScan = new IntenseScan(); | ||
this.flags = {}; | ||
this.startDate = new Date(); | ||
this.endDate = new Date(); | ||
this.elapsedSeconds = 0; | ||
this.target = ""; | ||
} | ||
|
||
exportSummary() { | ||
exportSummary(type: ReportType = ReportType.MARKDOWN) { | ||
let template: string = `` | ||
// Load Tepmplate | ||
if (type == ReportType.HTML) { | ||
template = fs.readFileSync('./templates/report.html', 'utf8'); | ||
} else { | ||
template = fs.readFileSync('./templates/report.md', 'utf8'); | ||
} | ||
// Override the classic info | ||
template = template.replace("{title}", this.flags.target); | ||
template = template.replace("{title}", this.flags.target); | ||
template = template.replace("{date}", formatDate(this.startDate, "dddd dd MMMM yyyy hh:mm")); | ||
template = template.replace("{target}", this.target); | ||
template = template.replace("{elapsedSeconds}", this.elapsedSeconds.toString()); | ||
let tempFlags = ``; | ||
// Building the table for flags | ||
for (const [key, value] of Object.entries(this.flags)) { | ||
if (type == ReportType.HTML) { | ||
tempFlags = tempFlags+`<tr><td>${key}</td><td>${value}</td></tr>`; | ||
} else { | ||
tempFlags = tempFlags+`| ${key} | ${value} |\n` | ||
} | ||
} | ||
template = template.replace("{flags}", tempFlags); | ||
let tempParams = ''; | ||
if (type == ReportType.HTML) { | ||
tempParams = `<tr><td>Powered By</td><td>${this.poweredBy}</td></tr> | ||
<tr><td>Cors</td><td>${this.cors}</td></tr> | ||
<tr><td>Last Modified</td><td>${this.lastModified}</td></tr> | ||
<tr><td>Content Type</td><td>${this.contentType}</td></tr>`; | ||
let urls = this.intenseScan.getUrlsSuccess().reduce((accumulator: any, currentValue: any) => { | ||
return accumulator+`<li>${currentValue}</li>`; | ||
}) | ||
let paths = this.intenseScan.getAllPathsDisclosures().reduce((accumulator: any, currentValue: any) => { | ||
return accumulator+`<li>${currentValue}</li>`; | ||
}) | ||
template = template.replace("{url1}", urls); | ||
template = template.replace("{path1}", paths); | ||
template = template.replace("{params}", tempParams); | ||
fs.writeFileSync("./reportFinal.html", template.toString()); | ||
} else { | ||
tempParams = `| Powered By | ${this.poweredBy} | | ||
| CORS | ${this.cors} | | ||
| Last Modified | ${this.lastModified} | | ||
| Content Type | ${this.contentType} |`; | ||
template = template.replace("{url1}", this.intenseScan.getUrlsSuccess().join('\n- ')); | ||
template = template.replace("{path1}", this.intenseScan.getAllPathsDisclosures().join('\n- ')); | ||
template = template.replace("{params}", tempParams); | ||
fs.writeFileSync("./reportFinal.md", template.toString()); | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.