Skip to content
This repository has been archived by the owner on May 14, 2020. It is now read-only.

LDAP Injection Rule #276

Closed
dnkolegov opened this issue Jan 14, 2016 · 16 comments
Closed

LDAP Injection Rule #276

dnkolegov opened this issue Jan 14, 2016 · 16 comments
Assignees

Comments

@dnkolegov
Copy link

The following LDAP injection vectors from Alonso-Parada research are not detected by current LDAP Injection Rule:

  • foo)(sn=100
  • printer)(uid=*)
  • printer)(department=fa*)
  • printer)(department=*fa*)

Burp Suite uses the following vectors to test an LDAP Injection and they are also not detected:

  • eb9adbd87d)(sn=*
  • eb9adbd87d)!(sn=*
  • *)(sn=*
  • *)!(sn=*

Also it is not obvious the purpose of the top and middle parts of regular expression that check values beginning with (:

(?:\((?:\W*?(?:objectc(?:ategory|lass)|homedirectory|[gu]idnumber|cn)\b\W*?=|[^\w\x80-\xFF]*?[\!\&\|][^\w\x80-\xFF]*?\()) 

Which LDAP injection context is supposed here?

@dune73 dune73 self-assigned this Mar 6, 2016
@dune73
Copy link
Contributor

dune73 commented Mar 6, 2016

@dnkolegov : Let's try and get this sorted out.

Do you have the capacity to test any new rules proposed here? My ldap knowledge is fairly limited and I do not want to introduce false positives here.

I think together we can get it done.

@dnkolegov
Copy link
Author

I propose to consider the following regex:

^[^:\(\)\&\|\!\<\>\~]*\)(?:\((?:[^,\(\)\=\&\|\!\<\>\~]+[><~]?=|[&!|](?:\)|\()?)|\)\([\&\|\!]|[&!|]\([^\(\)\=\&\|\!\<\>\~]+[><~]?=[^:\(\)\&\|\!\<\>\~]*)

Tests:

foo)(sn=100
foo)(&)
documents)(security_level=*))(&(directory=documents
printer))(&
printer)(&
printer)(uid=*)
printer)(department=fa*)
printer)(groupType:1.2.840.113556.1.4.803:=2147483648)
printer)(department=*fa*)
*pri*nter*)(department=*fa*)
*)(objectClass=*))(&(objectClass=void
*)(objectClass=users))(&(objectClass=foo
void)(objectClass=users))(&(objectClass=void)
eb9adbd87d)(sn=*
eb9adbd87d)!(sn=*
*)(sn=*
*)!(sn=*
ka0x)(|(homedirectory=*)
5faa0382d747b754)(sn=*
5faa0382d747b754)!(sn=*
*)(uid=*))(|(uid=*
aaa*aaa)(groupType:1.2.840.113556.1.4.803:=2147483648)
aaa*aaa)(memberof:1.2.840.113556.1.4.1941:=cn=Group1,OU=groupsOU,DC=x)
aaa*aaa)(cn>=bob)
cn=Group1,OU=groupsOU,DC=x)(memberof:1.2.840.113556.1.4.1941:=cn=Group1,OU=groupsOU,DC=x)
cn=Group1,OU=groupsOU,DC=x)(memberof:1.2.840.113556.1.4.1941:=cn=Group1,OU=groupsOU,DC=x))(&(memberof:1.2.840.113556.1.4.1941:=cn=Group1,OU=groupsOU,DC=x)
eb9adbd87d)(userAccountControl:1.2.840.113556.1.4.803:=65536)

@dune73
Copy link
Contributor

dune73 commented Mar 9, 2016

Thank you. That looks remarkable.

So this is a list of attack strings and a regex, which detects them?

What about false positives?

@dnkolegov
Copy link
Author

I tested this regex only for some valid LDAP filters:

(&(objectCategory=computer)  (userAccountControl:1.2.840.113556.1.4.803:=8192))
(objectSID=S-1-5-21-73586283-152049171-839522115-1111)
(userAccountControl:1.2.840.113556.1.4.803:=67108864)(&(objectCategory=group)(groupType:1.2.840.113556.1.4.803:=2147483648))

@csanders-git
Copy link
Contributor

@dune73 i guess this never got added - it is great work though I think we should put it on the 3.1 list.

@dune73
Copy link
Contributor

dune73 commented Aug 11, 2016

