Skip to content

Commit

Permalink
LDAP - test against openLDAP, minor win-proto fixes (#4539)
Browse files Browse the repository at this point in the history
* DCE/RPC: fix any() for conformant fields

* Kerberos: fix crealm in Authenticator

* Kerberos: add GET_SALT mode

* LDAP: improve client, support for search()

* Greatly improve SMB2 ACL support

* Test our LDAP client against OpenLDAP

* Update LDAP doc

* TLS client test: also close client_socket
  • Loading branch information
gpotter2 authored Sep 28, 2024
1 parent a07e5d5 commit f7a6411
Show file tree
Hide file tree
Showing 12 changed files with 1,254 additions and 146 deletions.
10 changes: 9 additions & 1 deletion .config/ci/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,22 @@ then
fi
fi

# Install wireshark data, ifconfig, vcan, samba
CUR=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )

# Install wireshark data, ifconfig, vcan, samba, openldap
if [ "$OSTYPE" = "linux-gnu" ]
then
sudo apt-get update
sudo apt-get -qy install tshark net-tools || exit 1
sudo apt-get -qy install can-utils || exit 1
sudo apt-get -qy install linux-modules-extra-$(uname -r) || exit 1
sudo apt-get -qy install samba smbclient
# For OpenLDAP, we need to pre-populate some setup questions
sudo debconf-set-selections <<< 'slapd slapd/password2 password Bonjour1'
sudo debconf-set-selections <<< 'slapd slapd/password1 password Bonjour1'
sudo debconf-set-selections <<< 'slapd slapd/domain string scapy.net'
sudo apt-get -qy install slapd
ldapadd -D "cn=admin,dc=scapy,dc=net" -w Bonjour1 -f $CUR/openldap-testdata.ldif -c
# Make sure libpcap is installed
if [ ! -z $SCAPY_USE_LIBPCAP ]
then
Expand Down
146 changes: 146 additions & 0 deletions .config/ci/openldap-testdata.ldif
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# SPDX-License-Identifier: OLDAP-2.8
# This file is https://git.openldap.org/openldap/openldap/-/blob/master/tests/data/ppolicy.ldif?ref_type=heads
# (renamed to dc=scapy, dc=net)

dn: dc=scapy, dc=net
objectClass: top
objectClass: organization
objectClass: dcObject
o: Scapy
dc: scapy

dn: ou=People, dc=scapy, dc=net
objectClass: top
objectClass: organizationalUnit
ou: People

dn: ou=Groups, dc=scapy, dc=net
objectClass: organizationalUnit
ou: Groups

dn: cn=Policy Group, ou=Groups, dc=scapy, dc=net
objectClass: groupOfNames
cn: Policy Group
member: uid=nd, ou=People, dc=scapy, dc=net
owner: uid=ndadmin, ou=People, dc=scapy, dc=net

dn: cn=Test Group, ou=Groups, dc=scapy, dc=net
objectClass: groupOfNames
cn: Policy Group
member: uid=another, ou=People, dc=scapy, dc=net

dn: ou=Policies, dc=scapy, dc=net
objectClass: top
objectClass: organizationalUnit
ou: Policies

dn: cn=Standard Policy, ou=Policies, dc=scapy, dc=net
objectClass: top
objectClass: device
objectClass: pwdPolicy
cn: Standard Policy
pwdAttribute: 2.5.4.35
pwdLockoutDuration: 15
pwdInHistory: 6
pwdCheckQuality: 2
pwdExpireWarning: 10
pwdMaxAge: 30
pwdMinLength: 5
pwdMaxLength: 13
pwdGraceAuthnLimit: 3
pwdAllowUserChange: TRUE
pwdMustChange: TRUE
pwdMaxFailure: 3
pwdFailureCountInterval: 120
pwdSafeModify: TRUE
pwdLockout: TRUE

dn: cn=Idle Expiration Policy, ou=Policies, dc=scapy, dc=net
objectClass: top
objectClass: device
objectClass: pwdPolicy
cn: Idle Expiration Policy
pwdAttribute: 2.5.4.35
pwdLockoutDuration: 15
pwdInHistory: 6
pwdCheckQuality: 2
pwdExpireWarning: 10
pwdMaxIdle: 15
pwdMinLength: 5
pwdMaxLength: 13
pwdGraceAuthnLimit: 3
pwdAllowUserChange: TRUE
pwdMustChange: TRUE
pwdMaxFailure: 3
pwdFailureCountInterval: 120
pwdSafeModify: TRUE
pwdLockout: TRUE

dn: cn=Stricter Policy, ou=Policies, dc=scapy, dc=net
objectClass: top
objectClass: device
objectClass: pwdPolicy
cn: Stricter Policy
pwdAttribute: 2.5.4.35
pwdLockoutDuration: 15
pwdInHistory: 6
pwdCheckQuality: 2
pwdExpireWarning: 10
pwdMaxAge: 15
pwdMinLength: 5
pwdMaxLength: 13
pwdAllowUserChange: TRUE
pwdMustChange: TRUE
pwdMaxFailure: 3
pwdFailureCountInterval: 120
pwdSafeModify: TRUE
pwdLockout: TRUE

