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

  1. description = [[
  2. Determines whether the server supports obsolete and less secure SSL-v2, and discovers which ciphers it
  3. supports.
  4. ]]
  5.  
  6. ---
  7. --@output
  8. -- 443/tcp open   https   syn-ack
  9. -- |  sslv2: server still supports SSLv2
  10. -- |       SSL2_RC4_128_WITH_MD5
  11. -- |       SSL2_DES_192_EDE3_CBC_WITH_MD5
  12. -- |       SSL2_RC2_CBC_128_CBC_WITH_MD5
  13. -- |       SSL2_DES_64_CBC_WITH_MD5
  14. -- |       SSL2_RC4_128_EXPORT40_WITH_MD5
  15. -- |_      SSL2_RC2_CBC_128_CBC_WITH_MD5
  16.  
  17. author = "Matt <mb2263@bristol.ac.uk>"
  18. license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
  19.  
  20. categories = {"default", "safe"}
  21.  
  22. require "shortport"
  23.  
  24. local portfunction = shortport.port_or_service({443,993,995},{'https','imaps','pop3s'})
  25.  
  26. portrule = function( host, port )
  27.   return portfunction( host, port ) or port.version.service_tunnel == 'ssl'
  28. end
  29.  
  30. hex2dec = function(hex)
  31.  
  32.     local byte1, byte2;
  33.  
  34.     byte1 = string.byte(hex, 1);
  35.     byte2 = string.byte(hex, 2);
  36.  
  37.     if (byte1 == nil or byte2 == nil) then return 0; end;
  38.     
  39.     return (byte1 * 256) + byte2;
  40.  
  41. end
  42.  
  43. cyphers = function(cypher_list, len)
  44.  
  45. -- returns names of cyphers supported by the server
  46.  
  47.     local cypher;
  48.     local cypher_name;
  49.     local byte1, byte2, byte3;
  50.     local available_cyphers = "";
  51.     local idx = 0;
  52.  
  53.     local ssl_cyphers = {
  54. -- (cut down) table of codes with their corresponding cyphers.
  55. -- stolen from wireshark's 'epan/dissectors/packet-ssl-utils.h'
  56.         [0x010080] = "SSL2_RC4_128_WITH_MD5",
  57.         [0x020080] = "SSL2_RC4_128_EXPORT40_WITH_MD5",
  58.         [0x030080] = "SSL2_RC2_CBC_128_CBC_WITH_MD5",
  59.         [0x040080] = "SSL2_RC2_CBC_128_CBC_WITH_MD5",
  60.         [0x050080] = "SSL2_IDEA_128_CBC_WITH_MD5",
  61.         [0x060040] = "SSL2_DES_64_CBC_WITH_MD5",
  62.         [0x0700c0] = "SSL2_DES_192_EDE3_CBC_WITH_MD5",
  63.         [0x080080] = "SSL2_RC4_64_WITH_MD5",
  64.     };
  65.  
  66.     if (len == 0) then return "\tthe server didn't offer any cyphers"; end
  67. -- something's got broken along the way if these aren't equal
  68.     if (len ~= string.len(cypher_list)) then
  69.         return "";
  70.     end
  71.  
  72.     for idx = 1, len, 3 do
  73.         cypher = string.sub(cypher_list, idx, idx + 2);
  74.  
  75.         byte1 = string.byte(cypher, 1);
  76.         byte2 = string.byte(cypher, 2);
  77.         byte3 = string.byte(cypher, 3);
  78.  
  79.         cypher = (byte1 * 256 * 256) + (byte2 * 256) + byte3;
  80.  
  81.         cypher_name = ssl_cyphers[cypher];
  82.  
  83.         if (cypher_name == nil) then
  84.             cypher_name = "unknown cypher (" .. byte1 .. "-" .. byte2 .. "-" .. byte3 .. " dec)"
  85.         end
  86.  
  87.         -- Check for duplicate cyphers
  88.         if not available_cyphers:match("\t" .. cypher_name .. "\n") then
  89.             available_cyphers = available_cyphers .. "\t" .. cypher_name .. "\n";
  90.         end
  91.     end
  92.  
  93.     return available_cyphers
  94.  
  95. end
  96.  
  97. give_n_bytes = function(idx, n, str)
  98.  
  99. -- returns the next n bytes of a string
  100.  
  101.     if (idx + (n - 1) > string.len(str)) then
  102.         return (idx + n), string.rep(string.char(0x00), n);
  103.     end
  104.  
  105.     return (idx + n), string.sub(str, idx, (idx + (n - 1)) );
  106.  
  107. end
  108.  
  109. action = function(host, port)
  110.  
  111.     local socket = nmap.new_socket();
  112.     local status = true;
  113.     
  114.     local tmp;
  115.  
  116.     local idx = 3;    -- start reading after the end of the length record
  117.  
  118.     local return_string = "";
  119.     local available_cyphers = "";
  120.  
  121.     local ssl_v2_hello;
  122.     local server_hello;
  123.  
  124.     local server_hello_len;
  125.     local message_type;
  126.     local SID_hit;
  127.     local certificate_type;
  128.     local ssl_version;
  129.     local certificate_len;
  130.     local cyphers_len;
  131.     local certificate;
  132.     local connection_ID_len;
  133.     local cypher_list;
  134.     local connection_ID;
  135.  
  136. -- build client hello packet (contents stolen from
  137. -- http://mail.nessus.org/pipermail/plugins-writers/2004-October/msg00041.html )
  138.     local t = {};
  139.     table.insert(t, string.char(0x80, 0x31));
  140.     table.insert(t, string.char(0x01));
  141.     table.insert(t, string.char(0x00, 0x02));
  142.     table.insert(t, string.char(0x00, 0x18));
  143.     table.insert(t, string.char(0x00, 0x00));
  144.     table.insert(t, string.char(0x00, 0x10));
  145.     table.insert(t, string.char(0x07, 0x00, 0xc0));
  146.     table.insert(t, string.char(0x05, 0x00, 0x80));
  147.     table.insert(t, string.char(0x03, 0x00, 0x80));
  148.     table.insert(t, string.char(0x01, 0x00, 0x80));
  149.     table.insert(t, string.char(0x08, 0x00, 0x80));
  150.     table.insert(t, string.char(0x06, 0x00, 0x40));
  151.     table.insert(t, string.char(0x04, 0x00, 0x80));
  152.     table.insert(t, string.char(0x02, 0x00, 0x80));
  153.     table.insert(t, string.char(0xe4, 0xbd, 0x00, 0x00));
  154.     table.insert(t, string.char(0xa4, 0x41, 0xb6, 0x74));
  155.     table.insert(t, string.char(0x71, 0x2b, 0x27, 0x95));
  156.     table.insert(t, string.char(0x44, 0xc0, 0x3d, 0xc0));
  157.     ssl_v2_hello = table.concat(t, "")
  158.  
  159.     socket:connect(host.ip, port.number, "tcp");
  160.     socket:send(ssl_v2_hello);
  161.  
  162.     status, server_hello = socket:receive_bytes(2);
  163.  
  164.     if (not status) then
  165.         socket:close();
  166.         return;
  167.     end
  168.  
  169.     server_hello_len = string.sub(server_hello, 1, 2);
  170.     server_hello_len = hex2dec(server_hello_len);
  171. -- length record doesn't include its own length, and is "broken".
  172.     server_hello_len = server_hello_len - (128 * 256) + 2;
  173.  
  174. -- the hello needs to be at least 13 bytes long to be of any use
  175.     if (server_hello_len < 13) then
  176.         socket:close();
  177.         return;
  178.     end
  179. --try to get entire hello, if we don't already
  180.     if (string.len(server_hello) < server_hello_len) then
  181.         status, tmp = socket:receive_bytes(server_hello_len - string.len(server_hello));
  182.  
  183.         if (not status) then
  184.             socket:close();
  185.             return;
  186.         end
  187.  
  188.         server_hello = server_hello .. tmp;
  189.     end;
  190.  
  191.     socket:close();
  192.  
  193. -- split up server hello into components
  194.     idx, message_type =     give_n_bytes(idx, 1, server_hello);
  195.     idx, SID_hit =             give_n_bytes(idx, 1, server_hello);
  196.     idx, certificate_type =     give_n_bytes(idx, 1, server_hello);
  197.     idx, ssl_version =         give_n_bytes(idx, 2, server_hello);
  198.     idx, certificate_len =         give_n_bytes(idx, 2, server_hello);
  199.         certificate_len = hex2dec(certificate_len);
  200.     idx, cyphers_len =         give_n_bytes(idx, 2, server_hello);
  201.         cyphers_len = hex2dec(cyphers_len);
  202.     idx, connection_ID_len =     give_n_bytes(idx, 2, server_hello);
  203.         connection_ID_len = hex2dec(connection_ID_len);
  204.     idx, certificate =         give_n_bytes(idx, certificate_len, server_hello);
  205.     idx, cypher_list =         give_n_bytes(idx, cyphers_len, server_hello);
  206.     idx, connection_ID =         give_n_bytes(idx, connection_ID_len, server_hello);
  207.  
  208. -- some sanity checks:
  209. -- is response a server hello?
  210.     if (message_type ~= string.char(0x04)) then
  211.         return;
  212.     end
  213. -- is certificate in X.509 format?
  214.     if (certificate_type ~= string.char(0x01)) then
  215.         return;
  216.     end
  217.  
  218. -- actually run some tests:
  219.     if (ssl_version == string.char(0x00, 0x02)) then
  220.         return_string = "server still supports SSLv2\n";
  221.     end
  222.  
  223.     if (nmap.verbosity() > 1 or nmap.debugging() > 0) then
  224.         available_cyphers = cyphers(cypher_list, cyphers_len);
  225.     end
  226.  
  227.     if (    string.len(return_string) > 0
  228.     or    string.len(available_cyphers) > 0) then
  229.             return return_string .. available_cyphers;
  230.     else
  231.             return;
  232.     end
  233.  
  234. end
  235.