ntlm.java
来自「Light in the box 抓取程序。 使用HttpClient」· Java 代码 · 共 566 行 · 第 1/2 页
JAVA
566 行
// Host offset (always 32). byte[] hostOff = convertShort(32); addByte(hostOff[0]); addByte(hostOff[1]); addByte((byte) 0); addByte((byte) 0); // Host String. addBytes(hostBytes); // Domain String. addBytes(domainBytes); return getResponse(); } /** * Extracts the server nonce out of the given message type 2. * * @param message the String containing the base64 encoded message. * @return an array of 8 bytes that the server sent to be used when * hashing the password. */ public byte[] parseType2Message(String message) { // Decode the message first. byte[] msg = Base64.decodeBase64(EncodingUtil.getBytes(message, DEFAULT_CHARSET)); byte[] nonce = new byte[8]; // The nonce is the 8 bytes starting from the byte in position 24. for (int i = 0; i < 8; i++) { nonce[i] = msg[i + 24]; } return nonce; } /** * Creates the type 3 message using the given server nonce. The type 3 message includes all the * information for authentication, host, domain, username and the result of encrypting the * nonce sent by the server using the user's password as the key. * * @param user The user name. This should not include the domain name. * @param password The password. * @param host The host that is originating the authentication request. * @param domain The domain to authenticate within. * @param nonce the 8 byte array the server sent. * @return The type 3 message. * @throws AuthenticationException If {@encrypt(byte[],byte[])} fails. */ public String getType3Message(String user, String password, String host, String domain, byte[] nonce) throws AuthenticationException { int ntRespLen = 0; int lmRespLen = 24; domain = domain.toUpperCase(); host = host.toUpperCase(); user = user.toUpperCase(); byte[] domainBytes = EncodingUtil.getBytes(domain, DEFAULT_CHARSET); byte[] hostBytes = EncodingUtil.getBytes(host, DEFAULT_CHARSET); byte[] userBytes = EncodingUtil.getBytes(user, credentialCharset); int domainLen = domainBytes.length; int hostLen = hostBytes.length; int userLen = userBytes.length; int finalLength = 64 + ntRespLen + lmRespLen + domainLen + userLen + hostLen; prepareResponse(finalLength); byte[] ntlmssp = EncodingUtil.getBytes("NTLMSSP", DEFAULT_CHARSET); addBytes(ntlmssp); addByte((byte) 0); addByte((byte) 3); addByte((byte) 0); addByte((byte) 0); addByte((byte) 0); // LM Resp Length (twice) addBytes(convertShort(24)); addBytes(convertShort(24)); // LM Resp Offset addBytes(convertShort(finalLength - 24)); addByte((byte) 0); addByte((byte) 0); // NT Resp Length (twice) addBytes(convertShort(0)); addBytes(convertShort(0)); // NT Resp Offset addBytes(convertShort(finalLength)); addByte((byte) 0); addByte((byte) 0); // Domain length (twice) addBytes(convertShort(domainLen)); addBytes(convertShort(domainLen)); // Domain offset. addBytes(convertShort(64)); addByte((byte) 0); addByte((byte) 0); // User Length (twice) addBytes(convertShort(userLen)); addBytes(convertShort(userLen)); // User offset addBytes(convertShort(64 + domainLen)); addByte((byte) 0); addByte((byte) 0); // Host length (twice) addBytes(convertShort(hostLen)); addBytes(convertShort(hostLen)); // Host offset addBytes(convertShort(64 + domainLen + userLen)); for (int i = 0; i < 6; i++) { addByte((byte) 0); } // Message length addBytes(convertShort(finalLength)); addByte((byte) 0); addByte((byte) 0); // Flags addByte((byte) 6); addByte((byte) 82); addByte((byte) 0); addByte((byte) 0); addBytes(domainBytes); addBytes(userBytes); addBytes(hostBytes); addBytes(hashPassword(password, nonce)); return getResponse(); } /** * Creates the LANManager and NT response for the given password using the * given nonce. * @param password the password to create a hash for. * @param nonce the nonce sent by the server. * @return The response. * @throws HttpException If {@link #encrypt(byte[],byte[])} fails. */ private byte[] hashPassword(String password, byte[] nonce) throws AuthenticationException { byte[] passw = EncodingUtil.getBytes(password.toUpperCase(), credentialCharset); byte[] lmPw1 = new byte[7]; byte[] lmPw2 = new byte[7]; int len = passw.length; if (len > 7) { len = 7; } int idx; for (idx = 0; idx < len; idx++) { lmPw1[idx] = passw[idx]; } for (; idx < 7; idx++) { lmPw1[idx] = (byte) 0; } len = passw.length; if (len > 14) { len = 14; } for (idx = 7; idx < len; idx++) { lmPw2[idx - 7] = passw[idx]; } for (; idx < 14; idx++) { lmPw2[idx - 7] = (byte) 0; } // Create LanManager hashed Password byte[] magic = { (byte) 0x4B, (byte) 0x47, (byte) 0x53, (byte) 0x21, (byte) 0x40, (byte) 0x23, (byte) 0x24, (byte) 0x25 }; byte[] lmHpw1; lmHpw1 = encrypt(lmPw1, magic); byte[] lmHpw2 = encrypt(lmPw2, magic); byte[] lmHpw = new byte[21]; for (int i = 0; i < lmHpw1.length; i++) { lmHpw[i] = lmHpw1[i]; } for (int i = 0; i < lmHpw2.length; i++) { lmHpw[i + 8] = lmHpw2[i]; } for (int i = 0; i < 5; i++) { lmHpw[i + 16] = (byte) 0; } // Create the responses. byte[] lmResp = new byte[24]; calcResp(lmHpw, nonce, lmResp); return lmResp; } /** * Takes a 21 byte array and treats it as 3 56-bit DES keys. The 8 byte * plaintext is encrypted with each key and the resulting 24 bytes are * stored in the results array. * * @param keys The keys. * @param plaintext The plain text to encrypt. * @param results Where the results are stored. * @throws AuthenticationException If {@link #encrypt(byte[],byte[])} fails. */ private void calcResp(byte[] keys, byte[] plaintext, byte[] results) throws AuthenticationException { byte[] keys1 = new byte[7]; byte[] keys2 = new byte[7]; byte[] keys3 = new byte[7]; for (int i = 0; i < 7; i++) { keys1[i] = keys[i]; } for (int i = 0; i < 7; i++) { keys2[i] = keys[i + 7]; } for (int i = 0; i < 7; i++) { keys3[i] = keys[i + 14]; } byte[] results1 = encrypt(keys1, plaintext); byte[] results2 = encrypt(keys2, plaintext); byte[] results3 = encrypt(keys3, plaintext); for (int i = 0; i < 8; i++) { results[i] = results1[i]; } for (int i = 0; i < 8; i++) { results[i + 8] = results2[i]; } for (int i = 0; i < 8; i++) { results[i + 16] = results3[i]; } } /** * Converts a given number to a two byte array in little endian order. * @param num the number to convert. * @return The byte representation of <i>num</i> in little endian order. */ private byte[] convertShort(int num) { byte[] val = new byte[2]; String hex = Integer.toString(num, 16); while (hex.length() < 4) { hex = "0" + hex; } String low = hex.substring(2, 4); String high = hex.substring(0, 2); val[0] = (byte) Integer.parseInt(low, 16); val[1] = (byte) Integer.parseInt(high, 16); return val; } /** * @return Returns the credentialCharset. */ public String getCredentialCharset() { return credentialCharset; } /** * @param credentialCharset The credentialCharset to set. */ public void setCredentialCharset(String credentialCharset) { this.credentialCharset = credentialCharset; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?