mirror of
https://github.com/trufflesecurity/xsshunter
synced 2024-11-10 06:44:13 +00:00
removed text and dom, and added secrets to db, endpoint, and UI, not probe
This commit is contained in:
parent
494adb6671
commit
299de17cfa
3 changed files with 75 additions and 59 deletions
18
app.js
18
app.js
|
@ -8,6 +8,7 @@ const uuid = require('uuid');
|
|||
const database = require('./database.js');
|
||||
const Settings = database.Settings;
|
||||
const PayloadFireResults = database.PayloadFireResults;
|
||||
const savePayload = database.savePayload;
|
||||
const CollectedPages = database.CollectedPages;
|
||||
const InjectionRequests = database.InjectionRequests;
|
||||
const sequelize = database.sequelize;
|
||||
|
@ -150,19 +151,15 @@ async function get_app_server() {
|
|||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"text": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"was_iframe": {
|
||||
"type": "string",
|
||||
"default": "false",
|
||||
"enum": ["true", "false"]
|
||||
},
|
||||
"dom": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
"secrets": {
|
||||
"type": "array",
|
||||
"default": []
|
||||
},
|
||||
}
|
||||
};
|
||||
app.post('/js_callback', upload.single('screenshot'), validate({body: JSCallbackSchema}), async (req, res) => {
|
||||
|
@ -210,8 +207,7 @@ async function get_app_server() {
|
|||
user_agent: req.body['user-agent'],
|
||||
cookies: req.body.cookies,
|
||||
title: req.body.title,
|
||||
dom: req.body.dom,
|
||||
text: req.body.text,
|
||||
secrets: req.body.secrets,
|
||||
origin: req.body.origin,
|
||||
screenshot_id: payload_fire_image_id,
|
||||
was_iframe: (req.body.was_iframe === 'true'),
|
||||
|
@ -231,7 +227,7 @@ async function get_app_server() {
|
|||
}
|
||||
|
||||
// Store payload fire results in the database
|
||||
const new_payload_fire_result = await PayloadFireResults.create(payload_fire_data);
|
||||
const new_payload_fire_result = await savePayload(payload_fire_data);
|
||||
|
||||
// Send out notification via configured notification channel
|
||||
if(process.env.SMTP_EMAIL_NOTIFICATIONS_ENABLED === "true") {
|
||||
|
|
68
database.js
68
database.js
|
@ -58,6 +58,50 @@ Settings.init({
|
|||
]
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
Secrets found in DOMs
|
||||
*/
|
||||
class Secrets extends Model {}
|
||||
Secrets.init({
|
||||
id: {
|
||||
allowNull: false,
|
||||
primaryKey: true,
|
||||
type: Sequelize.UUID,
|
||||
defaultValue: uuid.v4()
|
||||
},
|
||||
payload_id: {
|
||||
type: Sequelize.TEXT,
|
||||
allowNull: false,
|
||||
unique: false
|
||||
},
|
||||
secret_type: {
|
||||
type: sequelize.TEXT,
|
||||
allowNull: false,
|
||||
unique: false
|
||||
},
|
||||
secret_value: {
|
||||
type: sequelize.TEXT,
|
||||
allowNull: true,
|
||||
unique: false
|
||||
}
|
||||
}, {
|
||||
sequelize,
|
||||
modelName: 'secrets',
|
||||
indexes: [
|
||||
{
|
||||
unique: false,
|
||||
fields: ['secret_type'],
|
||||
method: 'BTREE',
|
||||
},
|
||||
{
|
||||
unique: false,
|
||||
fields: ['secret_value'],
|
||||
method: 'BTREE'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
/*
|
||||
XSS payload fire results
|
||||
*/
|
||||
|
@ -111,21 +155,6 @@ PayloadFireResults.init({
|
|||
allowNull: false,
|
||||
unique: false
|
||||
},
|
||||
// DOM contents of the page the payload
|
||||
// fired upon. Can be quite large so is
|
||||
// not indexed.
|
||||
dom: {
|
||||
type: Sequelize.TEXT,
|
||||
allowNull: false,
|
||||
unique: false
|
||||
},
|
||||
// Text content of the page
|
||||
// e.g: document.body.outerText
|
||||
text: {
|
||||
type: Sequelize.TEXT,
|
||||
allowNull: false,
|
||||
unique: false
|
||||
},
|
||||
// HTTP origin of the page (e.g.
|
||||
// https://example.com)
|
||||
origin: {
|
||||
|
@ -205,6 +234,15 @@ PayloadFireResults.init({
|
|||
]
|
||||
});
|
||||
|
||||
let savePayload = async function(payload){
|
||||
let payload = await PayloadFireResults.create(payload);
|
||||
for (const secret of payload.secrets){
|
||||
secret.payload_id = payload.id;
|
||||
await Secret.create(payload);
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
class CollectedPages extends Model {}
|
||||
CollectedPages.init({
|
||||
id: {
|
||||
|
|
|
@ -115,38 +115,6 @@
|
|||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p class="report-section-label mr-2">DOM/HTML</p>
|
||||
<small slot="helperText" class="form-text text-muted report-section-description">
|
||||
Rendered DOM of the vulnerable page.
|
||||
</small>
|
||||
</div>
|
||||
<div class="m-2 mt-4">
|
||||
<codemirror style="height: auto;" ref="cmEditor" v-model="report.dom" :options="{tabSize: 2, theme: 'monokai', lineNumbers: true, line: true, lint: true, lineWrapping: true, fixedGutter: true, readOnly: true}" v-if="report.dom.length < 10000" />
|
||||
<h4 v-else><i class="fas fa-exclamation-triangle"></i> Page HTML too large to display inline, please use one of the options below.</h4>
|
||||
<base-button simple type="primary" class="mt-3 ml-1 mr-1" v-on:click="view_html_in_new_tab(report.dom)">
|
||||
<i class="fas fa-external-link-alt"></i> View Raw HTML in New Tab
|
||||
</base-button>
|
||||
<base-button simple type="primary" class="mt-3 ml-1 mr-1" v-on:click="download_html(report.dom)">
|
||||
<i class="fas fa-download"></i> Download Raw HTML
|
||||
</base-button>
|
||||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p class="report-section-label mr-2">Text</p>
|
||||
<small slot="helperText" class="form-text text-muted report-section-description">
|
||||
Text of the vulnerable page.
|
||||
</small>
|
||||
</div>
|
||||
<div class="m-2 mt-4">
|
||||
<codemirror style="height: auto;" ref="cmEditortext" v-model="report.text" :options="{tabSize: 2, theme: 'monokai', lineNumbers: true, line: true, lint: false, lineWrapping: true, fixedGutter: true, readOnly: true}" v-if="report.text" />
|
||||
<pre v-else><i>None</i></pre>
|
||||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p class="report-section-label mr-2">Origin</p>
|
||||
|
@ -160,6 +128,20 @@
|
|||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p class="report-section-label mr-2">Secrets</p>
|
||||
<small slot="helperText" class="form-text text-muted report-section-description">
|
||||
Any secrets harvested from the HTML and Javascript.
|
||||
</small>
|
||||
</div>
|
||||
<div>
|
||||
<li v-for="secret in secrets">
|
||||
Secret type: {{ secret.secret_type }}
|
||||
Secret value: {{ secret.secret_value }}
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p class="report-section-label mr-2">Browser Time</p>
|
||||
|
@ -802,4 +784,4 @@ hr {
|
|||
}
|
||||
|
||||
.corner-loader {}
|
||||
</style>
|
||||
</style>
|
||||
|
|
Loading…
Reference in a new issue