-
Notifications
You must be signed in to change notification settings - Fork 385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LdapQuery Analyzer #589
Merged
+198
−0
Merged
LdapQuery Analyzer #589
Changes from 9 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
7a856d7
Create requirements.txt
cyberpescadito 02480e8
Create LdapQuery.py
cyberpescadito 7a07bde
Create LdapQuery.json
cyberpescadito cf28301
Create long.html
cyberpescadito 2bb6583
Create short.html
cyberpescadito 08a62ad
Adding case_snake formatting to configuration items
cyberpescadito b894ebd
adding snake_case formatting to config items
cyberpescadito 744e136
adding a missing character in params
cyberpescadito 9dc8f9b
fixed typo
cyberpescadito 36224f9
Adding some variable possibilities for taxonomies['value'] before fal…
cyberpescadito f69877c
use ldap3, add port/search_field, move templates
dadokkio File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{ | ||
"name": "Ldap_Query", | ||
"version": "2.0", | ||
"author": "Florian Perret @cyber_pescadito", | ||
"url": "https://github.com/cyberpescadito/Cortex-Analyzers/tree/master/analyzers/LdapQuery", | ||
"license": "AGPL-V3", | ||
"description": "Query your LDAP server to harvest informations about an user of your organization", | ||
"dataTypeList": ["username", "mail"], | ||
"command": "LdapQuery/LdapQuery.py", | ||
"baseConfig": "LdapQuery", | ||
"configurationItems": [ | ||
{ | ||
"name": "LDAP_Server_Address", | ||
"description": "Should contain the protocol. Eg: ldaps://myldap.myorg.com", | ||
"type": "string", | ||
"multi": false, | ||
"required": true | ||
}, | ||
{ | ||
"name": "LDAP_Username", | ||
"description": "Usernae of the account that will be used to bind to LDAP server. The Account should have permissions to read ldap objects and attributes.", | ||
"type": "string", | ||
"multi": false, | ||
"required": true | ||
}, | ||
{ | ||
"name": "LDAP_Password", | ||
"description": "Password of the account used to bind to LDAP server.", | ||
"type": "string", | ||
"multi": false, | ||
"required": true | ||
}, | ||
{ | ||
"name": "base_DN", | ||
"description": "The base DN to use in your LDAP. Eg: dc=myorg,dc=com", | ||
"type": "string", | ||
"multi": false, | ||
"required": true | ||
}, | ||
{ | ||
"name": "Attributes", | ||
"description": "Specify here the attributes you want to harvest. Eg: mail", | ||
"type": "string", | ||
"multi": true, | ||
"required": true | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#!/usr/bin/env python | ||
#Author: @cyber_pescadito | ||
import ldap | ||
import json | ||
from cortexutils.analyzer import Analyzer | ||
|
||
class LdapQuery(Analyzer): | ||
def __init__(self): | ||
Analyzer.__init__(self) | ||
self.ldap_address = self.get_param('config.LDAP_Server_Address', None, 'ldap_address is missing') | ||
self.username = self.get_param('config.LDAP_Username', None, 'username is missing') | ||
self.password = self.get_param('config.LDAP_Password', None, 'password is missing') | ||
self.base_dn = self.get_param('config.base_DN', None, 'base_dn is missing') | ||
self.attributes = self.get_param('config.Attributes', None, 'Missing attributes list to report') | ||
self.payload = self.get_param('data', None, 'username to search in LDAP is missing') | ||
|
||
def summary(self,raw): | ||
taxonomies = [] | ||
level = "info" | ||
namespace = "LDAP" | ||
predicate = "Query" | ||
value = "Success" | ||
taxonomies.append(self.build_taxonomy(level, namespace, predicate, value)) | ||
return {"taxonomies": taxonomies} | ||
|
||
def run(self): | ||
#Checking connection to LDAP | ||
Analyzer.run(self) | ||
try: | ||
l=ldap.initialize(self.ldap_address) | ||
l.protocol_version = ldap.VERSION3 | ||
l.simple_bind_s(self.username, self.password) | ||
valid = True | ||
except ldap.LDAPError, e: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should be: |
||
self.error(e) | ||
#Searching for the user | ||
try: | ||
searchScope = ldap.SCOPE_SUBTREE | ||
if self.data_type == "username": | ||
searchFilter = "(uid=" + self.payload + ")" | ||
elif self.data_type == "mail": | ||
searchFilter = "(mail=" + self.payload + ")" | ||
else: | ||
self.error('observable type not supported by this analyzer.') | ||
ldap_result_id = l.search(self.base_dn, searchScope, searchFilter, self.attributes) | ||
result_set = [] | ||
queryResult = {} | ||
while 1: | ||
result_type, result_data = l.result(ldap_result_id, 0) | ||
if (result_data == []): | ||
break | ||
else: | ||
if result_type == ldap.RES_SEARCH_ENTRY: | ||
result_set.append(result_data) | ||
for attribute in self.attributes: | ||
try: | ||
queryResult[attribute] = result_set[0][0][1][attribute][0] | ||
except: | ||
queryResult[attribute] = "unknown" | ||
# Cleaning characters that are wrongly parsed in thehive templates | ||
for key in queryResult: | ||
str=key | ||
strnew=str.replace('-','_') | ||
queryResult[strnew]=queryResult.pop(str) | ||
|
||
json_data = queryResult | ||
except ldap.LDAPError, e: | ||
self.error(e) | ||
|
||
|
||
self.report(json_data) | ||
|
||
if __name__ == '__main__': | ||
LdapQuery().run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<div class="report-LdapQuery" ng-if="success"> | ||
<style> | ||
.report-LdapQuery dl { | ||
margin-bottom: 2px; | ||
} | ||
</style> | ||
|
||
<div class="panel panel-info"> | ||
<div class="panel-heading"> | ||
<strong>LDAP Query Summary</strong> | ||
</div> | ||
<div class="panel-body"> | ||
<div ng-if="content[artifact.data].length === 0"> | ||
No records found | ||
</div> | ||
<div> | ||
<dl class="dl-horizontal"> | ||
<dt>cn: </dt> | ||
<dd class="wrap">{{content.cn || "-"}}</dd> | ||
</dl> | ||
<dl class="dl-horizontal"> | ||
<dt>mail: </dt> | ||
<dd class="wrap">{{content.mail || "-"}}</dd> | ||
</dl> | ||
<dl class="dl-horizontal"> | ||
<dt>uid: </dt> | ||
<dd class="wrap">{{content.uid|| "-"}}</dd> | ||
</dl> | ||
<dl class="dl-horizontal"> | ||
<dt>telephoneNumber: </dt> | ||
<dd class="wrap">{{content.telephoneNumber}}</dd> | ||
</dl> | ||
|
||
</div> | ||
</div> | ||
</div> | ||
|
||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
python-ldap | ||
cortexutils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<span class="label" ng-repeat="t in content.taxonomies" | ||
ng-class="{'info': 'label-info', 'safe': 'label-success', | ||
'suspicious': 'label-warning', | ||
'malicious':'label-danger'}[t.level]"> | ||
{{t.namespace}}:{{t.predicate}}={{t.value}} | ||
</span> |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any useful information you can put as the value of that taxonomie? probably the
cn
or theuid
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree it would be strange to not include "cn" value in attributes list to fetch from the LDAP, but if "cn" isn't declared in "attributes" list by the admin in cortex analyzer configuration it could break the summary. So i chosen to not include any value of LDAP there.
What is your point of view? should I change de program design to enforce "cn" attribute fetching ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the idea was to make that taxonomie meaningful/useful.
If it will be always:
Ldap:Query=Success
then it's not worth it.I would make a taxonomy like:
LdapQuery:cn=XXX
orLdapQuery:ATTRIBUTE_NAME=ARRTIBUTE_VALUE
or nothingThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is value a mandatory attribute of taxonomies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note sure, but the taxonomy aims to provide important info, without having to read the full report. You can probably show a taxonomy for important attributes if they exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I'm not sure how summary can receive taxonomies_values as parameter.
Probably you can add taxonomies_values as class variable and use it here with self.taxonomies_values