I’ve been sitting on this for ages, but finally I’m using the Christmas break to complete this article about integration between Samba and my PHP NTLM script. The basic idea is that pdbedit -w someuser will emit the NT hash (MD4) of someuser. Using this knowledge we will be able to create a helper utility that verifies NTLMv2 hashes by calling on pdbedit. This helper utility I named verifyntlm. A key requirement for this to work is that the Apache/PHP process be in the same machine the samba user database is hosted on, which also means this is strictly for samba and not for Windows servers.
There is one issue though, which is that pdbedit requires root privileges to access the hash. It unreasonable to think that the apache/PHP could be run in root. The answer to this is to setuid verifyntlm to root such that verifyntlm will get elevated to root every time it gets executed by any user. It also why verifyntlm is written in C as setuid doesn’t not work for scripts. For this to be secure, verifyntlm must be watertight or else it can potentially be used for a root privilege escalation exploit. Maximum care was taken when coding with this but as with everything, I can’t guarantee absolutely security. The source code is for all to see though, so feel free to comb through it.
You would only use verifyntlm in conjunction with ntlm.php as expects parameters such as the user, challenge, hash etc which only ntlm.php provides. The program is designed to divulge as little information as possible, only 1 if successful, 0 for failure. This way in the event that an attacker gains access to the binary, they can gain no new information that’s not already gained through brute forcing a login prompt.
Prerequisites
verifyntlm.c requires:
- gcc – To compile the C file
- openssl (library & headers) – If using debian/ubuntu, run apt-get install libssl-dev
- Samba – Obviously, so we can execute pdbedit
Installation
You may need to modify PDBEDIT_PATH in verifyntlm.c to point to where pdbedit is if it’s not at /usr/bin/pdbedit
Login as root (or add sudo in front) to compile and set the sticky bit:
# gcc verifyntlm.c -lssl -o verifyntlm
# chown root verifyntlm
# chmod u=rwxs,g=x,o=x verifyntlm
Move the binary to a location such as /sbin/
# mv verifyntlm /sbin
If you put the binary somewhere else, please modify $ntlm_verifyntlmpath in ntlm.php.
Usage
After compiling the binary, jump out of root into a normal user and try running it without parameters. If it prints usage information, then you should be set.
On PHP side, here’s how to use it in your own PHP scripts:
[php]
session_start();
$auth = ntlm_prompt("testwebsite", "testdomain", "mycomputer", "testdomain.local", "mycomputer.local", null, "ntlm_verify_hash_smb");
if ($auth[‘authenticated’]) {
print "You are authenticated as $auth[username] from $auth[domain]/$auth[workstation]";
}
[/php]
As always, get the source from my php-ntlm github.
Unfortunately, if you’re looking to integrate PHP NTLM with Active Directory, this is not the article you’re looking for, you may be able to achieve it through winbind, another samba component, but that’s for another time.
Hy, thanks for your help. I’m trying to run example, but after compiling the verify.ntlm source i get the following error:
/usr/bin/ld: /tmp/cctLNNqq.o: undefined reference to symbol ‘EVP_md5’
/usr/bin/ld: note: ‘EVP_md5’ is defined in DSO /lib/libcrypto.so.10 so try adding it to the linker command line
/lib/libcrypto.so.10: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
Any ideea on what can i do ? I’m using Fedora 13 i686; and have installed openssl-devel which i think is the equivalent of what you posted for ubuntu.
Thank you in advance.
@Shadow try this command line:
gcc verifyntlm.c -lcrypto -o verifyntlm