Last active
July 2, 2020 14:03
-
-
Save abythell/4757703 to your computer and use it in GitHub Desktop.
Using Unbound LDAP and JCIFS, create SMB/NTLM and LDAP password hashes from plaintext, then update LDAP.
This file contains hidden or 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
| /* | |
| * Change passwords stored in LDAP | |
| * Copyright Andrew Bythell, [email protected] | |
| */ | |
| package com.angryelectron.ldap; | |
| import com.unboundid.ldap.sdk.*; | |
| import java.io.FileInputStream; | |
| import java.io.IOException; | |
| import java.io.UnsupportedEncodingException; | |
| import java.security.MessageDigest; | |
| import java.security.NoSuchAlgorithmException; | |
| import java.util.Properties; | |
| import jcifs.util.Base64; | |
| import jcifs.util.Hexdump; | |
| import jcifs.util.MD4; | |
| public class Password { | |
| private String message; | |
| private Properties properties = new Properties(); | |
| public Password() { | |
| try { | |
| properties.load(new FileInputStream("ldap.properties")); | |
| } catch (IOException ex) { | |
| message = ex.getMessage(); | |
| } | |
| } | |
| @Override | |
| public String getMessage() { | |
| return "LDAP Password: " + message; | |
| } | |
| @Override | |
| public boolean changePassword(String user, String passwd) { | |
| final String dnAuth = properties.getProperty("ldapAdminDN"); | |
| final String passAuth = properties.getProperty("ldapAdminPass"); | |
| final String dnUser = properties.getProperty("ldapUserRDN") + "=" + user + "," + properties.getProperty("ldapUserBase"); | |
| final String ldapServer = properties.getProperty("ldapServer"); | |
| final Integer ldapPort = Integer.parseInt(properties.getProperty("ldapPort")); | |
| //TODO: consider using SSL or TLS | |
| LDAPConnection connection = new LDAPConnection(); | |
| try { | |
| connection.connect(ldapServer, ldapPort); | |
| connection.bind(dnAuth, passAuth); | |
| //update NT password | |
| Modification modification = new Modification(ModificationType.REPLACE, "sambaNTPassword", hashNTPassword(passwd)); | |
| LDAPResult result = connection.modify(dnUser, modification); | |
| if (result.getResultCode() != ResultCode.SUCCESS) { | |
| message = result.getDiagnosticMessage(); | |
| return false; | |
| } | |
| //update Unix password | |
| modification = new Modification(ModificationType.REPLACE, "userPassword", hashMD5Password(passwd)); | |
| result = connection.modify(dnUser, modification); | |
| if (result.getResultCode() != ResultCode.SUCCESS) { | |
| message = result.getDiagnosticMessage(); | |
| return false; | |
| } | |
| } catch (Exception ex) { | |
| message = ex.getMessage(); | |
| return false; | |
| } | |
| message = "Password changed"; | |
| return true; | |
| } | |
| /** | |
| * Generate an NTLM password hash | |
| * Adapted from http://lists.samba.org/archive/jcifs/2010-October/009375.html) | |
| * Uses jcifs | |
| * @param plain text password | |
| * @return NTLM 24-bit ANSI hash | |
| */ | |
| private String hashNTPassword(String password) throws UnsupportedEncodingException { | |
| MD4 md4 = new MD4(); | |
| byte[] bpass = password.getBytes("UnicodeLittleUnmarked"); | |
| md4.engineUpdate(bpass, 0, bpass.length); | |
| byte[] hashbytes = md4.engineDigest(); | |
| String ntHash = Hexdump.toHexString(hashbytes, 0, hashbytes.length * 2); | |
| return ntHash; | |
| } | |
| /** | |
| * Generate an MD5 password hash for LDAP | |
| * First create a digest from the plain text password, then append the LDAP | |
| * crypto-prefix | |
| * @param plaintext password | |
| * @return MD5 hashed string | |
| */ | |
| private String hashMD5Password(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException { | |
| MessageDigest digest = MessageDigest.getInstance("MD5"); | |
| digest.update(password.getBytes("UTF8")); | |
| String md5Password = Base64.encode(digest.digest()); | |
| return "{MD5}" + md5Password; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment