home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Networking / nmap-5.00-setup.exe / scripts / mysql-info.nse < prev    next >
Text File  |  2009-07-06  |  5KB  |  208 lines

  1. description = [[
  2. Connects to a MySQL server and prints information such as the protocol and
  3. version numbers, thread ID, status, capabilities, and the password salt.
  4.  
  5. If service detection is performed and the server appears to be blocking
  6. our host or is blocked because of too many connections, then this script
  7. isn't run (see the portrule).
  8. ]]
  9.  
  10. ---
  11. --@output
  12. -- 3306/tcp open  mysql
  13. -- |  mysql-info: Protocol: 10
  14. -- |  Version: 5.0.51a-3ubuntu5.1
  15. -- |  Thread ID: 7
  16. -- |  Some Capabilities: Connect with DB, Transactions, Secure Connection
  17. -- |  Status: Autocommit
  18. -- |_ Salt: bYyt\NQ/4V6IN+*3`imj
  19.  
  20. -- Many thanks to jah (jah@zadkiel.plus.com) for testing and enhancements
  21.  
  22. author = "Kris Katterjohn <katterjohn@gmail.com>"
  23.  
  24. license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
  25.  
  26. categories = { "default", "discovery", "safe" }
  27.  
  28. require 'bit'
  29. require 'comm'
  30.  
  31. --- Grabs NUL-terminated string
  32. --@param orig Start of the string
  33. --@return The NUL-terminated string
  34. local getstring = function(orig)
  35.     return orig:match("^([^%z]*)");
  36. end
  37.  
  38. --- Converts two bytes into a number
  39. --@param num Start of the two bytes
  40. --@return The converted number
  41. local ntohs = function(num)
  42.     local b1 = bit.band(num:byte(1), 255)
  43.     local b2 = bit.band(num:byte(2), 255)
  44.  
  45.     return bit.bor(b1, bit.lshift(b2, 8))
  46. end
  47.  
  48. --- Converts three bytes into a number
  49. --@param num Start of the three bytes
  50. --@return The converted number
  51. local ntoh3 = function(num)
  52.     local b1 = bit.band(num:byte(1), 255)
  53.     local b2 = bit.band(num:byte(2), 255)
  54.     local b3 = bit.band(num:byte(3), 255)
  55.  
  56.     return bit.bor(b1, bit.lshift(b2, 8), bit.lshift(b3, 16))
  57. end
  58.  
  59. --- Converts four bytes into a number
  60. --@param num Start of the four bytes
  61. --@return The converted number
  62. local ntohl = function(num)
  63.     local b1 = bit.band(num:byte(1), 255)
  64.     local b2 = bit.band(num:byte(2), 255)
  65.     local b3 = bit.band(num:byte(3), 255)
  66.     local b4 = bit.band(num:byte(4), 255)
  67.  
  68.     return bit.bor(b1, bit.lshift(b2, 8), bit.lshift(b3, 16), bit.lshift(b4, 24))
  69. end
  70.  
  71. --- Converts a number to a string description of the capabilities
  72. --@param num Start of the capabilities data
  73. --@return String describing the capabilities offered
  74. local capabilities = function(num)
  75.     local caps = ""
  76.  
  77.     if bit.band(num, 1) > 0 then
  78.         caps = caps .. "Long Passwords, "
  79.     end
  80.  
  81.     if bit.band(num, 8) > 0 then
  82.         caps = caps .. "Connect with DB, "
  83.     end
  84.  
  85.     if bit.band(num, 32) > 0 then
  86.         caps = caps .. "Compress, "
  87.     end
  88.  
  89.     if bit.band(num, 64) > 0 then
  90.         caps = caps .. "ODBC, "
  91.     end
  92.  
  93.     if bit.band(num, 2048) > 0 then
  94.         caps = caps .. "SSL, "
  95.     end
  96.  
  97.     if bit.band(num, 8192) > 0 then
  98.         caps = caps .. "Transactions, "
  99.     end
  100.  
  101.     if bit.band(num, 32768) > 0 then
  102.         caps = caps .. "Secure Connection, "
  103.     end
  104.  
  105.     return caps:gsub(", $", "")
  106. end
  107.  
  108. portrule = function(host, port)
  109.     local extra = port.version.extrainfo
  110.  
  111.     return (port.number == 3306 or port.service == "mysql")
  112.         and port.protocol == "tcp"
  113.         and port.state == "open"
  114.         and not (extra ~= nil
  115.             and (extra:match("[Uu]nauthorized")
  116.                 or extra:match("[Tt]oo many connection")))
  117. end
  118.  
  119. action = function(host, port)
  120.     local output = ""
  121.  
  122.     local status, response = comm.get_banner(host, port, {timeout=5000})
  123.  
  124.     if not status then
  125.         return
  126.     end
  127.  
  128.     local length = ntoh3(response:sub(1, 3))
  129.  
  130.     if length ~= response:len() - 4 then
  131.         return "Invalid greeting (Not MySQL?)"
  132.     end
  133.  
  134.     -- Keeps track of where we are in the binary data
  135.     local offset = 1 + 4
  136.  
  137.     local protocol = response:byte(offset)
  138.  
  139.     offset = offset + 1
  140.  
  141.     -- If a 0xff is here instead of the protocol, an error occurred.
  142.     -- Pass it along to the user..
  143.     if (protocol == 255) then
  144.         output = "MySQL Error detected!\n"
  145.  
  146.         local sqlerrno = ntohs(response:sub(offset, offset + 2))
  147.  
  148.         offset = offset + 2
  149.  
  150.         local sqlerrstr = response:sub(offset)
  151.  
  152.         output = output .. "Error Code was: " .. sqlerrno .. "\n"
  153.  
  154.         output = output .. sqlerrstr
  155.  
  156.         return output
  157.     end
  158.  
  159.     local version = getstring(response:sub(offset))
  160.  
  161.     offset = offset + version:len() + 1
  162.  
  163.     local threadid = ntohl(response:sub(offset, offset + 4))
  164.  
  165.     offset = offset + 4
  166.  
  167.     local salt = getstring(response:sub(offset))
  168.  
  169.     offset = offset + salt:len() + 1
  170.  
  171.     local caps = capabilities(ntohs(response:sub(offset, offset + 2)))
  172.  
  173.     offset = offset + 2
  174.  
  175.     offset = offset + 1
  176.  
  177.     local status = ""
  178.  
  179.     if ntohs(response:sub(offset, offset + 2)) == 2 then
  180.         status = "Autocommit"
  181.     end
  182.  
  183.     offset = offset + 2
  184.  
  185.     offset = offset + 13 -- unused
  186.  
  187.     if response:len() - offset + 1 == 13 then
  188.         salt = salt .. getstring(response:sub(offset))
  189.     end
  190.  
  191.     output = output .. "Protocol: " .. protocol .. "\n"
  192.     output = output .. "Version: " .. version .. "\n"
  193.     output = output .. "Thread ID: " .. threadid .. "\n"
  194.  
  195.     if caps:len() > 0 then
  196.         output = output .. "Some Capabilities: " .. caps .. "\n"
  197.     end
  198.  
  199.     if status:len() > 0 then
  200.         output = output .. "Status: " .. status .. "\n"
  201.     end
  202.  
  203.     output = output .. "Salt: " .. salt .. "\n"
  204.  
  205.     return output
  206. end
  207.  
  208.