Skip to content

Commit bdcf9a2

Browse files
Merge pull request #1488 from TheHive-Project/ldapquery-3-1
LdapQuery 3.1 - Add configurable TLS security level
2 parents b30852a + 2774978 commit bdcf9a2

5 files changed

Lines changed: 101 additions & 26 deletions

File tree

analyzers/LdapQuery/Dockerfile

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
1-
# pull official base image
2-
FROM python:3.9-slim
3-
4-
# Set ARGS
5-
ARG ANALYZER_NAME
6-
7-
# set work directory
8-
WORKDIR /app/
9-
10-
# Copy the current directory contents into the container at /worker
1+
# Builder stage
2+
FROM python:3-slim AS builder
3+
WORKDIR /build
4+
COPY requirements.txt .
5+
RUN test ! -e requirements.txt || pip install --user --no-cache-dir -r requirements.txt
6+
7+
# Runtime stage
8+
FROM python:3-slim
9+
WORKDIR /worker
10+
COPY --from=builder /root/.local /root/.local
1111
COPY . LdapQuery/
12-
13-
# install python3 pip3 and openssl
14-
RUN apt update
15-
RUN apt install python3 python3-pip openssl -y
16-
17-
# install dependencies using builder
18-
RUN pip3 install -r LdapQuery/requirements.txt
19-
20-
# Run app.py when the container launches
21-
ENTRYPOINT ["python","LdapQuery/ldapQuery.py"]
12+
ENV PATH=/root/.local/bin:$PATH
13+
ENTRYPOINT ["python", "LdapQuery/ldapQuery.py"]

analyzers/LdapQuery/LdapQuery.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Ldap_Query",
3-
"version": "3.0",
3+
"version": "3.1",
44
"author": "Florian Perret @cyber_pescadito & THA-CERT @tha_cert",
55
"url": "https://github.com/cyberpescadito/Cortex-Analyzers/tree/master/analyzers/LdapQuery",
66
"license": "AGPL-V3",
@@ -44,6 +44,13 @@
4444
"multi": false,
4545
"required": true
4646
},
47+
{
48+
"name": "LDAP_tls_seclevel",
49+
"description": "OpenSSL security level (0-5), lower to allow connecting to legacy LDAP/AD servers with old certificates or ciphers. Leave empty to use OpenSSL's default (2, requires >=2048-bit keys). '1' allows >=1024-bit keys and SHA-1 certs; '0' removes all restrictions, including unauthenticated ciphers. Only set this if you hit a TLS handshake failure against an older server; lowering it weakens transport security.",
50+
"type": "string",
51+
"multi": false,
52+
"required": false
53+
},
4754
{
4855
"name": "uid_search_fields",
4956
"description": "Specify here one or multiple fields to use when searching by username. Eg: uid and/or sAMAccountName",

analyzers/LdapQuery/ldapQuery.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,21 @@ def __init__(self):
4444
# Get attributes to export as custom fields
4545
self.attributes_to_custom_fields, self.attributes_to_custom_fields_prefix = self.get_attribute_mapping("config.attributes_to_custom_fields")
4646

47+
tls_seclevel = self.get_param("config.LDAP_tls_seclevel", None)
48+
4749
# Establish LDAP server connexion
4850
try:
49-
# tls_configuration = Tls(
50-
# validate=ssl.CERT_REQUIRED,
51-
# version=ssl.PROTOCOL_TLSv1_2 # Or Version 1.3 if supported.
52-
# )
51+
tls_kwargs = {"validate": ssl.CERT_NONE}
52+
if tls_seclevel:
53+
# allows handshakes with older LDAP/AD certs OpenSSL 3.x rejects by default
54+
tls_kwargs["ciphers"] = "DEFAULT@SECLEVEL={}".format(tls_seclevel)
55+
tls_configuration = Tls(**tls_kwargs)
5356
s = Server(
5457
ldap_address,
5558
port=ldap_port,
5659
get_info=ALL,
5760
use_ssl=True if ldap_port == 636 else False,
58-
# tls=tls_configuration if ldap_port == 636 else None,
61+
tls=tls_configuration if ldap_port == 636 else None,
5962
)
6063
self.connection = Connection(
6164
s,
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<!-- Success: Dynamic display (limited to 5 results) -->
2+
<div ng-if="success && content.results.length > 0">
3+
<div class="panel panel-success" ng-repeat="result in content.results | limitTo:5">
4+
<div class="panel-heading">
5+
<strong>{{ result.cn || result.uid || ('LDAP Result ' + ($index + 1)) }}</strong>
6+
</div>
7+
<div class="panel-body">
8+
<dl class="dl-horizontal">
9+
<div ng-if="result.cn">
10+
<dt>Full Name</dt>
11+
<dd class="wrap">{{result.cn}}</dd>
12+
</div>
13+
<div ng-if="result.mail">
14+
<dt>Email</dt>
15+
<dd class="wrap"><a href="mailto:{{result.mail}}">{{result.mail}}</a></dd>
16+
</div>
17+
<div ng-if="result.uid">
18+
<dt>UID</dt>
19+
<dd class="wrap">{{result.uid}}</dd>
20+
</div>
21+
<!-- Dynamically show other attributes -->
22+
<div ng-repeat="(attr, value) in result" ng-if="attr !== 'cn' && attr !== 'mail' && attr !== 'uid'">
23+
<div>
24+
<dt>{{ attr | uppercase }}</dt>
25+
<dd class="wrap">{{ value }}</dd>
26+
</div>
27+
</div>
28+
</dl>
29+
</div>
30+
</div>
31+
</div>
32+
33+
<!-- No results found -->
34+
<div class="panel panel-info" ng-if="success && content.results.length === 0">
35+
<div class="panel-heading">
36+
<strong>No results found</strong>
37+
</div>
38+
<div class="panel-body">
39+
<p>No LDAP entries matched your query.</p>
40+
</div>
41+
</div>
42+
43+
<!-- Filtered results -->
44+
<div class="panel panel-warning" ng-if="success && content.filtered">
45+
<div class="panel-heading">
46+
<strong>Filtered LDAP Query</strong>
47+
</div>
48+
<div class="panel-body">
49+
<dl class="dl-horizontal">
50+
<dt>Message</dt>
51+
<dd class="wrap">{{content.filtered.message}}</dd>
52+
<dt>Data</dt>
53+
<dd class="wrap">{{content.filtered.data}}</dd>
54+
<dt>Data type</dt>
55+
<dd class="wrap">{{content.filtered.data_type}}</dd>
56+
<dt>Whitelist</dt>
57+
<dd class="wrap">{{content.filtered.whitelist}}</dd>
58+
</dl>
59+
</div>
60+
</div>
61+
62+
<!-- General error -->
63+
<div class="panel panel-danger" ng-if="!success">
64+
<div class="panel-heading">
65+
<strong>Error during LDAP query</strong>
66+
</div>
67+
<div class="panel-body">
68+
<p>{{content.errorMessage}}</p>
69+
</div>
70+
</div>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<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]">
2+
{{t.namespace}}:{{t.predicate}}={{t.value}}
3+
</span>

0 commit comments

Comments
 (0)