Skip to content

Commit

Permalink
Added PingCastle
Browse files Browse the repository at this point in the history
  • Loading branch information
drakylar committed Jan 29, 2022
1 parent 9469046 commit b0b0c22
Show file tree
Hide file tree
Showing 6 changed files with 4,324 additions and 9 deletions.
146 changes: 139 additions & 7 deletions routes/ui/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3714,9 +3714,9 @@ def duplicator_page_form(project_id, current_project, current_user):
if current_path['network_in']:
source_network = db.select_network(current_path['network_in'])[0]
network_in = db.select_network_by_ip(destination_project['id'],
source_network['ip'],
source_network['mask'],
source_network['is_ipv6'])[0]['id']
source_network['ip'],
source_network['mask'],
source_network['is_ipv6'])[0]['id']

# search dublicates
dublicate_paths = db.search_path(project_id=destination_project['id'],
Expand Down Expand Up @@ -5395,12 +5395,144 @@ def nmap_helper_page(project_id, current_project, current_user):
tab_name='Nmap Helper')


@routes.route('/project/<uuid:project_id>/tools/msfvenom-helper/', methods=['GET'])
@routes.route('/project/<uuid:project_id>/tools/pingcastle/', methods=['GET'])
@requires_authorization
@check_session
@check_project_access
@check_project_archived
@send_log_data
def pingcastle_page(project_id, current_project, current_user):
return render_template('project/tools/import/pingcastle.html',
current_project=current_project,
tab_name='PingCastle')


