removed text and dom, and added secrets to db, endpoint, and UI, not probe

This commit is contained in:
counter 2023-01-13 21:05:33 -08:00
parent 494adb6671
commit 299de17cfa
3 changed files with 75 additions and 59 deletions

18
app.js
View file

@ -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") {

View file

@ -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: {

View file

@ -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>