I like this as well. But I think we need somebody with real ldap experience telling us, if FPs are likely.
LDAP traffic is rare so I totally see us ship this regex and kill some site with it.

@csanders-git csanders-git added this to the CRS v3.1.0 RC1 milestone Aug 11, 2016
@dnkolegov
Copy link
Author

Updated regex (fixed whitespaces):

^[^:\(\)\&\|\!\<\>\~]*\)\s*(?:\((?:[^,\(\)\=\&\|\!\<\>\~]+[><~]?=|\s*[&!|]\s*(?:\)|\()?\s*)|\)\s*\(\s*[\&\|\!]\s*|[&!|]\s*\([^\(\)\=\&\|\!\<\>\~]+[><~]?=[^:\(\)\&\|\!\<\>\~]*)

@lifeforms
Copy link
Contributor

@dune73
Copy link
Contributor

dune73 commented Dec 17, 2018

This is still not added and given our lack of knowledge for everything LDAP we would rely on @dnkolegov's word to go and include this into our rule set.

So @dnkolegov, are you actively using this rule on your server(s)? Any feedback with regards to false positives?

@dnkolegov
Copy link
Author

dnkolegov commented Dec 18, 2018

This rule was developed and used within a proprietary Positive Technologies' Application Firewall. I do not remember customer requests regarding this rule. But I have not been working there for 2 years, so I do not have actual information.

@dune73
Copy link
Contributor

dune73 commented Dec 18, 2018

Thank you for writing in again, @dnkolegov!

So what do we do guys: I see this as a new paranoia level 3 rule, or we drop the endeavour despite the good contribution by @dnkolegov because we simply lack the knowledge to support this.

@lifeforms
Copy link
Contributor

I would argue to bring back the rule in the default set (paranoia level 1). Vulnerability to LDAP injection may be somewhat rare, but nevertheless it's a well published attack class, I could see it being important to enterprise users, and even OWASP and Webappsec wikis have extensive pages on it.

The LDAP injection rule was present in CRS 2.x but removed, I have no data why, but I can't recall ever having operations trouble with the rule myself.

Our old rule was apparently not having enough coverage, but with the improvements by @dnkolegov
it's a good start, he has supplied material for adding unit tests, and if users turn up more payloads we can handle them incrementally.

A risk could be false positives, but we'll have our regular development cycle with the release candidates to flesh them out. We can be a little more bold at the start of a cycle, and if we run into trouble we can always put the rule in a higher paranoia level.

@dune73
Copy link
Contributor

dune73 commented Dec 25, 2018

OK. Let's do that. I'll prepare a PR.

@dune73
Copy link
Contributor

dune73 commented Mar 11, 2019

I've done the following rule now

SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ^[^:\(\)\&\|\!\<\>\~]*\)\s*(?:\((?:[^,\(\)\=\&\|\!\<\>\~]+[><~]?=|\s*[&!|]\s*(?:\)|\()?\s*)|\)\s*\(\s*[\&\|\!]\s*|[&!|]\s*\([^\(\)\=\&\|\!\<\>\~]+[><~]?=[^:\(\)\&\|\!\<\>\~]*)" \
    "id:921190,\
    phase:2,\
    block,\
    capture,\
    t:none,t:htmlEntityDecode,\
    msg:'LDAP Injection Attack',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-ldap',\
    tag:'platform-multi',\
    ctl:auditLogParts=+E,\
    ver:'OWASP_CRS/3.1.0',\
    severity:'CRITICAL',\
    setvar:'tx.msg=%{rule.msg}',\
    setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
    setvar:'tx.%{rule.id}-OWASP_CRS/LDAP_INJECTION-%{MATCHED_VAR_NAME}=%{tx.0}'"

Triggered with $> curl localhost -d "a=printer)(department=fa*)"

Question: Where do we put this. I've added it to 921, protocol attacks, but so far there are only http protocol attacks in this group. Other options?

@dune73
Copy link
Contributor

dune73 commented Feb 11, 2020

During the monthly CRS community chat, I re-confirmed my lifelong commitment to this problem and I promised to make this into a PR and get it merged.

Meeting minutes: #1671 (comment)

@dune73
Copy link
Contributor

dune73 commented May 5, 2020

A long story comes to an end. We merged the fix for this with PR #1707.

Thank you for your contribution @dnkolegov.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants