Nmap krb5-enum-users NSE Script


This page contains detailed information about how to use the krb5-enum-users NSE script. For list of all NSE scripts, visit the Nmap NSE Library.

Select:
Overview
Error Messages

Script Overview


Script source code: https://github.com/nmap/nmap/tree/master/scripts/krb5-enum-users.nse
Script categories: auth, intrusive
Target service / protocol: kerberos-sec, udp, tcp
Target network port(s): 88
List of CVEs: -

Script Description


The krb5-enum-users.nse script discovers valid usernames by brute force querying likely usernames against a Kerberos service. When an invalid username is requested the server will respond using the Kerberos error code KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, allowing us to determine that the user name was invalid. Valid user names will illicit either the TGT in a AS-REP response or the error KRB5KDC_ERR_PREAUTH_REQUIRED, signaling that the user is required to perform pre authentication.

The script should work against Active Directory and ? It needs a valid Kerberos REALM in order to operate.

Krb5-enum-users NSE Script Arguments


This is a full list of arguments supported by the krb5-enum-users.nse script:

krb5-enum-users.realm

This argument is required as it supplies the script with the Kerberos REALM against which to guess the user names.

passdb

The filename of an alternate password database. Default: nselib/data/passwords.lst

unpwdb.passlimit

The maximum number of passwords passwords will return (default unlimited).

unpwdb.timelimit

The maximum amount of time that any iterator will run before stopping. The value is in seconds by default and you can follow it with ms, s, m, or h for milliseconds, seconds, minutes, or hours. For example, unpwdb.timelimit=30m or unpwdb.timelimit=.5h for 30 minutes. The default depends on the timing template level (see the module description). Use the value 0 to disable the time limit.

unpwdb.userlimit

The maximum number of usernames usernames will return (default unlimited).

userdb

The filename of an alternate username database. Default: nselib/data/usernames.lst

- - -
To use these script arguments, add them to the Nmap command line using the --script-args arg1=value,[arg2=value,..] syntax. For example:

nmap --script=krb5-enum-users --script-args krb5-enum-users.realm=value,passdb=value <target>

Krb5-enum-users NSE Script Example Usage


Here's an example of how to use the krb5-enum-users.nse script:

nmap -p 88 --script krb5-enum-users --script-args krb5-enum-users.realm='test'

Krb5-enum-users NSE Script Example Output


Here's a sample output from the krb5-enum-users.nse script:

PORT   STATE SERVICE      REASON
88/tcp open  kerberos-sec syn-ack
| krb5-enum-users:
| Discovered Kerberos principals
|     administrator@test
|     mysql@test
|_    tomcat@test

Krb5-enum-users NSE Script Example XML Output


There is no sample XML output for this module. However, by providing the -oX <file> option, Nmap will produce a XML output and save it in the file.xml file.

Author


  • Patrik Karlsson

References


See Also


Visit Nmap NSE Library for more scripts.

The krb5-enum-users.nse script may fail with the following error messages. Check for the possible causes by using the code snippets highlighted below found in the script source code. This can often times help in identifying the root cause of the problem.

ERROR: Failed to connect to Kerberos service


Here is a relevant code snippet related to the "ERROR: Failed to connect to Kerberos service" error message:

299:	  local data = krb5:encodeASREQ(realm, user, port.protocol)
300:	  local socket = nmap.new_socket()
301:	  local status = socket:connect(host, port)
302:	
303:	  if ( not(status) ) then
304:	    return false, "ERROR: Failed to connect to Kerberos service"
305:	  end
306:	
307:	  socket:send(data)
308:	  status, data = socket:receive()
309:	

ERROR: Failed to receive result from Kerberos service


Here is a relevant code snippet related to the "ERROR: Failed to receive result from Kerberos service" error message:

308:	  status, data = socket:receive()
309:	
310:	  if ( port.protocol == 'tcp' ) then data = data:sub(5) end
311:	
312:	  if ( not(status) ) then
313:	    return false, "ERROR: Failed to receive result from Kerberos service"
314:	  end
315:	  socket:close()
316:	
317:	  local msg
318:	  status, msg = krb5:parseResult(data)

ERROR: Failed to parse the result returned from the Kerberos service


Here is a relevant code snippet related to the "ERROR: Failed to parse the result returned from the Kerberos service" error message:

316:	
317:	  local msg
318:	  status, msg = krb5:parseResult(data)
319:	
320:	  if ( not(status) ) then
321:	    return false, "ERROR: Failed to parse the result returned from the Kerberos service"
322:	  end
323:	
324:	  if ( msg and msg.error_code ) then
325:	    if ( msg.error_code == KRB5.ErrorMessages['KRB5KDC_ERR_PREAUTH_REQUIRED'] ) then
326:	      return true, "VALID"

Invalid Kerberos REALM


Here is a relevant code snippet related to the "Invalid Kerberos REALM" error message:

323:	
324:	  if ( msg and msg.error_code ) then
325:	    if ( msg.error_code == KRB5.ErrorMessages['KRB5KDC_ERR_PREAUTH_REQUIRED'] ) then
326:	      return true, "VALID"
327:	    elseif ( msg.error_code == KRB5.ErrorMessages['KDC_ERR_WRONG_REALM'] ) then
328:	      return false, "Invalid Kerberos REALM"
329:	    end
330:	  elseif ( msg.type == KRB5.MessageType['AS-REP'] ) then
331:	    return true, "VALID"
332:	  end
333:	  return true, "INVALID"

No Kerberos REALM was supplied, aborting ...


Here is a relevant code snippet related to the "No Kerberos REALM was supplied, aborting ..." error message:

366:	  local result = {}
367:	  local condvar = nmap.condvar(result)
368:	
369:	  -- did the user supply a realm
370:	  if ( not(realm) ) then
371:	    return fail("No Kerberos REALM was supplied, aborting ...")
372:	  end
373:	
374:	  -- does the realm appear to exist
375:	  if ( not(isValidRealm(host, port, realm)) ) then
376:	    return fail("Invalid Kerberos REALM, aborting ...")

Invalid Kerberos REALM, aborting ...


Here is a relevant code snippet related to the "Invalid Kerberos REALM, aborting ..." error message:

371:	    return fail("No Kerberos REALM was supplied, aborting ...")
372:	  end
373:	
374:	  -- does the realm appear to exist
375:	  if ( not(isValidRealm(host, port, realm)) ) then
376:	    return fail("Invalid Kerberos REALM, aborting ...")
377:	  end
378:	
379:	  -- load our user database from unpwdb
380:	  local status, usernames = unpwdb.usernames()
381:	  if( not(status) ) then return fail("Failed to load unpwdb usernames") end

Failed to load unpwdb usernames


Here is a relevant code snippet related to the "Failed to load unpwdb usernames" error message:

376:	    return fail("Invalid Kerberos REALM, aborting ...")
377:	  end
378:	
379:	  -- load our user database from unpwdb
380:	  local status, usernames = unpwdb.usernames()
381:	  if( not(status) ) then return fail("Failed to load unpwdb usernames") end
382:	
383:	  -- start as many threads as there are names in the list
384:	  local threads = {}
385:	  for user in usernames do
386:	    local co = stdnse.new_thread( checkUserThread, host, port, realm, user, result )

Version


This page has been created based on Nmap version 7.92.

Go back to menu.