@routes.route('/project/<uuid:project_id>/tools/pingcastle/', methods=['POST'])
@requires_authorization
@check_session
@check_project_access
@check_project_archived
@send_log_data
def msfvenom_helper_page(project_id, current_project, current_user):
return render_template('project/tools/helpers/msfvenom-helper.html',
def pingcastle_page_form(project_id, current_project, current_user):
form = PingCastleForm()
form.validate()
errors = []
if form.errors:
for field in form.errors:
for error in form.errors[field]:
errors.append(error)

if not errors:
# prepare issues database
f = open('./routes/ui/tools_files/PingCastle/PingCastleDescription.resx')
s = f.read()
f.close()
issues_database = {}
issues_database_xml = BeautifulSoup(s, 'html.parser')
for issue_obj in issues_database_xml.findAll('data'):
issues_database[issue_obj.attrs['name']] = issue_obj.findAll('value')[0].text

# xml files
for file in form.xml_files.data:
if file.filename:
scan_result = BeautifulSoup(file.read(), "html.parser")
scan_obj = scan_result.healthcheckdata

# add DCs
domain_controllers = scan_obj.domaincontrollers
dc_ports_dict = {}
if domain_controllers:
for domain_obj in domain_controllers.findAll('healthcheckdomaincontroller'):
host_description = ''
host_os = '' if not domain_obj.operatingsystem else domain_obj.operatingsystem.text
if domain_obj.dcname: host_description += 'DC name: {}\n'.format(domain_obj.dcname.text)
if domain_obj.lastcomputerlogondate: host_description += 'Last Logon: {}\n'.format(domain_obj.lastcomputerlogondate.text)
if domain_obj.distinguishedname: host_description += 'Distinguished Name: {}\n'.format(domain_obj.distinguishedname.text)
if domain_obj.ownersid: host_description += 'Owner SID: {}\n'.format(domain_obj.ownersid.text)
if domain_obj.ownername: host_description += 'Owner Name: {}\n'.format(domain_obj.ownername.text)
if domain_obj.hasnullsession and domain_obj.hasnullsession == 'true': host_description += 'Has null session!\n'
if domain_obj.supportsmb1 and domain_obj.supportsmb1.text == 'true':
host_description += 'Supports SMB1!\n'
if domain_obj.smb1securitymode and domain_obj.smb1securitymode.text == 'NotTested':
host_description += 'SMB1SecurityMode: {}\n'.format(domain_obj.smb1securitymode.text)
if domain_obj.supportsmb2orsmb3 and domain_obj.supportsmb2orsmb3.text == 'true': host_description += 'Supports SMBv2 or SMBv3.\n'
if domain_obj.smb2securitymode: host_description += 'SMB2 security mode: {}\n'.format(domain_obj.smb2securitymode.text)
if domain_obj.remotespoolerdetected and domain_obj.remotespoolerdetected.text == 'true': host_description += 'Detected remote spooler.\n'
if domain_obj.pwdlastset: host_description += 'Last pwd set: {}.\n'.format(domain_obj.pwdlastset.text)
if domain_obj.rodc and domain_obj.rodc.text == 'true': host_description += 'Read-Only DC\n'
if domain_obj.sysvoloverwrite and domain_obj.sysvoloverwrite == 'true': host_description += 'SYSVOL overwrite\n'

if domain_obj.fsmo:
fsmo_result = ', '.join([x.text for x in domain_obj.fsmo.findAll("string")])
if fsmo_result:
host_description += 'FSMO: {}\n'.format(fsmo_result)

host_description = host_description.strip(' \n\t\r')
# TODO: fields LDAPSProtocols
try:
ip_obj = domain_obj.ip
for host_ip_obj in ip_obj.findAll('string'):
host_ip = host_ip_obj.text
# check for valid ip
ipaddress.ip_address(host_ip)
current_host = db.select_project_host_by_ip(current_project['id'], host_ip)
if current_host:
current_host_id = current_host[0]['id']
if host_os:
db.update_host_os(current_host_id, host_os)

else:
current_host_id = db.insert_host(current_project['id'], host_ip, current_user['id'], 'Added from PingCastle', os=host_os)
# add 88 port
current_port = db.select_host_port(current_host_id, port_num=88, is_tcp=True)
if current_port:
current_port_id = current_port[0]['id']
if host_description:
db.update_port_proto_description(current_port_id, 'kerberos', host_description)
else:
current_port_id = db.insert_host_port(current_host_id, 88, True, 'kerberos',
host_description, current_user['id'], current_project['id'])
dc_ports_dict[current_port_id] = ['0']
except Exception as e:
pass

# TODO: ignored fields: Sites, lDAPIPDenyList, PreWindows2000AnonymousAccess, PreWindows2000NoDefault
# PreWindows2000AuthenticatedUsers, DsHeuristicsAnonymousAccess, DsHeuristicsAdminSDExMaskModified
# DsHeuristicsDoListObject, DsHeuristicsAllowAnonNSPI, UsingNTFRSForSYSVOL

# Issues - RiskRules
risk_rules = scan_obj.riskrules
for risk_obj in risk_rules.findAll('healthcheckriskrule'):
issue_points = int(risk_obj.points.text)
issue_category = risk_obj.category.text # PrivilegedAccounts
issue_model = risk_obj.model.text # AccountTakeOver
issue_riskid = risk_obj.riskid.text.replace('-', '_') # A_AdminSDHolder
issue_briefly = risk_obj.rationale.text
issue_links = issues_database[issue_riskid + '_Documentation'].replace(' ', '') if (issue_riskid + '_Documentation') in issues_database else ''
issue_purpose = issues_database[issue_riskid + '_Description'] if (issue_riskid + '_Description') in issues_database else ''
issue_fix = issues_database[issue_riskid + '_Solution'] if (issue_riskid + '_Solution') in issues_database else ''
issue_technical_description = issues_database[issue_riskid + '_TechnicalExplanation'] if (issue_riskid + '_TechnicalExplanation') in issues_database else ''
issue_name = 'PingCastle: {}'.format(issues_database[issue_riskid + '_Title'])

issue_full_description = 'Brief: {}\n\nTechnical information: {}\n\nTest purpose: {}\n\nLinks: \n{}'.format(
issue_briefly,
issue_technical_description,
issue_purpose,
issue_links
)
if issue_points < 1:
issue_cvss = 0
elif issue_points < 10:
issue_cvss = 3
elif issue_points < 30:
issue_cvss = 6
else:
issue_cvss = 9.5

issue_id = db.insert_new_issue_no_dublicate(issue_name, issue_full_description, '', issue_cvss,
current_user['id'], dc_ports_dict, 'need to recheck',
current_project['id'], fix=issue_fix)
return render_template('project/tools/import/pingcastle.html',
current_project=current_project,
tab_name='MSFvenom Helper')
tab_name='PingCastle',
errors=errors)
Loading

0 comments on commit b0b0c22

Please sign in to comment.