dn: cn=Another Policy, ou=Policies, dc=scapy, dc=net
objectClass: top
objectClass: device
objectClass: pwdPolicy
cn: Test Policy
pwdAttribute: 2.5.4.35

dn: uid=nd, ou=People, dc=scapy, dc=net
objectClass: top
objectClass: person
objectClass: inetOrgPerson
cn: Neil Dunbar
uid: nd
sn: Dunbar
givenName: Neil
userPassword: testpassword

dn: uid=ndadmin, ou=People, dc=scapy, dc=net
objectClass: top
objectClass: person
objectClass: inetOrgPerson
cn: Neil Dunbar (Admin)
uid: ndadmin
sn: Dunbar
givenName: Neil
userPassword: testpw

dn: uid=test, ou=People, dc=scapy, dc=net
objectClass: top
objectClass: person
objectClass: inetOrgPerson
cn: test test
uid: test
sn: Test
givenName: Test
userPassword: kfhgkjhfdgkfd
pwdPolicySubEntry: cn=No Policy, ou=Policies, dc=scapy, dc=net

dn: uid=another, ou=People, dc=scapy, dc=net
objectClass: top
objectClass: person
objectClass: inetOrgPerson
cn: Another Test
uid: another
sn: Test
givenName: Another
userPassword: testing

32 changes: 27 additions & 5 deletions doc/scapy/layers/ldap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ LDAP
Scapy fully implements the LDAPv2 / LDAPv3 messages, in addition to a very basic :class:`~scapy.layers.ldap.LDAP_Client` class.

.. warning::
*The String Representation of LDAP Search Filters* (RFC2254) is currently **unsupported**.
This means that you can't use the commonly known LDAP search syntax, and instead have to use the binary format.
PRs are welcome !
Scapy's LDAP client is currently read-only. PRs are welcome !


LDAP client usage
-----------------
Expand All @@ -16,6 +15,7 @@ The general idea when using the :class:`~scapy.layers.ldap.LDAP_Client` class co
- instantiating the class
- calling :func:`~scapy.layers.ldap.LDAP_Client.connect` with the IP (this is where to specify whether to use SSL or not)
- calling :func:`~scapy.layers.ldap.LDAP_Client.bind` (this is where to specify a SSP if authentication is desired)
- calling :func:`~scapy.layers.ldap.LDAP_Client.search` to search data.

The simplest, unauthenticated demo of the client would be something like:

Expand Down Expand Up @@ -172,9 +172,28 @@ Once the LDAP connection is bound, it becomes possible to perform requests. For
client.sr1(LDAP_SearchRequest()).show()
Querying more complicated requests is a bit tedious, as it *currently* requires you to build the Search request yourself.
We can also use the :func:`~scapy.layers.ldap.LDAP_Client.search` passing a base DN, a filter (as specified by RFC2254) and a scope.\\

The scope can be one of the following:

- 0=baseObject: only the base DN's attributes are queried
- 1=singleLevel: the base DN's children are queried
- 2=wholeSubtree: the entire subtree under the base DN is included

For instance, this corresponds to querying the DN ``CN=Users,DC=domain,DC=local`` with the filter ``(objectCategory=person)`` and asking for the attributes ``objectClass,name,description,canonicalName``:

.. code:: python
resp = client.search(
"CN=Users,DC=domain,DC=local",
"(objectCategory=person)",
["objectClass", "name", "description", "canonicalName"],
scope=1, # children
)
resp.show()
To understand exactly what's going on, note that the previous call is exactly identical to the following:

.. code:: python
resp = client.sr1(
Expand All @@ -199,4 +218,7 @@ For instance, this corresponds to querying the DN ``CN=Users,DC=domain,DC=local`
attrsOnly=ASN1_BOOLEAN(0)
)
)
resp.show()
.. warning::
Our RFC2254 parser currently does not support 'Extensible Match'.
5 changes: 1 addition & 4 deletions scapy/layers/dcerpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1686,9 +1686,6 @@ def i2h(self, pkt, x):
def h2i(self, pkt, x):
return x

# def i2count(self, pkt, x):
# return 1

def i2len(self, pkt, x):
if x is None:
return 0
Expand Down Expand Up @@ -2156,7 +2153,7 @@ def i2len(self, pkt, x):
def any2i(self, pkt, x):
# User-friendly helper
if self.conformant_in_struct:
return x
return super(_NDRConfField, self).any2i(pkt, x)
if self.CONFORMANT_STRING and not isinstance(x, NDRConformantString):
return NDRConformantString(
value=super(_NDRConfField, self).any2i(pkt, x),
Expand Down
Loading

0 comments on commit f7a6411

Please sign in to comment.