Skip to content
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

Add KB for LDAP injection #113

Merged
merged 3 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions WEB_SERVICE/WEB/_HIGH/LDAP_INJECTION/description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
LDAP Injection involves exploiting web-based applications that generate LDAP statements using user input. In cases where an application fails to properly sanitize user input, attackers can manipulate LDAP statements by injecting special keywords into the query, an attack that is similar to SQL Injection.


=== Java
```java
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.*;

public class LDAPSearchExample {

public static void main(String[] args) {
// Input from the user (replace this with your own input mechanism)
String userInput = "username"; // User-supplied input

// LDAP connection parameters
String ldapURL = "ldap://your-ldap-server:389";
String baseDN = "ou=users,dc=example,dc=com"; // Replace with your base DN

// Set up the environment for creating the initial context
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapURL);

try {
// Create the initial context
LdapContext ctx = new InitialLdapContext(env, null);

// Specify the search filter
String searchFilter = "(uid=" + userInput + ")";

// Set the search controls
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

// Perform the search
NamingEnumeration<SearchResult> results = ctx.search(baseDN, searchFilter, searchControls);

// Iterate through the search results
while (results.hasMore()) {
SearchResult result = results.next();
// Process the result as needed (e.g., print attributes)
Attributes attributes = result.getAttributes();
System.out.println("User found: " + attributes.get("cn").get());
}

// Close the context
ctx.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
```

=== JavaScript
```javascript
const ldap = require('ldapjs');

const userInput = 'user123';
const ldapQuery = `(uid=${userInput})`; // Vulnerable to LDAP Injection

const client = ldap.createClient({
url: 'ldap://example.com:389'
});

client.search('ou=users,dc=example,dc=com', {
filter: ldapQuery,
}, (err, res) => {
// Process search results
res.on('searchEntry', (entry) => {
// Handle entry
});

res.on('error', (err) => {
console.error('Error:', err.message);
});
});
```

=== PHP
```php
<?php
// Vulnerable PHP code with LDAP Injection
$userInput = 'user123';
$ldapQuery = "(uid=$userInput)"; // Vulnerable to LDAP Injection

$ldapconn = ldap_connect("ldap://example.com");
ldap_bind($ldapconn, "cn=admin,dc=example,dc=com", "adminpassword");

$result = ldap_search($ldapconn, "ou=users,dc=example,dc=com", $ldapQuery);
$entries = ldap_get_entries($ldapconn, $result);

// Process search results
foreach ($entries as $entry) {
// Handle entry
}

ldap_close($ldapconn);
?>
```

27 changes: 27 additions & 0 deletions WEB_SERVICE/WEB/_HIGH/LDAP_INJECTION/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"risk_rating": "high",
"short_description": "The web application is vulnerable to an LDAP injection vulnerability.",
"references": {
"OWASP": "https://owasp.org/www-community/attacks/LDAP_Injection",
"OWASP cheatsheets":"https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html",
"Hacktricks": "https://book.hacktricks.xyz/pentesting-web/ldap-injection"
},
"title": "LDAP Injection",
"privacy_issue": false,
"security_issue": true,
"categories": {
"CWE_TOP_25": [
"CWE_90"
],
"GDPR": [
"ART_25",
"ART_32"
],
"PCI_STANDARDS":[
BlueSquare1 marked this conversation as resolved.
Show resolved Hide resolved
"REQ_6_2",
"REQ_6_3",
"REQ_6_4",
"REQ_6_5"
]
}
}
133 changes: 133 additions & 0 deletions WEB_SERVICE/WEB/_HIGH/LDAP_INJECTION/recommendation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
To mitigate the risk of LDAP injection, consider the following recommendations:

- __Parameterized Queries:__ Use parameterized queries instead of direct concatenation to construct LDAP queries.
BlueSquare1 marked this conversation as resolved.
Show resolved Hide resolved

- __Input Validation / Sanitization__: Implement input validation to ensure that user input adheres to expected formats and does not contain special characters that might alter LDAP queries, also sanitize user input using methods such as `LdapFilterEncode`

- __Use Frameworks that Automatically Protect from LDAP Injection:__ Utilize well-established and secure LDAP query APIs or libraries that automatically encode user input when building LDAP queries.

- __Enabling Bind Authentication__: Using bind authentication will limit the attack surface of the LDAP server if an attacker manages to perform LDAP injection.

- __Least Privilege__: Least Privilege principle is a rule of the thumb advice to minimize the impact of compromised services.

=== Java
```java
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.*;

public class LDAPSearchMitigatedExample {

public static void main(String[] args) {
// Input from the user (replace this with your own input mechanism)
String userInput = "username"; // User-supplied input

// LDAP connection parameters
String ldapURL = "ldap://your-ldap-server:389";
String baseDN = "ou=users,dc=example,dc=com"; // Replace with your base DN

// Set up the environment for creating the initial context
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapURL);

try {
// Create the initial context
LdapContext ctx = new InitialLdapContext(env, null);

// Use parameterized query to avoid LDAP injection
String searchFilter = "(uid={0})";
Object[] filterArgs = {userInput};

// Set the search controls
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

// Perform the search
NamingEnumeration<SearchResult> results = ctx.search(baseDN, searchFilter, filterArgs, searchControls);

// Iterate through the search results
while (results.hasMore()) {
SearchResult result = results.next();
// Process the result as needed (e.g., print attributes)
Attributes attributes = result.getAttributes();
System.out.println("User found: " + attributes.get("cn").get());
}

// Close the context
ctx.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
```

=== JavaScript
```javascript
// Mitigated JavaScript code with input validation and parameterized query
const ldap = require('ldapjs');

const userInput = 'user123';
// Perform input validation to ensure userInput is safe for LDAP query
if (isValidUserInput(userInput)) {
const ldapQuery = `(uid=${userInput})`;
const client = ldap.createClient({
url: 'ldap://example.com:389'
});

client.search('ou=users,dc=example,dc=com', {
filter: ldapQuery,
}, (err, res) => {
// Process search results
res.on('searchEntry', (entry) => {
// Handle entry
});

res.on('error', (err) => {
console.error('Error:', err.message);
});
});
} else {
console.log('Invalid userInput');
}

function isValidUserInput(userInput) {
// Implement proper input validation logic
// For example, check for allowed characters, length, etc.
return /^[a-zA-Z0-9]+$/.test(userInput);
}
```

=== PHP
```php
<?php
// Mitigated PHP code with input validation and parameterized query
$userInput = 'user123';
// Perform input validation to ensure userInput is safe for LDAP query
if (isValidUserInput($userInput)) {
$ldapQuery = "(uid=$userInput)";
$ldapconn = ldap_connect("ldap://example.com");
ldap_bind($ldapconn, "cn=admin,dc=example,dc=com");

$result = ldap_search($ldapconn, "ou=users,dc=example,dc=com", $ldapQuery);
$entries = ldap_get_entries($ldapconn, $result);

// Process search results
foreach ($entries as $entry) {
// Handle entry
}

ldap_close($ldapconn);
} else {
echo 'Invalid userInput';
}

function isValidUserInput($userInput) {
// Implement proper input validation logic
// For example, check for allowed characters, length, etc.
return preg_match('/^[a-zA-Z0-9]+$/', $userInput);
}
?>
```
Loading