Skip to content

Commit

Permalink
Fix injection issue
Browse files Browse the repository at this point in the history
  • Loading branch information
rvazarkar committed Aug 26, 2019
1 parent a7ea536 commit c48afcb
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 98 deletions.
26 changes: 23 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"bootstrap": "^3.3.7",
"bootstrap-3-typeahead": "^4.0.2",
"dagre": "^0.7.4",
"dompurify": "^1.0.11",
"electron-store": "^1.3.0",
"eventemitter2": "^4.1.0",
"fontfaceobserver": "^2.0.13",
Expand All @@ -79,6 +80,7 @@
"react-alert-template-basic": "^1.0.0",
"react-bootstrap": "0.32.0",
"react-dom": "^16.8.6",
"react-highlighter": "^0.4.3",
"react-if": "^3.4.3",
"react-images": "^1.0.0",
"react-photo-gallery": "^8.0.0",
Expand Down
28 changes: 14 additions & 14 deletions src/components/Modals/HelpModal.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { Component } from 'react';

import { Modal, Tabs, Tab } from 'react-bootstrap';
import DOMPurify from 'dompurify';

export default class HelpModal extends Component {
constructor() {
Expand Down Expand Up @@ -33,9 +34,9 @@ export default class HelpModal extends Component {

createGeneralInfoTab(edge, source, target) {
let sourceType = source.type.toLowerCase();
let sourceName = source.label;
let sourceName = DOMPurify.sanitize(source.label);
let targetType = target.type.toLowerCase();
let targetName = target.label;
let targetName = DOMPurify.sanitize(target.label);
let formatted;
if (edge.label === 'AdminTo') {
let text = `${this.groupSpecialFormat(
Expand Down Expand Up @@ -225,25 +226,24 @@ export default class HelpModal extends Component {
targetType,
targetName
);
} else if (edge.label === 'SQLAdmin'){
} else if (edge.label === 'SQLAdmin') {
formatted = `The user ${sourceName} is a SQL admin on the computer ${targetName}.
There is at least one MSSQL instance running on ${targetName} where the user ${sourceName} is the account configured to run the SQL Server instance. The typical configuration for MSSQL is to have the local Windows account or Active Directory domain account that is configured to run the SQL Server service (the primary database engine for SQL Server) have sysadmin privileges in the SQL Server application. As a result, the SQL Server service account can be used to log into the SQL Server instance remotely, read all of the databases (including those protected with transparent encryption), and run operating systems command through SQL Server (as the service account) using a variety of techniques.
For Windows systems that have been joined to an Active Directory domain, the SQL Server instances and the associated service account can be identified by executing a LDAP query for a list of "MSSQLSvc" Service Principal Names (SPN) as a domain user. In short, when the Database Engine service starts, it attempts to register the SPN, and the SPN is then used to help facilitate Kerberos authentication.
Author: Scott Sutherland`;

}

this.setState({ infoTabContent: { __html: formatted } });
}

createAbuseInfoTab(edge, source, target) {
let sourceType = source.type;
let sourceName = source.label;
let sourceName = DOMPurify.sanitize(source.label);
let targetType = target.type;
let targetName = target.label;
let targetName = DOMPurify.sanitize(target.label);
let formatted;
if (edge.label === 'AdminTo') {
let text = `<h4>Lateral movement</h4>
Expand Down Expand Up @@ -1569,8 +1569,8 @@ export default class HelpModal extends Component {
Use Rubeus' *s4u* module to get a service ticket for the service name (sname) we want to "pretend" to be "admin" for. This ticket is injected (thanks to /ptt), and in this case grants us access to the file system of the TARGETCOMPUTER:
<code>Rubeus.exe s4u /user:${sourceName}$ /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:admin /msdsspn:cifs/TARGETCOMPUTER.testlab.local /ptt</code>`;
} else if (edge.label === 'SQLAdmin'){
formatted = `Scott Sutherland (<a href="https://twitter.com/_nullbind">@nullbind</a>) from NetSPI has authored PowerUpSQL, a PowerShell Toolkit for Attacking SQL Server. Major contributors include Antti Rantasaari, Eric Gruber (<a href="https://twitter.com/egru">@egru</a>), and Thomas Elling (<a href="https://github.com/thomaselling">@thomaselling</a>). Before executing any of the below commands, download PowerUpSQL and laod it into your PowerShell instance. Get PowerUpSQL here: <a href="https://github.com/NetSPI/PowerUpSQL">https://github.com/NetSPI/PowerUpSQL</a>.
} else if (edge.label === 'SQLAdmin') {
formatted = `Scott Sutherland (<a href="https://twitter.com/_nullbind">@nullbind</a>) from NetSPI has authored PowerUpSQL, a PowerShell Toolkit for Attacking SQL Server. Major contributors include Antti Rantasaari, Eric Gruber (<a href="https://twitter.com/egru">@egru</a>), and Thomas Elling (<a href="https://github.com/thomaselling">@thomaselling</a>). Before executing any of the below commands, download PowerUpSQL and laod it into your PowerShell instance. Get PowerUpSQL here: <a href="https://github.com/NetSPI/PowerUpSQL">https://github.com/NetSPI/PowerUpSQL</a>.
<h4>Finding Data</h4>
Get a list of databases, sizes, and encryption status:
Expand Down Expand Up @@ -1631,9 +1631,9 @@ export default class HelpModal extends Component {

createOpsecTab(edge, source, target) {
let sourceType = source.type;
let sourceName = source.label;
let sourceName = DOMPurify.sanitize(source.label);
let targetType = target.type;
let targetName = target.label;
let targetName = DOMPurify.sanitize(target.label);
let formatted;
if (edge.label === 'AdminTo') {
let text = `There are several forensic artifacts generated by the techniques described above. For instance, lateral movement via PsExec will generate 4697 events on the target system. If the target organization is collecting and analyzing those events, they may very easily detect lateral movement via PsExec.
Expand Down Expand Up @@ -1720,7 +1720,7 @@ export default class HelpModal extends Component {
formatted = `To execute this attack, the Rubeus C# assembly needs to be executed on some system with the ability to send/receive traffic in the domain. Modification of the *msDS-AllowedToActOnBehalfOfOtherIdentity* property against the target also must occur, whether through PowerShell or another method. The property should be cleared (or reset to its original value) after attack execution in order to prevent easy detection.`;
} else if (edge.label === 'AllowedToAct') {
formatted = `To execute this attack, the Rubeus C# assembly needs to be executed on some system with the ability to send/receive traffic in the domain.`;
} else if (edge.label === 'SQLAdmin'){
} else if (edge.label === 'SQLAdmin') {
formatted = `Prior to executing operating system commands through SQL Server, review the audit configuration and choose a command execution method that is not being monitored.
View audits:
Expand Down Expand Up @@ -1778,9 +1778,9 @@ export default class HelpModal extends Component {

createReferencesTab(edge, source, target) {
let sourceType = source.type;
let sourceName = source.label;
let sourceName = DOMPurify.sanitize(source.label);
let targetType = target.type;
let targetName = target.label;
let targetName = DOMPurify.sanitize(target.label);
let formatted;
if (edge.label === 'AdminTo') {
let text = `<h4>Lateral movement</h4>
Expand Down Expand Up @@ -1952,7 +1952,7 @@ export default class HelpModal extends Component {
<a href="http://www.harmj0y.net/blog/redteaming/another-word-on-delegation/">http://www.harmj0y.net/blog/redteaming/another-word-on-delegation/</a>
<a href="https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1">https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1</a>
<a href="https://github.com/Kevin-Robertson/Powermad#new-machineaccount">https://github.com/Kevin-Robertson/Powermad#new-machineaccount</a>`;
} else if (edge.label === 'SQLAdmin'){
} else if (edge.label === 'SQLAdmin') {
formatted = `<a href="https://github.com/NetSPI/PowerUpSQL/wiki">https://github.com/NetSPI/PowerUpSQL/wiki</a>
<a href="https://www.slideshare.net/nullbind/powerupsql-2018-blackhat-usa-arsenal-presentation">https://www.slideshare.net/nullbind/powerupsql-2018-blackhat-usa-arsenal-presentation</a>
<a href="https://sqlwiki.netspi.com/attackQueries/executingOSCommands/#sqlserver">https://sqlwiki.netspi.com/attackQueries/executingOSCommands/#sqlserver</a>
Expand Down
126 changes: 45 additions & 81 deletions src/components/SearchContainer/SearchContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import GlyphiconSpan from '../GlyphiconSpan';
import Icon from '../Icon';
import TabContainer from './TabContainer';
import { buildSearchQuery, buildSelectQuery } from 'utils';
import SearchRow from './SearchRow';
import ReactDOMServer from 'react-dom/server';

const SEPARATOR = '#BLOODHOUNDSEPARATOR#';

Expand Down Expand Up @@ -159,55 +161,56 @@ export default class SearchContainer extends Component {
}
},
highlighter: function(item) {
let spl = item.split(SEPARATOR);
let name = spl[0];
let index = spl[1];
let [name, index] = item.split(SEPARATOR);
let obj = this.map[index];

let searchTerm = this.query;
if (this.query.includes(':')) {
searchTerm = searchTerm.split(':')[1];
}

let type = obj.type;
let icon = '';
return ReactDOMServer.renderToString(
<SearchRow key={index} item={obj} search={searchTerm} />
);

// let type = obj.type;
// let icon = '';

switch (type) {
case 'Group':
icon =
'<i style="float:right" class="fa fa-users"></i>';
break;
case 'User':
icon = '<i style="float:right" class="fa fa-user"></i>';
break;
case 'Computer':
icon =
'<i style="float:right" class="fa fa-desktop"></i>';
break;
case 'Domain':
icon =
'<i style="float:right" class="fa fa-globe"></i>';
break;
case 'GPO':
icon = '<i style="float:right" class="fa fa-list"></i>';
break;
case 'OU':
icon =
'<i style="float:right" class="fa fa-sitemap"></i>';
break;
}
// switch (type) {
// case 'Group':
// icon =
// '<i style="float:right" class="fa fa-users"></i>';
// break;
// case 'User':
// icon = '<i style="float:right" class="fa fa-user"></i>';
// break;
// case 'Computer':
// icon =
// '<i style="float:right" class="fa fa-desktop"></i>';
// break;
// case 'Domain':
// icon =
// '<i style="float:right" class="fa fa-globe"></i>';
// break;
// case 'GPO':
// icon = '<i style="float:right" class="fa fa-list"></i>';
// break;
// case 'OU':
// icon =
// '<i style="float:right" class="fa fa-sitemap"></i>';
// break;
// }

let html = '<div>{}'.format(name);
// let html = '<div>{}'.format(name);

if (searchTerm !== '') {
let reQuery = new RegExp('(' + searchTerm + ')', 'gi');
// if (searchTerm !== '') {
// let reQuery = new RegExp('(' + searchTerm + ')', 'gi');

html = html.replace(reQuery, '<strong>$1</strong>');
}
html += icon + '</div>';
let jElem = $(html);
// html = html.replace(reQuery, '<strong>$1</strong>');
// }
// html += icon + '</div>';
// let jElem = $(html);

return jElem.html();
// return jElem.html();
},
});

Expand Down Expand Up @@ -289,55 +292,16 @@ export default class SearchContainer extends Component {
}
},
highlighter: function(item) {
let spl = item.split(SEPARATOR);
let name = spl[0];
let index = spl[1];
let [name, index] = item.split(SEPARATOR);
let obj = this.map[index];

let searchTerm = this.query;
if (this.query.includes(':')) {
searchTerm = searchTerm.split(':')[1];
}

let type = obj.type;
let icon = '';

switch (type) {
case 'Group':
icon =
'<i style="float:right" class="fa fa-users"></i>';
break;
case 'User':
icon = '<i style="float:right" class="fa fa-user"></i>';
break;
case 'Computer':
icon =
'<i style="float:right" class="fa fa-desktop"></i>';
break;
case 'Domain':
icon =
'<i style="float:right" class="fa fa-globe"></i>';
break;
case 'GPO':
icon = '<i style="float:right" class="fa fa-list"></i>';
break;
case 'OU':
icon =
'<i style="float:right" class="fa fa-sitemap"></i>';
break;
}

let html = '<div>{}'.format(name);

if (searchTerm !== '') {
let reQuery = new RegExp('(' + searchTerm + ')', 'gi');

html = html.replace(reQuery, '<strong>$1</strong>');
}
html += icon + '</div>';
let jElem = $(html);

return jElem.html();
return ReactDOMServer.renderToString(
<SearchRow key={index} item={obj} search={searchTerm} />
);
},
});
}
Expand Down
50 changes: 50 additions & 0 deletions src/components/SearchContainer/SearchRow.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { useEffect } from 'react';
import Highlight from 'react-highlighter';

const SearchRow = ({ item, search }) => {
let searched;
if (search.includes(':')) {
searched = search.split(':')[1];
} else {
searched = search;
}

let type = item.type;
let icon = {};
icon.style = { marginLeft: '10px' };

switch (type) {
case 'Group':
icon.className = 'fa fa-users';
break;
case 'User':
icon.className = 'fa fa-user';
break;
case 'Computer':
icon.className = 'fa fa-desktop';
break;
case 'Domain':
icon.className = 'fa fa-globe';
break;
case 'GPO':
icon.className = 'fa fa-list';
break;
case 'OU':
icon.className = 'fa fa-sitemap';
break;
}

let name = item.name;

return (
<div>
<Highlight matchElement='strong' search={searched}>
{name}
</Highlight>
<i {...icon} />
</div>
);
};

SearchRow.propTypes = {};
export default SearchRow;
Loading

0 comments on commit c48afcb

Please # to comment.