* Added warnings and threats comments about pth findings

This commit is contained in:
maor.rayzin 2018-08-08 16:03:16 +03:00
parent 4a780d81a8
commit 3c40fd7cc3
3 changed files with 42 additions and 24 deletions

View File

@ -118,17 +118,16 @@ class PTHReportService(object):
def get_duplicated_passwords_issues(pth, password_groups): def get_duplicated_passwords_issues(pth, password_groups):
issues = [] issues = []
for group in password_groups: for group in password_groups:
for username in group['cred_group']: username = group['cred_group'][0]
sid = list(pth.GetSidsByUsername(username.split('\\')[1])) sid = list(pth.GetSidsByUsername(username.split('\\')[1]))
machine_info = pth.GetSidInfo(sid[0]) machine_info = pth.GetSidInfo(sid[0])
issues.append( issues.append(
{ {
'type': 'shared_password', 'type': 'shared_passwords',
'machine': machine_info.get('hostname').split('.')[0], 'machine': machine_info.get('hostname').split('.')[0],
'shared_with': [x for x in group['cred_group'] if x != username], 'shared_with': group['cred_group']
'username': username }
} )
)
return issues return issues
@ -207,7 +206,7 @@ class PTHReportService(object):
issues += PTHReportService.get_duplicated_passwords_issues(pth, same_password) issues += PTHReportService.get_duplicated_passwords_issues(pth, same_password)
issues += PTHReportService.get_shared_local_admins_issues(local_admin_shared) issues += PTHReportService.get_shared_local_admins_issues(local_admin_shared)
issues += PTHReportService.strong_users_on_crit_issues(strong_users_on_crit_services) issues += PTHReportService.strong_users_on_crit_issues(strong_users_on_crit_services)
formated_issues = PTHReportService.get_issues_list(issues) #formated_issues = PTHReportService.get_issues_list(issues)
report = \ report = \
{ {
@ -217,7 +216,7 @@ class PTHReportService(object):
'local_admin_shared': local_admin_shared, 'local_admin_shared': local_admin_shared,
'strong_users_on_crit_services': strong_users_on_crit_services, 'strong_users_on_crit_services': strong_users_on_crit_services,
'strong_users_on_non_crit_services': strong_users_on_non_crit_services, 'strong_users_on_non_crit_services': strong_users_on_non_crit_services,
'pth_issues': formated_issues 'pth_issues': issues
}, },
'pthmap': 'pthmap':
{ {

View File

@ -9,6 +9,7 @@ from cc.services.config import ConfigService
from cc.services.edge import EdgeService from cc.services.edge import EdgeService
from cc.services.node import NodeService from cc.services.node import NodeService
from cc.utils import local_ip_addresses, get_subnets from cc.utils import local_ip_addresses, get_subnets
from pth_report import PTHReportService
__author__ = "itay.mizeretz" __author__ = "itay.mizeretz"
@ -43,10 +44,14 @@ class ReportService:
AZURE = 6 AZURE = 6
STOLEN_SSH_KEYS = 7 STOLEN_SSH_KEYS = 7
STRUTS2 = 8 STRUTS2 = 8
PTH_CRIT_SERVICES_ACCESS = 10
class WARNINGS_DICT(Enum): class WARNINGS_DICT(Enum):
CROSS_SEGMENT = 0 CROSS_SEGMENT = 0
TUNNEL = 1 TUNNEL = 1
SHARED_LOCAL_ADMIN = 2
SHARED_PASSWORDS = 3
@staticmethod @staticmethod
def get_first_monkey_time(): def get_first_monkey_time():
@ -365,7 +370,8 @@ class ReportService:
@staticmethod @staticmethod
def get_issues(): def get_issues():
issues = ReportService.get_exploits() + ReportService.get_tunnels() +\ issues = ReportService.get_exploits() + ReportService.get_tunnels() +\
ReportService.get_cross_segment_issues() + ReportService.get_azure_issues() ReportService.get_cross_segment_issues() + ReportService.get_azure_issues() + \
PTHReportService.get_report().get('report_info').get('pth_issues', [])
issues_dict = {} issues_dict = {}
for issue in issues: for issue in issues:
machine = issue['machine'] machine = issue['machine']
@ -430,7 +436,9 @@ class ReportService:
issues_byte_array[ReportService.ISSUES_DICT.STOLEN_SSH_KEYS.value] = True issues_byte_array[ReportService.ISSUES_DICT.STOLEN_SSH_KEYS.value] = True
elif issue['type'] == 'struts2': elif issue['type'] == 'struts2':
issues_byte_array[ReportService.ISSUES_DICT.STRUTS2.value] = True issues_byte_array[ReportService.ISSUES_DICT.STRUTS2.value] = True
elif issue['type'].endswith('_password') and issue['password'] in config_passwords and \ elif issue['type'] == 'strong_users_on_crit':
issues_byte_array[ReportService.ISSUES_DICT.PTH_CRIT_SERVICES_ACCESS.value] = True
elif issue['type'].endswith('_password') and issue.get('password', None) in config_passwords and \
issue['username'] in config_users or issue['type'] == 'ssh': issue['username'] in config_users or issue['type'] == 'ssh':
issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD.value] = True issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD.value] = True
elif issue['type'].endswith('_pth') or issue['type'].endswith('_password'): elif issue['type'].endswith('_pth') or issue['type'].endswith('_password'):
@ -440,7 +448,7 @@ class ReportService:
@staticmethod @staticmethod
def get_warnings_overview(issues): def get_warnings_overview(issues):
warnings_byte_array = [False] * 2 warnings_byte_array = [False] * len(ReportService.WARNINGS_DICT)
for machine in issues: for machine in issues:
for issue in issues[machine]: for issue in issues[machine]:
@ -448,6 +456,10 @@ class ReportService:
warnings_byte_array[ReportService.WARNINGS_DICT.CROSS_SEGMENT.value] = True warnings_byte_array[ReportService.WARNINGS_DICT.CROSS_SEGMENT.value] = True
elif issue['type'] == 'tunnel': elif issue['type'] == 'tunnel':
warnings_byte_array[ReportService.WARNINGS_DICT.TUNNEL.value] = True warnings_byte_array[ReportService.WARNINGS_DICT.TUNNEL.value] = True
elif issue['type'] == 'shared_admins':
warnings_byte_array[ReportService.WARNINGS_DICT.SHARED_LOCAL_ADMIN.value] = True
elif issue['type'] == 'shared_passwords':
warnings_byte_array[ReportService.WARNINGS_DICT.SHARED_PASSWORDS.value] = True
return warnings_byte_array return warnings_byte_array
@ -472,6 +484,7 @@ class ReportService:
config_users = ReportService.get_config_users() config_users = ReportService.get_config_users()
config_passwords = ReportService.get_config_passwords() config_passwords = ReportService.get_config_passwords()
report = \ report = \
{ {
'overview': 'overview':

View File

@ -28,13 +28,16 @@ class ReportPageComponent extends AuthComponent {
CONFICKER: 5, CONFICKER: 5,
AZURE: 6, AZURE: 6,
STOLEN_SSH_KEYS: 7, STOLEN_SSH_KEYS: 7,
STRUTS2: 8 STRUTS2: 8,
PTH_CRIT_SERVICES_ACCESS: 10
}; };
Warning = Warning =
{ {
CROSS_SEGMENT: 0, CROSS_SEGMENT: 0,
TUNNEL: 1 TUNNEL: 1,
SHARED_LOCAL_ADMIN: 2,
SHARED_PASSWORDS: 3
}; };
constructor(props) { constructor(props) {
@ -345,6 +348,9 @@ class ReportPageComponent extends AuthComponent {
<li>Struts2 servers are vulnerable to remote code execution. (<a <li>Struts2 servers are vulnerable to remote code execution. (<a
href="https://cwiki.apache.org/confluence/display/WW/S2-045"> href="https://cwiki.apache.org/confluence/display/WW/S2-045">
CVE-2017-5638</a>)</li> : null } CVE-2017-5638</a>)</li> : null }
{this.state.report.overview.issues[this.Issue.PTH_CRIT_SERVICES_ACCESS] ?
<li>Credentials of strong users was found on machines and can give access to critical servers
(DC, MSSQL, etc..)</li>: null }
</ul> </ul>
</div> </div>
: :
@ -370,6 +376,10 @@ class ReportPageComponent extends AuthComponent {
communicate.</li> : null} communicate.</li> : null}
{this.state.report.overview.warnings[this.Warning.TUNNEL] ? {this.state.report.overview.warnings[this.Warning.TUNNEL] ?
<li>Weak segmentation - Machines were able to communicate over unused ports.</li> : null} <li>Weak segmentation - Machines were able to communicate over unused ports.</li> : null}
{this.state.report.overview.warnings[this.Warning.SHARED_LOCAL_ADMIN] ?
<li>The monkey has found that some users have administrative rights on several machines.</li> : null}
{this.state.report.overview.warnings[this.Warning.SHARED_PASSWORDS] ?
<li>The monkey has found that some users are sharing passwords.</li> : null}
</ul> </ul>
</div> </div>
: :
@ -390,7 +400,6 @@ class ReportPageComponent extends AuthComponent {
</h3> </h3>
<div> <div>
{this.generateIssues(this.state.report.recommendations.issues)} {this.generateIssues(this.state.report.recommendations.issues)}
{this.generateIssues(this.state.pthreport.pth_issues)}
</div> </div>
</div> </div>
); );
@ -448,9 +457,6 @@ class ReportPageComponent extends AuthComponent {
<div style={{marginBottom: '20px'}}> <div style={{marginBottom: '20px'}}>
<StolenPasswords data={this.state.report.glance.stolen_creds}/> <StolenPasswords data={this.state.report.glance.stolen_creds}/>
</div> </div>
<div style={{marginBottom: '20px'}}>
<SharedCreds data = {this.state.pthreport.same_password} />
</div>
<div style={{marginBottom: '20px'}}> <div style={{marginBottom: '20px'}}>
<SharedAdmins data = {this.state.pthreport.local_admin_shared} /> <SharedAdmins data = {this.state.pthreport.local_admin_shared} />
</div> </div>
@ -744,7 +750,7 @@ class ReportPageComponent extends AuthComponent {
<li> <li>
Some users are sharing passwords, this should be fixed by changing passwords. Some users are sharing passwords, this should be fixed by changing passwords.
<CollapsibleWellComponent> <CollapsibleWellComponent>
The user <span className="label label-primary">{issue.username}</span> is sharing access password with: These users are sharing access password:
{this.generateInfoBadges(issue.shared_with)}. {this.generateInfoBadges(issue.shared_with)}.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </li>
@ -849,7 +855,7 @@ class ReportPageComponent extends AuthComponent {
case 'cross_segment': case 'cross_segment':
data = this.generateCrossSegmentIssue(issue); data = this.generateCrossSegmentIssue(issue);
break; break;
case 'shared_password': case 'shared_passwords':
data = this.generateSharedCredsIssue(issue); data = this.generateSharedCredsIssue(issue);
break; break;
case 'shared_admins': case 'shared_admins':