librex 0.0.13 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (435) hide show
  1. data/README.markdown +1 -1
  2. data/Rakefile +1 -0
  3. metadata +3 -435
  4. data/lib/rex/LICENSE +0 -29
  5. data/lib/rex/arch.rb +0 -103
  6. data/lib/rex/arch/sparc.rb +0 -75
  7. data/lib/rex/arch/sparc.rb.ut.rb +0 -18
  8. data/lib/rex/arch/x86.rb +0 -513
  9. data/lib/rex/arch/x86.rb.ut.rb +0 -93
  10. data/lib/rex/assembly/nasm.rb +0 -104
  11. data/lib/rex/assembly/nasm.rb.ut.rb +0 -22
  12. data/lib/rex/codepage.map +0 -104
  13. data/lib/rex/compat.rb +0 -311
  14. data/lib/rex/constants.rb +0 -113
  15. data/lib/rex/elfparsey.rb +0 -11
  16. data/lib/rex/elfparsey/elf.rb +0 -123
  17. data/lib/rex/elfparsey/elfbase.rb +0 -258
  18. data/lib/rex/elfparsey/exceptions.rb +0 -27
  19. data/lib/rex/elfscan.rb +0 -12
  20. data/lib/rex/elfscan/scanner.rb +0 -207
  21. data/lib/rex/elfscan/search.rb +0 -46
  22. data/lib/rex/encoder/alpha2.rb +0 -31
  23. data/lib/rex/encoder/alpha2/alpha_mixed.rb +0 -68
  24. data/lib/rex/encoder/alpha2/alpha_upper.rb +0 -79
  25. data/lib/rex/encoder/alpha2/generic.rb +0 -114
  26. data/lib/rex/encoder/alpha2/unicode_mixed.rb +0 -117
  27. data/lib/rex/encoder/alpha2/unicode_upper.rb +0 -129
  28. data/lib/rex/encoder/ndr.rb +0 -89
  29. data/lib/rex/encoder/ndr.rb.ut.rb +0 -44
  30. data/lib/rex/encoder/nonalpha.rb +0 -61
  31. data/lib/rex/encoder/nonupper.rb +0 -64
  32. data/lib/rex/encoder/xdr.rb +0 -106
  33. data/lib/rex/encoder/xdr.rb.ut.rb +0 -29
  34. data/lib/rex/encoder/xor.rb +0 -69
  35. data/lib/rex/encoder/xor/dword.rb +0 -13
  36. data/lib/rex/encoder/xor/dword_additive.rb +0 -13
  37. data/lib/rex/encoders/xor_dword.rb +0 -35
  38. data/lib/rex/encoders/xor_dword_additive.rb +0 -53
  39. data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +0 -12
  40. data/lib/rex/encoding/xor.rb +0 -20
  41. data/lib/rex/encoding/xor.rb.ts.rb +0 -14
  42. data/lib/rex/encoding/xor/byte.rb +0 -15
  43. data/lib/rex/encoding/xor/byte.rb.ut.rb +0 -21
  44. data/lib/rex/encoding/xor/dword.rb +0 -21
  45. data/lib/rex/encoding/xor/dword.rb.ut.rb +0 -15
  46. data/lib/rex/encoding/xor/dword_additive.rb +0 -92
  47. data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +0 -15
  48. data/lib/rex/encoding/xor/exceptions.rb +0 -17
  49. data/lib/rex/encoding/xor/generic.rb +0 -146
  50. data/lib/rex/encoding/xor/generic.rb.ut.rb +0 -120
  51. data/lib/rex/encoding/xor/qword.rb +0 -15
  52. data/lib/rex/encoding/xor/word.rb +0 -21
  53. data/lib/rex/encoding/xor/word.rb.ut.rb +0 -13
  54. data/lib/rex/exceptions.rb +0 -275
  55. data/lib/rex/exceptions.rb.ut.rb +0 -44
  56. data/lib/rex/exploitation/cmdstager.rb +0 -9
  57. data/lib/rex/exploitation/cmdstager/base.rb +0 -175
  58. data/lib/rex/exploitation/cmdstager/debug_asm.rb +0 -142
  59. data/lib/rex/exploitation/cmdstager/debug_write.rb +0 -136
  60. data/lib/rex/exploitation/cmdstager/tftp.rb +0 -63
  61. data/lib/rex/exploitation/cmdstager/vbs.rb +0 -128
  62. data/lib/rex/exploitation/egghunter.rb +0 -277
  63. data/lib/rex/exploitation/egghunter.rb.ut.rb +0 -25
  64. data/lib/rex/exploitation/encryptjs.rb +0 -77
  65. data/lib/rex/exploitation/heaplib.js.b64 +0 -331
  66. data/lib/rex/exploitation/heaplib.rb +0 -94
  67. data/lib/rex/exploitation/javascriptosdetect.rb +0 -897
  68. data/lib/rex/exploitation/obfuscatejs.rb +0 -335
  69. data/lib/rex/exploitation/omelet.rb +0 -320
  70. data/lib/rex/exploitation/omelet.rb.ut.rb +0 -13
  71. data/lib/rex/exploitation/opcodedb.rb +0 -818
  72. data/lib/rex/exploitation/opcodedb.rb.ut.rb +0 -279
  73. data/lib/rex/exploitation/seh.rb +0 -92
  74. data/lib/rex/exploitation/seh.rb.ut.rb +0 -19
  75. data/lib/rex/file.rb +0 -112
  76. data/lib/rex/file.rb.ut.rb +0 -16
  77. data/lib/rex/image_source.rb +0 -12
  78. data/lib/rex/image_source/disk.rb +0 -60
  79. data/lib/rex/image_source/image_source.rb +0 -46
  80. data/lib/rex/image_source/memory.rb +0 -37
  81. data/lib/rex/io/bidirectional_pipe.rb +0 -157
  82. data/lib/rex/io/datagram_abstraction.rb +0 -35
  83. data/lib/rex/io/stream.rb +0 -319
  84. data/lib/rex/io/stream_abstraction.rb +0 -197
  85. data/lib/rex/io/stream_server.rb +0 -211
  86. data/lib/rex/job_container.rb +0 -187
  87. data/lib/rex/logging.rb +0 -4
  88. data/lib/rex/logging/log_dispatcher.rb +0 -179
  89. data/lib/rex/logging/log_sink.rb +0 -42
  90. data/lib/rex/logging/sinks/flatfile.rb +0 -55
  91. data/lib/rex/logging/sinks/stderr.rb +0 -43
  92. data/lib/rex/machparsey.rb +0 -9
  93. data/lib/rex/machparsey/exceptions.rb +0 -34
  94. data/lib/rex/machparsey/mach.rb +0 -209
  95. data/lib/rex/machparsey/machbase.rb +0 -408
  96. data/lib/rex/machscan.rb +0 -9
  97. data/lib/rex/machscan/scanner.rb +0 -217
  98. data/lib/rex/mime.rb +0 -9
  99. data/lib/rex/mime/header.rb +0 -77
  100. data/lib/rex/mime/message.rb +0 -144
  101. data/lib/rex/mime/part.rb +0 -20
  102. data/lib/rex/nop/opty2.rb +0 -108
  103. data/lib/rex/nop/opty2.rb.ut.rb +0 -23
  104. data/lib/rex/nop/opty2_tables.rb +0 -300
  105. data/lib/rex/ole.rb +0 -205
  106. data/lib/rex/ole/clsid.rb +0 -47
  107. data/lib/rex/ole/difat.rb +0 -141
  108. data/lib/rex/ole/directory.rb +0 -231
  109. data/lib/rex/ole/direntry.rb +0 -240
  110. data/lib/rex/ole/docs/dependencies.txt +0 -8
  111. data/lib/rex/ole/docs/references.txt +0 -1
  112. data/lib/rex/ole/fat.rb +0 -99
  113. data/lib/rex/ole/header.rb +0 -204
  114. data/lib/rex/ole/minifat.rb +0 -77
  115. data/lib/rex/ole/propset.rb +0 -144
  116. data/lib/rex/ole/samples/create_ole.rb +0 -27
  117. data/lib/rex/ole/samples/dir.rb +0 -35
  118. data/lib/rex/ole/samples/dump_stream.rb +0 -34
  119. data/lib/rex/ole/samples/ole_info.rb +0 -23
  120. data/lib/rex/ole/storage.rb +0 -395
  121. data/lib/rex/ole/stream.rb +0 -53
  122. data/lib/rex/ole/substorage.rb +0 -49
  123. data/lib/rex/ole/util.rb +0 -157
  124. data/lib/rex/parser/arguments.rb +0 -97
  125. data/lib/rex/parser/arguments.rb.ut.rb +0 -67
  126. data/lib/rex/parser/ini.rb +0 -185
  127. data/lib/rex/parser/ini.rb.ut.rb +0 -29
  128. data/lib/rex/parser/ip360_aspl_xml.rb +0 -102
  129. data/lib/rex/parser/ip360_xml.rb +0 -93
  130. data/lib/rex/parser/nessus_xml.rb +0 -118
  131. data/lib/rex/parser/netsparker_xml.rb +0 -94
  132. data/lib/rex/parser/nexpose_xml.rb +0 -131
  133. data/lib/rex/parser/nmap_xml.rb +0 -121
  134. data/lib/rex/parser/retina_xml.rb +0 -109
  135. data/lib/rex/payloads.rb +0 -1
  136. data/lib/rex/payloads/win32.rb +0 -2
  137. data/lib/rex/payloads/win32/common.rb +0 -26
  138. data/lib/rex/payloads/win32/kernel.rb +0 -53
  139. data/lib/rex/payloads/win32/kernel/common.rb +0 -54
  140. data/lib/rex/payloads/win32/kernel/migration.rb +0 -12
  141. data/lib/rex/payloads/win32/kernel/recovery.rb +0 -50
  142. data/lib/rex/payloads/win32/kernel/stager.rb +0 -194
  143. data/lib/rex/peparsey.rb +0 -12
  144. data/lib/rex/peparsey/exceptions.rb +0 -32
  145. data/lib/rex/peparsey/pe.rb +0 -212
  146. data/lib/rex/peparsey/pe_memdump.rb +0 -63
  147. data/lib/rex/peparsey/pebase.rb +0 -1680
  148. data/lib/rex/peparsey/section.rb +0 -136
  149. data/lib/rex/pescan.rb +0 -13
  150. data/lib/rex/pescan/analyze.rb +0 -309
  151. data/lib/rex/pescan/scanner.rb +0 -206
  152. data/lib/rex/pescan/search.rb +0 -56
  153. data/lib/rex/platforms.rb +0 -1
  154. data/lib/rex/platforms/windows.rb +0 -51
  155. data/lib/rex/poly.rb +0 -132
  156. data/lib/rex/poly/block.rb +0 -477
  157. data/lib/rex/poly/register.rb +0 -100
  158. data/lib/rex/poly/register/x86.rb +0 -40
  159. data/lib/rex/post.rb +0 -8
  160. data/lib/rex/post/dir.rb +0 -51
  161. data/lib/rex/post/file.rb +0 -172
  162. data/lib/rex/post/file_stat.rb +0 -220
  163. data/lib/rex/post/gen.pl +0 -13
  164. data/lib/rex/post/io.rb +0 -182
  165. data/lib/rex/post/meterpreter.rb +0 -4
  166. data/lib/rex/post/meterpreter/channel.rb +0 -445
  167. data/lib/rex/post/meterpreter/channel_container.rb +0 -54
  168. data/lib/rex/post/meterpreter/channels/pool.rb +0 -160
  169. data/lib/rex/post/meterpreter/channels/pools/file.rb +0 -62
  170. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +0 -103
  171. data/lib/rex/post/meterpreter/channels/stream.rb +0 -87
  172. data/lib/rex/post/meterpreter/client.rb +0 -364
  173. data/lib/rex/post/meterpreter/client_core.rb +0 -274
  174. data/lib/rex/post/meterpreter/dependencies.rb +0 -3
  175. data/lib/rex/post/meterpreter/extension.rb +0 -32
  176. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +0 -58
  177. data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +0 -16
  178. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +0 -94
  179. data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +0 -21
  180. data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +0 -57
  181. data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +0 -15
  182. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +0 -118
  183. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +0 -61
  184. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +0 -111
  185. data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +0 -28
  186. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +0 -101
  187. data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +0 -26
  188. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +0 -333
  189. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +0 -282
  190. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +0 -266
  191. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +0 -103
  192. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +0 -48
  193. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +0 -144
  194. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +0 -73
  195. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +0 -56
  196. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +0 -137
  197. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +0 -180
  198. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +0 -167
  199. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +0 -208
  200. data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +0 -6
  201. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +0 -38106
  202. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb.ut.rb +0 -31
  203. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +0 -47
  204. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb.ut.rb +0 -36
  205. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +0 -1818
  206. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +0 -96
  207. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +0 -3848
  208. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +0 -26
  209. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +0 -153
  210. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +0 -21
  211. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +0 -3169
  212. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +0 -599
  213. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +0 -318
  214. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +0 -100
  215. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb +0 -42
  216. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +0 -148
  217. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb.ut.rb +0 -127
  218. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +0 -309
  219. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +0 -204
  220. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +0 -51
  221. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +0 -630
  222. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +0 -75
  223. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb.ut.rb +0 -103
  224. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +0 -149
  225. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +0 -97
  226. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +0 -192
  227. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +0 -41
  228. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +0 -61
  229. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +0 -370
  230. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +0 -129
  231. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +0 -55
  232. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +0 -336
  233. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +0 -141
  234. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +0 -279
  235. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +0 -193
  236. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +0 -102
  237. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +0 -180
  238. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +0 -211
  239. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +0 -227
  240. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +0 -63
  241. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +0 -30
  242. data/lib/rex/post/meterpreter/object_aliases.rb +0 -83
  243. data/lib/rex/post/meterpreter/packet.rb +0 -688
  244. data/lib/rex/post/meterpreter/packet_dispatcher.rb +0 -431
  245. data/lib/rex/post/meterpreter/packet_parser.rb +0 -94
  246. data/lib/rex/post/meterpreter/packet_response_waiter.rb +0 -83
  247. data/lib/rex/post/meterpreter/ui/console.rb +0 -137
  248. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +0 -62
  249. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +0 -730
  250. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +0 -108
  251. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +0 -241
  252. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +0 -231
  253. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +0 -61
  254. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +0 -98
  255. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +0 -51
  256. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +0 -132
  257. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +0 -187
  258. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +0 -65
  259. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +0 -442
  260. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +0 -298
  261. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +0 -486
  262. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +0 -315
  263. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +0 -157
  264. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +0 -95
  265. data/lib/rex/post/permission.rb +0 -26
  266. data/lib/rex/post/process.rb +0 -57
  267. data/lib/rex/post/thread.rb +0 -57
  268. data/lib/rex/post/ui.rb +0 -52
  269. data/lib/rex/proto.rb +0 -13
  270. data/lib/rex/proto.rb.ts.rb +0 -8
  271. data/lib/rex/proto/dcerpc.rb +0 -6
  272. data/lib/rex/proto/dcerpc.rb.ts.rb +0 -9
  273. data/lib/rex/proto/dcerpc/client.rb +0 -361
  274. data/lib/rex/proto/dcerpc/client.rb.ut.rb +0 -491
  275. data/lib/rex/proto/dcerpc/exceptions.rb +0 -150
  276. data/lib/rex/proto/dcerpc/handle.rb +0 -47
  277. data/lib/rex/proto/dcerpc/handle.rb.ut.rb +0 -85
  278. data/lib/rex/proto/dcerpc/ndr.rb +0 -72
  279. data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +0 -41
  280. data/lib/rex/proto/dcerpc/packet.rb +0 -253
  281. data/lib/rex/proto/dcerpc/packet.rb.ut.rb +0 -56
  282. data/lib/rex/proto/dcerpc/response.rb +0 -187
  283. data/lib/rex/proto/dcerpc/response.rb.ut.rb +0 -15
  284. data/lib/rex/proto/dcerpc/uuid.rb +0 -84
  285. data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +0 -46
  286. data/lib/rex/proto/dhcp.rb +0 -7
  287. data/lib/rex/proto/dhcp/constants.rb +0 -33
  288. data/lib/rex/proto/dhcp/server.rb +0 -292
  289. data/lib/rex/proto/drda.rb +0 -5
  290. data/lib/rex/proto/drda.rb.ts.rb +0 -17
  291. data/lib/rex/proto/drda/constants.rb +0 -49
  292. data/lib/rex/proto/drda/constants.rb.ut.rb +0 -23
  293. data/lib/rex/proto/drda/packet.rb +0 -252
  294. data/lib/rex/proto/drda/packet.rb.ut.rb +0 -109
  295. data/lib/rex/proto/drda/utils.rb +0 -123
  296. data/lib/rex/proto/drda/utils.rb.ut.rb +0 -84
  297. data/lib/rex/proto/http.rb +0 -5
  298. data/lib/rex/proto/http.rb.ts.rb +0 -12
  299. data/lib/rex/proto/http/client.rb +0 -821
  300. data/lib/rex/proto/http/client.rb.ut.rb +0 -95
  301. data/lib/rex/proto/http/handler.rb +0 -46
  302. data/lib/rex/proto/http/handler/erb.rb +0 -128
  303. data/lib/rex/proto/http/handler/erb.rb.ut.rb +0 -21
  304. data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +0 -1
  305. data/lib/rex/proto/http/handler/proc.rb +0 -60
  306. data/lib/rex/proto/http/handler/proc.rb.ut.rb +0 -24
  307. data/lib/rex/proto/http/header.rb +0 -161
  308. data/lib/rex/proto/http/header.rb.ut.rb +0 -46
  309. data/lib/rex/proto/http/packet.rb +0 -407
  310. data/lib/rex/proto/http/packet.rb.ut.rb +0 -165
  311. data/lib/rex/proto/http/request.rb +0 -356
  312. data/lib/rex/proto/http/request.rb.ut.rb +0 -214
  313. data/lib/rex/proto/http/response.rb +0 -90
  314. data/lib/rex/proto/http/response.rb.ut.rb +0 -149
  315. data/lib/rex/proto/http/server.rb +0 -369
  316. data/lib/rex/proto/http/server.rb.ut.rb +0 -79
  317. data/lib/rex/proto/ntlm.rb +0 -7
  318. data/lib/rex/proto/ntlm.rb.ut.rb +0 -177
  319. data/lib/rex/proto/ntlm/base.rb +0 -326
  320. data/lib/rex/proto/ntlm/constants.rb +0 -74
  321. data/lib/rex/proto/ntlm/crypt.rb +0 -415
  322. data/lib/rex/proto/ntlm/exceptions.rb +0 -9
  323. data/lib/rex/proto/ntlm/message.rb +0 -533
  324. data/lib/rex/proto/ntlm/utils.rb +0 -763
  325. data/lib/rex/proto/proxy/socks4a.rb +0 -440
  326. data/lib/rex/proto/rfb.rb +0 -19
  327. data/lib/rex/proto/rfb.rb.ut.rb +0 -37
  328. data/lib/rex/proto/rfb/cipher.rb +0 -84
  329. data/lib/rex/proto/rfb/client.rb +0 -207
  330. data/lib/rex/proto/rfb/constants.rb +0 -52
  331. data/lib/rex/proto/smb.rb +0 -7
  332. data/lib/rex/proto/smb.rb.ts.rb +0 -8
  333. data/lib/rex/proto/smb/client.rb +0 -1952
  334. data/lib/rex/proto/smb/client.rb.ut.rb +0 -223
  335. data/lib/rex/proto/smb/constants.rb +0 -1047
  336. data/lib/rex/proto/smb/constants.rb.ut.rb +0 -18
  337. data/lib/rex/proto/smb/crypt.rb +0 -36
  338. data/lib/rex/proto/smb/evasions.rb +0 -66
  339. data/lib/rex/proto/smb/exceptions.rb +0 -858
  340. data/lib/rex/proto/smb/simpleclient.rb +0 -306
  341. data/lib/rex/proto/smb/simpleclient.rb.ut.rb +0 -128
  342. data/lib/rex/proto/smb/utils.rb +0 -103
  343. data/lib/rex/proto/smb/utils.rb.ut.rb +0 -20
  344. data/lib/rex/proto/sunrpc.rb +0 -1
  345. data/lib/rex/proto/sunrpc/client.rb +0 -195
  346. data/lib/rex/proto/tftp.rb +0 -12
  347. data/lib/rex/proto/tftp/constants.rb +0 -39
  348. data/lib/rex/proto/tftp/server.rb +0 -497
  349. data/lib/rex/proto/tftp/server.rb.ut.rb +0 -28
  350. data/lib/rex/script.rb +0 -42
  351. data/lib/rex/script/base.rb +0 -59
  352. data/lib/rex/script/meterpreter.rb +0 -15
  353. data/lib/rex/script/shell.rb +0 -9
  354. data/lib/rex/service.rb +0 -48
  355. data/lib/rex/service_manager.rb +0 -141
  356. data/lib/rex/service_manager.rb.ut.rb +0 -32
  357. data/lib/rex/services/local_relay.rb +0 -423
  358. data/lib/rex/socket.rb +0 -684
  359. data/lib/rex/socket.rb.ut.rb +0 -107
  360. data/lib/rex/socket/comm.rb +0 -119
  361. data/lib/rex/socket/comm/local.rb +0 -412
  362. data/lib/rex/socket/comm/local.rb.ut.rb +0 -75
  363. data/lib/rex/socket/ip.rb +0 -130
  364. data/lib/rex/socket/parameters.rb +0 -345
  365. data/lib/rex/socket/parameters.rb.ut.rb +0 -51
  366. data/lib/rex/socket/range_walker.rb +0 -346
  367. data/lib/rex/socket/range_walker.rb.ut.rb +0 -55
  368. data/lib/rex/socket/ssl_tcp.rb +0 -184
  369. data/lib/rex/socket/ssl_tcp.rb.ut.rb +0 -39
  370. data/lib/rex/socket/ssl_tcp_server.rb +0 -122
  371. data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +0 -61
  372. data/lib/rex/socket/subnet_walker.rb +0 -75
  373. data/lib/rex/socket/subnet_walker.rb.ut.rb +0 -28
  374. data/lib/rex/socket/switch_board.rb +0 -278
  375. data/lib/rex/socket/switch_board.rb.ut.rb +0 -52
  376. data/lib/rex/socket/tcp.rb +0 -76
  377. data/lib/rex/socket/tcp.rb.ut.rb +0 -64
  378. data/lib/rex/socket/tcp_server.rb +0 -67
  379. data/lib/rex/socket/tcp_server.rb.ut.rb +0 -44
  380. data/lib/rex/socket/udp.rb +0 -164
  381. data/lib/rex/socket/udp.rb.ut.rb +0 -44
  382. data/lib/rex/struct2.rb +0 -5
  383. data/lib/rex/struct2/c_struct.rb +0 -181
  384. data/lib/rex/struct2/c_struct_template.rb +0 -39
  385. data/lib/rex/struct2/constant.rb +0 -26
  386. data/lib/rex/struct2/element.rb +0 -44
  387. data/lib/rex/struct2/generic.rb +0 -73
  388. data/lib/rex/struct2/restraint.rb +0 -54
  389. data/lib/rex/struct2/s_string.rb +0 -72
  390. data/lib/rex/struct2/s_struct.rb +0 -111
  391. data/lib/rex/sync.rb +0 -6
  392. data/lib/rex/sync/event.rb +0 -94
  393. data/lib/rex/sync/read_write_lock.rb +0 -176
  394. data/lib/rex/sync/ref.rb +0 -57
  395. data/lib/rex/sync/thread_safe.rb +0 -82
  396. data/lib/rex/test.rb +0 -35
  397. data/lib/rex/text.rb +0 -1149
  398. data/lib/rex/text.rb.ut.rb +0 -190
  399. data/lib/rex/thread_factory.rb +0 -42
  400. data/lib/rex/time.rb +0 -65
  401. data/lib/rex/transformer.rb +0 -115
  402. data/lib/rex/transformer.rb.ut.rb +0 -38
  403. data/lib/rex/ui.rb +0 -21
  404. data/lib/rex/ui/interactive.rb +0 -254
  405. data/lib/rex/ui/output.rb +0 -78
  406. data/lib/rex/ui/output/none.rb +0 -18
  407. data/lib/rex/ui/progress_tracker.rb +0 -96
  408. data/lib/rex/ui/subscriber.rb +0 -149
  409. data/lib/rex/ui/text/color.rb +0 -97
  410. data/lib/rex/ui/text/color.rb.ut.rb +0 -18
  411. data/lib/rex/ui/text/dispatcher_shell.rb +0 -467
  412. data/lib/rex/ui/text/input.rb +0 -117
  413. data/lib/rex/ui/text/input/buffer.rb +0 -75
  414. data/lib/rex/ui/text/input/readline.rb +0 -129
  415. data/lib/rex/ui/text/input/socket.rb +0 -95
  416. data/lib/rex/ui/text/input/stdio.rb +0 -45
  417. data/lib/rex/ui/text/irb_shell.rb +0 -57
  418. data/lib/rex/ui/text/output.rb +0 -80
  419. data/lib/rex/ui/text/output/buffer.rb +0 -61
  420. data/lib/rex/ui/text/output/file.rb +0 -43
  421. data/lib/rex/ui/text/output/socket.rb +0 -43
  422. data/lib/rex/ui/text/output/stdio.rb +0 -40
  423. data/lib/rex/ui/text/progress_tracker.rb +0 -56
  424. data/lib/rex/ui/text/progress_tracker.rb.ut.rb +0 -34
  425. data/lib/rex/ui/text/shell.rb +0 -328
  426. data/lib/rex/ui/text/table.rb +0 -279
  427. data/lib/rex/ui/text/table.rb.ut.rb +0 -55
  428. data/lib/rex/zip.rb +0 -93
  429. data/lib/rex/zip/archive.rb +0 -184
  430. data/lib/rex/zip/blocks.rb +0 -182
  431. data/lib/rex/zip/entry.rb +0 -104
  432. data/lib/rex/zip/samples/comment.rb +0 -32
  433. data/lib/rex/zip/samples/mkwar.rb +0 -138
  434. data/lib/rex/zip/samples/mkzip.rb +0 -19
  435. data/lib/rex/zip/samples/recursive.rb +0 -58
@@ -1,37 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- ##
4
- # $Id: $
5
- ##
6
-
7
- ##
8
- #
9
- # RFB protocol support
10
- #
11
- # by Joshua J. Drake <jduck>
12
- #
13
- # Based on:
14
- # vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
15
- # vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
16
- #
17
- ##
18
-
19
- require 'rex/socket'
20
- require 'rex/proto/rfb'
21
-
22
- sd = Rex::Socket::Tcp.create('PeerHost' => ENV["VNCHOST"], 'PeerPort' => Rex::Proto::RFB::DefaultPort)
23
-
24
- v = Rex::Proto::RFB::Client.new(sd)
25
- if not v.connect('password')
26
- $stderr.puts v.error
27
- exit(1)
28
- end
29
-
30
- loop {
31
- sret = select([sd],nil,nil,10)
32
- puts sret.inspect
33
- if sret and sret[0].include? sd
34
- buf = sd.sysread(8192)
35
- puts "read #{buf.length} bytes: #{buf.inspect}"
36
- end
37
- }
@@ -1,84 +0,0 @@
1
- ##
2
- # $Id: $
3
- ##
4
-
5
- ##
6
- #
7
- # RFB protocol support
8
- #
9
- # by Joshua J. Drake <jduck>
10
- #
11
- # Based on:
12
- # vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
13
- # vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
14
- #
15
- ##
16
-
17
- # Required for VNC authentication
18
- require 'openssl'
19
-
20
- module Rex
21
- module Proto
22
- module RFB
23
-
24
- ##
25
- # A bit of information about the DES algorithm was found here:
26
- # http://www.vidarholen.net/contents/junk/vnc.html
27
- #
28
- # In addition, VNC uses two individual 8 byte block encryptions rather than
29
- # using any block mode (like cbc, ecb, etc).
30
- ##
31
-
32
- class Cipher
33
-
34
- def self.mangle_password(password)
35
- key = ''
36
- key = password.dup if password
37
- key.slice!(8,key.length) if key.length > 8
38
- key << "\x00" * (8 - key.length) if key.length < 8
39
-
40
- # We have to mangle the key so the LSB are kept vs the MSB
41
- [key.unpack('B*').first.scan(/.{8}/).map! { |e| e.reverse }.join].pack('B*')
42
- end
43
-
44
- def self.encrypt(plain, password)
45
- key = self.mangle_password(password)
46
-
47
- # pad the plain to 16 chars
48
- plain << ("\x00" * (16 - plain.length)) if plain.length < 16
49
-
50
- # VNC auth does two 8-byte blocks individually instead supporting some block mode
51
- cipher = ''
52
- 2.times { |x|
53
- c = OpenSSL::Cipher::Cipher.new('des')
54
- c.encrypt
55
- c.key = key
56
- cipher << c.update(plain[x*8, 8])
57
- }
58
-
59
- cipher
60
- end
61
-
62
- #
63
- # NOTE: The default password is that of winvnc/etc which is used for
64
- # encrypting the password(s) on disk/in registry.
65
- #
66
- def self.decrypt(cipher, password = "\x17\x52\x6b\x06\x23\x4e\x58\x07")
67
- key = self.mangle_password(password)
68
-
69
- # pad the cipher text to 9 bytes
70
- cipher << ("\x00" * (9 - cipher.length)) if cipher.length < 9
71
-
72
- # NOTE: This only does one 8 byte block
73
- plain = ''
74
- c = OpenSSL::Cipher::Cipher.new('des')
75
- c.decrypt
76
- c.key = key
77
- c.update(cipher)
78
- end
79
-
80
- end
81
-
82
- end
83
- end
84
- end
@@ -1,207 +0,0 @@
1
- ##
2
- # $Id: $
3
- ##
4
-
5
- ##
6
- #
7
- # RFB protocol support
8
- #
9
- # by Joshua J. Drake <jduck>
10
- #
11
- # Based on:
12
- # vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
13
- # vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
14
- #
15
- # TODO: determine how to detect a view-only session.
16
- ##
17
-
18
- module Rex
19
- module Proto
20
- module RFB
21
-
22
- class Client
23
-
24
- def initialize(sock, opts = {})
25
- @sock = sock
26
- @opts = opts
27
-
28
- @banner = nil
29
- @majver = MajorVersion
30
- @minver = -1
31
- @auth_types = []
32
- end
33
-
34
- def read_error_message
35
- len = @sock.get_once(4)
36
- return 'Unknown error' if not len or len.length != 4
37
-
38
- len = len.unpack("N").first
39
- @sock.get_once(len)
40
- end
41
-
42
- def handshake
43
- @banner = @sock.get_once(12)
44
- if not @banner
45
- @error = "Unable to obtain banner from server"
46
- return false
47
- end
48
-
49
- # RFB Protocol Version 3.3 (1998-01)
50
- # RFB Protocol Version 3.7 (2003-08)
51
- # RFB Protocol Version 3.8 (2007-06)
52
-
53
- if @banner =~ /RFB ([0-9]{3})\.([0-9]{3})/
54
- maj = $1.to_i
55
- if maj != MajorVersion
56
- @error = "Invalid major version number: #{maj}"
57
- return false
58
- end
59
- else
60
- @error = "Invalid RFB banner: #{@banner}"
61
- return false
62
- end
63
-
64
- @minver = $2.to_i
65
-
66
- our_ver = "RFB %03d.%03d\n" % [MajorVersion, @minver]
67
- @sock.put(our_ver)
68
-
69
- true
70
- end
71
-
72
- def connect(password = nil)
73
- return false if not handshake
74
- return false if not authenticate(password)
75
- return false if not send_client_init
76
- true
77
- end
78
-
79
- def send_client_init
80
- if @opts[:exclusive]
81
- @sock.put("\x00") # do share.
82
- else
83
- @sock.put("\x01") # do share.
84
- end
85
- end
86
-
87
- def authenticate(password = nil)
88
- type = negotiate_authentication
89
- return false if not type
90
-
91
- # Authenticate.
92
- case type
93
- when AuthType::None
94
- # Nothing here.
95
-
96
- when AuthType::VNC
97
- return false if not negotiate_vnc_auth(password)
98
-
99
- end
100
-
101
- # Handle reading the security result message
102
- result = @sock.get_once(4)
103
- if not result
104
- @error = "Unable to read auth result"
105
- return false
106
- end
107
-
108
- result = result.unpack('N').first
109
- case result
110
- when 0
111
- return true
112
-
113
- when 1
114
- if @minver >= 8
115
- msg = read_error_message
116
- @error = "Authentication failed: #{msg}"
117
- else
118
- @error = "Authentication failed"
119
- end
120
- when 2
121
- @error = "Too many authentication attempts"
122
- else
123
- @error = "Unknown authentication result: #{result}"
124
- end
125
-
126
- false
127
- end
128
-
129
- def negotiate_authentication
130
- # Authentication type negotiation is protocol version specific.
131
- if @minver < 7
132
- buf = @sock.get_once(4)
133
- if not buf
134
- @error = "Unable to obtain requested authentication method"
135
- return nil
136
- end
137
- @auth_types = buf.unpack('N')
138
- if not @auth_types or @auth_types.first == 0
139
- msg = read_error_message
140
- @error = "No authentication types available: #{msg}"
141
- return nil
142
- end
143
- else
144
- buf = @sock.get_once(1)
145
- if not buf
146
- @error = "Unable to obtain supported authentication method count"
147
- return nil
148
- end
149
-
150
- # first byte is number of security types
151
- num_types = buf.unpack("C").first
152
- if (num_types == 0)
153
- msg = read_error_message
154
- @error = "No authentication types available: #{msg}"
155
- return nil
156
- end
157
-
158
- buf = @sock.get_once(num_types)
159
- if not buf or buf.length != num_types
160
- @error = "Unable to read authentication types"
161
- return nil
162
- end
163
-
164
- @auth_types = buf.unpack("C*")
165
- end
166
-
167
- if not @auth_types or @auth_types.length < 1
168
- @error = "No authentication types found"
169
- return nil
170
- end
171
-
172
- # Select the one we prefer
173
- selected = nil
174
- selected ||= AuthType::None if @opts[:allow_none] and @auth_types.include? AuthType::None
175
- selected ||= AuthType::VNC if @auth_types.include? AuthType::VNC
176
-
177
- if not selected
178
- @error = "No supported authentication method found."
179
- return nil
180
- end
181
-
182
- # For 3.7 and later, clients must state which security-type to use
183
- @sock.put([selected].pack('C')) if @minver >= 7
184
-
185
- selected
186
- end
187
-
188
- def negotiate_vnc_auth(password = nil)
189
- challenge = @sock.get_once(16)
190
- if not challenge or challenge.length != 16
191
- @error = "Unable to obtain VNC challenge"
192
- return false
193
- end
194
-
195
- response = Cipher.encrypt(challenge, password)
196
- @sock.put(response)
197
-
198
- true
199
- end
200
-
201
- attr_reader :error, :majver, :minver, :auth_types
202
- attr_reader :view_only
203
- end
204
-
205
- end
206
- end
207
- end
@@ -1,52 +0,0 @@
1
- ##
2
- # $Id: $
3
- ##
4
-
5
- ##
6
- #
7
- # RFB protocol support
8
- #
9
- # by Joshua J. Drake <jduck>
10
- #
11
- # Based on:
12
- # vnc_auth_none contributed by Matteo Cantoni <goony[at]nothink.org>
13
- # vnc_auth_login contributed by carstein <carstein.sec[at]gmail.com>
14
- #
15
- ##
16
-
17
- module Rex
18
- module Proto
19
- module RFB
20
-
21
- DefaultPort = 5900
22
-
23
- # Version information
24
- MajorVersion = 3
25
- # NOTE: We will emulate whatever minor version the server reports.
26
-
27
- # Security types
28
- class AuthType
29
- Invalid = 0
30
- None = 1
31
- VNC = 2
32
- RA2 = 5
33
- RA2ne = 6
34
- Tight = 16
35
- Ultra = 17
36
- TLS = 18
37
- VeNCrypt = 19
38
- GtkVncSasl = 20
39
- MD5Hash = 21
40
- ColinDeanXVP = 22
41
-
42
- def self.to_s(num)
43
- self.constants.each { |c|
44
- return c.to_s if self.const_get(c) == num
45
- }
46
- 'Unknown'
47
- end
48
- end
49
-
50
- end
51
- end
52
- end
data/lib/rex/proto/smb.rb DELETED
@@ -1,7 +0,0 @@
1
- require 'rex/proto/smb/constants'
2
- require 'rex/proto/smb/exceptions'
3
- require 'rex/proto/smb/evasions'
4
- require 'rex/proto/smb/crypt'
5
- require 'rex/proto/smb/utils'
6
- require 'rex/proto/smb/client'
7
- require 'rex/proto/smb/simpleclient'
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rex/test'
4
- require 'rex/proto/smb/client.rb.ut.rb'
5
- require 'rex/proto/smb/constants.rb.ut.rb'
6
- require 'rex/proto/smb/crypt.rb.ut.rb'
7
- require 'rex/proto/smb/simpleclient.rb.ut.rb'
8
- require 'rex/proto/smb/utils.rb.ut.rb'
@@ -1,1952 +0,0 @@
1
- module Rex
2
- module Proto
3
- module SMB
4
- class Client
5
-
6
- require 'rex/text'
7
- require 'rex/struct2'
8
- require 'rex/proto/smb/constants'
9
- require 'rex/proto/smb/exceptions'
10
- require 'rex/proto/smb/evasions'
11
- require 'rex/proto/smb/utils'
12
- require 'rex/proto/smb/crypt'
13
- require 'rex/proto/ntlm/crypt'
14
- require 'rex/proto/ntlm/constants'
15
- require 'rex/proto/ntlm/utils'
16
-
17
-
18
- # Some short-hand class aliases
19
- CONST = Rex::Proto::SMB::Constants
20
- CRYPT = Rex::Proto::SMB::Crypt
21
- UTILS = Rex::Proto::SMB::Utils
22
- XCEPT = Rex::Proto::SMB::Exceptions
23
- EVADE = Rex::Proto::SMB::Evasions
24
- NTLM_CRYPT = Rex::Proto::NTLM::Crypt
25
- NTLM_CONST = Rex::Proto::NTLM::Constants
26
- NTLM_UTILS = Rex::Proto::NTLM::Utils
27
-
28
- def initialize(socket)
29
- self.socket = socket
30
- self.native_os = 'Windows 2000 2195'
31
- self.native_lm = 'Windows 2000 5.0'
32
- self.encrypt_passwords = true
33
- self.extended_security = false
34
- self.multiplex_id = rand(0xffff)
35
- self.process_id = rand(0xffff)
36
- self.read_timeout = 10
37
- self.evasion_opts = {
38
-
39
- # Padding is performed between packet headers and data
40
- 'pad_data' => EVADE::EVASION_NONE,
41
-
42
- # File path padding is performed on all open/create calls
43
- 'pad_file' => EVADE::EVASION_NONE,
44
-
45
- # Modify the \PIPE\ string in trans_named_pipe calls
46
- 'obscure_trans_pipe' => EVADE::EVASION_NONE,
47
- }
48
-
49
- self.verify_signature = false
50
- self.use_ntlmv2 = false
51
- self.usentlm2_session = true
52
- self.send_lm = true
53
- self.use_lanman_key = false
54
- self.send_ntlm = true
55
-
56
- # Signing
57
- self.sequence_counter = 0
58
- self.signing_key = ''
59
- self.require_signing = false
60
-
61
- #Misc
62
- self.spnopt = {}
63
-
64
- end
65
-
66
- # Read a SMB packet from the socket
67
- def smb_recv
68
-
69
- data = socket.timed_read(4, self.read_timeout)
70
- if (data.nil? or data.length < 4)
71
- raise XCEPT::NoReply
72
- end
73
-
74
- recv_len = data[2,2].unpack('n')[0]
75
- if (recv_len == 0)
76
- return data
77
- end
78
-
79
- recv_len += 4
80
-
81
- while (data.length != recv_len)
82
- buff = ''
83
-
84
- begin
85
- buff << self.socket.timed_read(recv_len - data.length, self.read_timeout)
86
- rescue Timeout::Error
87
- rescue
88
- raise XCEPT::ReadPacket
89
- end
90
-
91
- if (buff.nil? or buff.length == 0)
92
- raise XCEPT::ReadPacket
93
- end
94
-
95
- data << buff
96
- end
97
-
98
- #signing
99
- if self.require_signing && self.signing_key != ''
100
- if self.verify_signature
101
- raise XCEPT::IncorrectSigningError if not CRYPT::is_signature_correct?(self.signing_key,self.sequence_counter,data)
102
- end
103
- self.sequence_counter += 1
104
- end
105
-
106
- return data
107
-
108
-
109
- end
110
-
111
- # Send a SMB packet down the socket
112
- def smb_send(data, evasion_level=0)
113
-
114
- # evasion_level is ignored, since real evasion happens
115
- # in the actual socket layer
116
-
117
- size = 0
118
- wait = 0
119
-
120
- #signing
121
- if self.require_signing && self.signing_key != ''
122
- data = CRYPT::sign_smb_packet(self.signing_key, self.sequence_counter, data)
123
- self.sequence_counter += 1
124
- end
125
-
126
- begin
127
- # Just send the packet and return
128
- if (size == 0 or size >= data.length)
129
- return self.socket.put(data)
130
- end
131
-
132
- # Break the packet up into chunks and wait between them
133
- ret = 0
134
- while ( (chunk = data.slice!(0, size)).length > 0 )
135
- ret = self.socket.put(chunk)
136
- if (wait > 0)
137
- ::IO.select(nil, nil, nil, wait)
138
- end
139
- end
140
- return ret
141
- end
142
- end
143
-
144
- # Set the SMB parameters to some reasonable defaults
145
- def smb_defaults(packet)
146
- packet.v['MultiplexID'] = self.multiplex_id.to_i
147
- packet.v['TreeID'] = self.last_tree_id.to_i
148
- packet.v['UserID'] = self.auth_user_id.to_i
149
- packet.v['ProcessID'] = self.process_id.to_i
150
- end
151
-
152
-
153
- # The main dispatcher for all incoming SMB packets
154
- def smb_recv_parse(expected_type, ignore_errors = false)
155
-
156
- # This will throw an exception if it fails to read the whole packet
157
- data = self.smb_recv
158
-
159
- pkt = CONST::SMB_BASE_PKT.make_struct
160
- pkt.from_s(data)
161
- res = pkt
162
-
163
- begin
164
- case pkt['Payload']['SMB'].v['Command']
165
-
166
- when CONST::SMB_COM_NEGOTIATE
167
- res = smb_parse_negotiate(pkt, data)
168
-
169
- when CONST::SMB_COM_SESSION_SETUP_ANDX
170
- res = smb_parse_session_setup(pkt, data)
171
-
172
- when CONST::SMB_COM_TREE_CONNECT_ANDX
173
- res = smb_parse_tree_connect(pkt, data)
174
-
175
- when CONST::SMB_COM_TREE_DISCONNECT
176
- res = smb_parse_tree_disconnect(pkt, data)
177
-
178
- when CONST::SMB_COM_NT_CREATE_ANDX
179
- res = smb_parse_create(pkt, data)
180
-
181
- when CONST::SMB_COM_TRANSACTION, CONST::SMB_COM_TRANSACTION2
182
- res = smb_parse_trans(pkt, data)
183
-
184
- when CONST::SMB_COM_NT_TRANSACT
185
- res = smb_parse_nttrans(pkt, data)
186
-
187
- when CONST::SMB_COM_NT_TRANSACT_SECONDARY
188
- res = smb_parse_nttrans(pkt, data)
189
-
190
- when CONST::SMB_COM_OPEN_ANDX
191
- res = smb_parse_open(pkt, data)
192
-
193
- when CONST::SMB_COM_WRITE_ANDX
194
- res = smb_parse_write(pkt, data)
195
-
196
- when CONST::SMB_COM_READ_ANDX
197
- res = smb_parse_read(pkt, data)
198
-
199
- when CONST::SMB_COM_CLOSE
200
- res = smb_parse_close(pkt, data)
201
-
202
- when CONST::SMB_COM_DELETE
203
- res = smb_parse_delete(pkt, data)
204
-
205
- else
206
- raise XCEPT::InvalidCommand
207
- end
208
-
209
- if (pkt['Payload']['SMB'].v['Command'] != expected_type)
210
- raise XCEPT::InvalidType
211
- end
212
-
213
- if (ignore_errors == false and pkt['Payload']['SMB'].v['ErrorClass'] != 0)
214
- raise XCEPT::ErrorCode
215
- end
216
-
217
- rescue XCEPT::InvalidWordCount, XCEPT::InvalidCommand, XCEPT::InvalidType, XCEPT::ErrorCode
218
- $!.word_count = pkt['Payload']['SMB'].v['WordCount']
219
- $!.command = pkt['Payload']['SMB'].v['Command']
220
- $!.error_code = pkt['Payload']['SMB'].v['ErrorClass']
221
- raise $!
222
- end
223
-
224
- return res
225
- end
226
-
227
- # Process incoming SMB_COM_NEGOTIATE packets
228
- def smb_parse_negotiate(pkt, data)
229
- #Process NTLM negotiate responses
230
- if (pkt['Payload']['SMB'].v['WordCount'] == 17)
231
- res = CONST::SMB_NEG_RES_NT_PKT.make_struct
232
- res.from_s(data)
233
- return res
234
- end
235
-
236
- # Process LANMAN negotiate responses
237
- if (pkt['Payload']['SMB'].v['WordCount'] == 13)
238
- res = CONST::SMB_NEG_RES_LM_PKT.make_struct
239
- res.from_s(data)
240
- return res
241
- end
242
-
243
- # Process ERROR negotiate responses
244
- if (pkt['Payload']['SMB'].v['WordCount'] == 1)
245
- res = CONST::SMB_NEG_RES_ERR_PKT.make_struct
246
- res.from_s(data)
247
- return res
248
- end
249
-
250
- # Process SMB error responses
251
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
252
- return pkt
253
- end
254
-
255
- raise XCEPT::InvalidWordCount
256
- end
257
-
258
- # Process incoming SMB_COM_SESSION_SETUP_ANDX packets
259
- def smb_parse_session_setup(pkt, data)
260
- # Process NTLMSSP negotiate responses
261
- if (pkt['Payload']['SMB'].v['WordCount'] == 4)
262
- res = CONST::SMB_SETUP_NTLMV2_RES_PKT.make_struct
263
- res.from_s(data)
264
- return res
265
- end
266
-
267
- # Process LANMAN responses
268
- if (pkt['Payload']['SMB'].v['WordCount'] == 3)
269
- res = CONST::SMB_SETUP_RES_PKT.make_struct
270
- res.from_s(data)
271
- return res
272
- end
273
-
274
- # Process SMB error responses
275
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
276
- return pkt
277
- end
278
-
279
- raise XCEPT::InvalidWordCount
280
- end
281
-
282
- # Process incoming SMB_COM_TREE_CONNECT_ANDX packets
283
- def smb_parse_tree_connect(pkt, data)
284
-
285
- if (pkt['Payload']['SMB'].v['WordCount'] == 3)
286
- res = CONST::SMB_TREE_CONN_RES_PKT.make_struct
287
- res.from_s(data)
288
- return res
289
- end
290
-
291
- # Process SMB error responses
292
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
293
- return pkt
294
- end
295
-
296
- raise XCEPT::InvalidWordCount
297
- end
298
-
299
- # Process incoming SMB_COM_TREE_DISCONNECT packets
300
- def smb_parse_tree_disconnect(pkt, data)
301
-
302
- # Process SMB responses
303
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
304
- res = CONST::SMB_TREE_DISCONN_RES_PKT.make_struct
305
- res.from_s(data)
306
- return res
307
- end
308
-
309
- raise XCEPT::InvalidWordCount
310
- end
311
-
312
- # Process incoming SMB_COM_NT_CREATE_ANDX packets
313
- def smb_parse_create(pkt, data)
314
-
315
- # Windows says 42, but Samba says 34, same structure :-/
316
- if (pkt['Payload']['SMB'].v['WordCount'] == 42)
317
- res = CONST::SMB_CREATE_RES_PKT.make_struct
318
- res.from_s(data)
319
- return res
320
- end
321
-
322
- if (pkt['Payload']['SMB'].v['WordCount'] == 34)
323
- res = CONST::SMB_CREATE_RES_PKT.make_struct
324
- res.from_s(data)
325
- return res
326
- end
327
-
328
- # Process SMB error responses
329
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
330
- return pkt
331
- end
332
-
333
- raise XCEPT::InvalidWordCount
334
- end
335
-
336
- # Process incoming SMB_COM_TRANSACTION packets
337
- def smb_parse_trans(pkt, data)
338
-
339
- if (pkt['Payload']['SMB'].v['WordCount'] == 10)
340
- res = CONST::SMB_TRANS_RES_PKT.make_struct
341
- res.from_s(data)
342
- return res
343
- end
344
-
345
- # Process SMB error responses
346
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
347
- return pkt
348
- end
349
-
350
- raise XCEPT::InvalidWordCount
351
- end
352
-
353
- # Process incoming SMB_COM_NT_TRANSACT packets
354
- def smb_parse_nttrans(pkt, data)
355
-
356
- # Process SMB error responses
357
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
358
- return pkt
359
- end
360
-
361
- if (pkt['Payload']['SMB'].v['WordCount'] >= 18)
362
- res = CONST::SMB_NTTRANS_RES_PKT.make_struct
363
- res.from_s(data)
364
- return res
365
- end
366
-
367
- raise XCEPT::InvalidWordCount
368
- end
369
-
370
- # Process incoming SMB_COM_OPEN_ANDX packets
371
- def smb_parse_open(pkt, data)
372
- # Process open responses
373
- if (pkt['Payload']['SMB'].v['WordCount'] == 15)
374
- res = CONST::SMB_OPEN_RES_PKT.make_struct
375
- res.from_s(data)
376
- return res
377
- end
378
-
379
- # Process SMB error responses
380
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
381
- return pkt
382
- end
383
-
384
- raise XCEPT::InvalidWordCount
385
- end
386
-
387
- # Process incoming SMB_COM_WRITE_ANDX packets
388
- def smb_parse_write(pkt, data)
389
-
390
- # Process write responses
391
- if (pkt['Payload']['SMB'].v['WordCount'] == 6)
392
- res = CONST::SMB_WRITE_RES_PKT.make_struct
393
- res.from_s(data)
394
- return res
395
- end
396
-
397
- # Process SMB error responses
398
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
399
- return pkt
400
- end
401
-
402
- raise XCEPT::InvalidWordCount
403
- end
404
-
405
- # Process incoming SMB_COM_READ_ANDX packets
406
- def smb_parse_read(pkt, data)
407
-
408
- # Process read responses
409
- if (pkt['Payload']['SMB'].v['WordCount'] == 12)
410
- res = CONST::SMB_READ_RES_PKT.make_struct
411
- res.from_s(data)
412
- return res
413
- end
414
-
415
- # Process SMB error responses
416
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
417
- return pkt
418
- end
419
-
420
- raise XCEPT::InvalidWordCount
421
- end
422
-
423
- # Process incoming SMB_COM_CLOSE packets
424
- def smb_parse_close(pkt, data)
425
-
426
- # Process SMB error responses
427
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
428
- return pkt
429
- end
430
-
431
- raise XCEPT::InvalidWordCount
432
- end
433
-
434
- # Process incoming SMB_COM_DELETE packets
435
- def smb_parse_delete(pkt, data)
436
-
437
- # Process SMB error responses
438
- if (pkt['Payload']['SMB'].v['WordCount'] == 0)
439
- res = CONST::SMB_DELETE_RES_PKT.make_struct
440
- res.from_s(data)
441
- return res
442
- end
443
-
444
- raise XCEPT::InvalidWordCount
445
- end
446
-
447
- # Request a SMB session over NetBIOS
448
- def session_request(name = '*SMBSERVER', do_recv = true)
449
-
450
- name ||= '*SMBSERVER'
451
-
452
- data = ''
453
- data << "\x20" + UTILS.nbname_encode(name) + "\x00"
454
- data << "\x20" + CONST::NETBIOS_REDIR + "\x00"
455
-
456
- pkt = CONST::NBRAW_PKT.make_struct
457
- pkt.v['Type'] = 0x81
458
- pkt['Payload'].v['Payload'] = data
459
-
460
- # Most SMB implementations can't handle this being fragmented
461
- ret = self.smb_send(pkt.to_s, EVADE::EVASION_NONE)
462
- return ret if not do_recv
463
-
464
- res = self.smb_recv
465
-
466
- ack = CONST::NBRAW_PKT.make_struct
467
- ack.from_s(res)
468
-
469
- if (ack.v['Type'] != 130)
470
- raise XCEPT::NetbiosSessionFailed
471
- end
472
-
473
- return ack
474
- end
475
-
476
- # Negotiate a SMB dialect
477
- def negotiate(smb_extended_security=true, do_recv = true)
478
-
479
- dialects = ['LANMAN1.0', 'LM1.2X002' ]
480
-
481
- if (self.encrypt_passwords)
482
- dialects.push('NT LANMAN 1.0', 'NT LM 0.12')
483
- end
484
-
485
- data = dialects.collect { |dialect| "\x02" + dialect + "\x00" }.join('')
486
-
487
- pkt = CONST::SMB_NEG_PKT.make_struct
488
- self.smb_defaults(pkt['Payload']['SMB'])
489
-
490
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NEGOTIATE
491
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
492
-
493
- if(smb_extended_security)
494
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
495
- else
496
- pkt['Payload']['SMB'].v['Flags2'] = 0xc001
497
- end
498
-
499
- pkt['Payload'].v['Payload'] = data
500
-
501
- ret = self.smb_send(pkt.to_s, EVADE::EVASION_NONE)
502
- return ret if not do_recv
503
-
504
- ack = self.smb_recv_parse(CONST::SMB_COM_NEGOTIATE)
505
-
506
- idx = ack['Payload'].v['Dialect']
507
-
508
- # Check for failed dialect selection
509
- if (idx < 0 or idx >= dialects.length)
510
- return nil
511
- end
512
-
513
- # Set the selected dialect
514
- self.dialect = dialects[idx]
515
-
516
- # Does the server support extended security negotiation?
517
- if (ack['Payload'].v['Capabilities'] & 0x80000000 != 0)
518
- self.extended_security = true
519
- end
520
-
521
- # Set the security mode
522
- self.security_mode = ack['Payload'].v['SecurityMode']
523
-
524
- #set require_signing
525
- if (ack['Payload'].v['SecurityMode'] & 0x08 != 0)
526
- self.require_signing = true
527
- end
528
-
529
- # Set the challenge key
530
- if (ack['Payload'].v['EncryptionKey'] != nil)
531
- self.challenge_key = ack['Payload'].v['EncryptionKey']
532
- else
533
- # Handle Windows NT 4.0 responses
534
- if (ack['Payload'].v['KeyLength'] > 0)
535
- self.challenge_key = ack['Payload'].v['Payload'][0, ack['Payload'].v['KeyLength']]
536
- end
537
- end
538
-
539
- # Set the session identifier
540
- if (ack['Payload'].v['SessionKey'] != nil)
541
- self.session_id = ack['Payload'].v['SessionKey']
542
- end
543
-
544
- # Extract the payload (GUID/SecurityBlob)
545
- buf = ack['Payload'].v['Payload'] || ''
546
-
547
- # Set the server GUID
548
- if (self.extended_security and buf.length >= 16)
549
- self.server_guid = buf[0,16]
550
- end
551
-
552
- # Set the server SecurityBlob
553
- if (self.extended_security and buf.length > 16)
554
- # buf[16, buf.length - 16]
555
- end
556
-
557
- # The number of 100-nanosecond intervals that have elapsed since January 1, 1601, in
558
- # Coordinated Universal Time (UTC) format.
559
- # We convert it to a friendly Time object here
560
- self.system_time = UTILS.time_smb_to_unix(ack['Payload'].v['SystemTimeHigh'],ack['Payload'].v['SystemTimeLow'])
561
- self.system_time = ::Time.at( self.system_time )
562
-
563
- # A signed 16-bit signed integer that represents the server's time zone, in minutes,
564
- # from UTC. The time zone of the server MUST be expressed in minutes, plus or minus,
565
- # from UTC.
566
- # NOTE: althought the spec says +/- it doesn't say that it should be inverted :-/
567
- system_zone = ack['Payload'].v['ServerTimeZone']
568
- # Convert the ServerTimeZone to _seconds_ and back into a signed integer :-/
569
- if (system_zone & 0x8000) == 0x8000
570
- system_zone = (( (~system_zone) & 0x0FFF ) + 1 )
571
- else
572
- system_zone *= -1
573
- end
574
- self.system_zone = system_zone * 60
575
-
576
- return ack
577
- end
578
-
579
-
580
- # Authenticate and establish a session
581
- def session_setup(*args)
582
-
583
- if (self.dialect =~ /^(NT LANMAN 1.0|NT LM 0.12)$/)
584
-
585
- if (self.challenge_key)
586
- return self.session_setup_no_ntlmssp(*args)
587
- end
588
-
589
- if ( self.extended_security )
590
- return self.session_setup_with_ntlmssp(*args)
591
- end
592
-
593
- end
594
-
595
- return self.session_setup_clear(*args)
596
- end
597
-
598
- # Authenticate using clear-text passwords
599
- def session_setup_clear(user = '', pass = '', domain = '', do_recv = true)
600
-
601
- data = [ pass, user, domain, self.native_os, self.native_lm ].collect{ |a| a + "\x00" }.join('');
602
-
603
- pkt = CONST::SMB_SETUP_LANMAN_PKT.make_struct
604
- self.smb_defaults(pkt['Payload']['SMB'])
605
-
606
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
607
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
608
- if self.require_signing
609
- #ascii
610
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
611
- else
612
- #ascii
613
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
614
- end
615
-
616
- pkt['Payload']['SMB'].v['WordCount'] = 10
617
- pkt['Payload'].v['AndX'] = 255
618
- pkt['Payload'].v['MaxBuff'] = 0xffdf
619
- pkt['Payload'].v['MaxMPX'] = 2
620
- pkt['Payload'].v['VCNum'] = 1
621
- pkt['Payload'].v['PasswordLen'] = pass.length + 1
622
- pkt['Payload'].v['Capabilities'] = 64
623
- pkt['Payload'].v['SessionKey'] = self.session_id
624
- pkt['Payload'].v['Payload'] = data
625
-
626
- ret = self.smb_send(pkt.to_s)
627
- return ret if not do_recv
628
-
629
- ack = self.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX)
630
-
631
- if (ack['Payload'].v['Action'] != 1 and user.length > 0)
632
- self.auth_user = user
633
- end
634
-
635
- self.auth_user_id = ack['Payload']['SMB'].v['UserID']
636
-
637
- info = ack['Payload'].v['Payload'].split(/\x00/)
638
- self.peer_native_os = info[0]
639
- self.peer_native_lm = info[1]
640
- self.default_domain = info[2]
641
-
642
- return ack
643
- end
644
-
645
- # Authenticate without NTLMSSP
646
- def session_setup_no_ntlmssp(user = '', pass = '', domain = '', do_recv = true)
647
-
648
- # Requires a challenge key to have been seen during negotiation
649
- raise XCEPT::NTLM1MissingChallenge if not self.challenge_key
650
-
651
- #
652
- # We can not yet handle signing in this situation
653
- # But instead of throwing an exception,we will disable signing, continue and hope for the best.
654
- #
655
-
656
- #raise XCEPT::SigningError if self.require_signing
657
- self.require_signing = false if self.require_signing
658
-
659
-
660
- if NTLM_UTILS.is_pass_ntlm_hash?(pass)
661
- arglm = {
662
- :lm_hash => [ pass.upcase()[0,32] ].pack('H32'),
663
- :challenge => self.challenge_key
664
- }
665
- hash_lm = NTLM_CRYPT::lm_response(arglm)
666
-
667
- argntlm = {
668
- :ntlm_hash => [ pass.upcase()[33,65] ].pack('H32'),
669
- :challenge => self.challenge_key
670
- }
671
- hash_nt = NTLM_CRYPT::ntlm_response(argntlm)
672
- else
673
- hash_lm = pass.length > 0 ? NTLM_CRYPT.lanman_des(pass, self.challenge_key) : ''
674
- hash_nt = pass.length > 0 ? NTLM_CRYPT.ntlm_md4(pass, self.challenge_key) : ''
675
- end
676
-
677
- data = ''
678
- data << hash_lm
679
- data << hash_nt
680
- data << user + "\x00"
681
- data << domain + "\x00"
682
- data << self.native_os + "\x00"
683
- data << self.native_lm + "\x00"
684
-
685
- pkt = CONST::SMB_SETUP_NTLMV1_PKT.make_struct
686
- self.smb_defaults(pkt['Payload']['SMB'])
687
-
688
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
689
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
690
- pkt['Payload']['SMB'].v['Flags2'] = 0x2001
691
- pkt['Payload']['SMB'].v['WordCount'] = 13
692
- pkt['Payload'].v['AndX'] = 255
693
- pkt['Payload'].v['MaxBuff'] = 0xffdf
694
- pkt['Payload'].v['MaxMPX'] = 2
695
- pkt['Payload'].v['VCNum'] = 1
696
- pkt['Payload'].v['PasswordLenLM'] = hash_lm.length
697
- pkt['Payload'].v['PasswordLenNT'] = hash_nt.length
698
- pkt['Payload'].v['Capabilities'] = 64
699
- pkt['Payload'].v['SessionKey'] = self.session_id
700
- pkt['Payload'].v['Payload'] = data
701
-
702
- ret = self.smb_send(pkt.to_s)
703
- return ret if not do_recv
704
-
705
- ack = self.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX)
706
-
707
- if (ack['Payload'].v['Action'] != 1 and user.length > 0)
708
- self.auth_user = user
709
- end
710
-
711
- self.auth_user_id = ack['Payload']['SMB'].v['UserID']
712
-
713
- info = ack['Payload'].v['Payload'].split(/\x00/)
714
-
715
- self.peer_native_os = info[0]
716
- self.peer_native_lm = info[1]
717
- self.default_domain = info[2]
718
-
719
- return ack
720
- end
721
-
722
-
723
- # Authenticate without ntlmssp with a precomputed hash pair
724
- def session_setup_no_ntlmssp_prehash(user, domain, hash_lm, hash_nt, do_recv = true)
725
-
726
- #raise XCEPT::NTLM2MissingChallenge if self.require_signing
727
-
728
- data = ''
729
- data << hash_lm
730
- data << hash_nt
731
- data << user + "\x00"
732
- data << domain + "\x00"
733
- data << self.native_os + "\x00"
734
- data << self.native_lm + "\x00"
735
-
736
- pkt = CONST::SMB_SETUP_NTLMV1_PKT.make_struct
737
- self.smb_defaults(pkt['Payload']['SMB'])
738
-
739
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
740
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
741
- pkt['Payload']['SMB'].v['Flags2'] = 0x2001
742
- pkt['Payload']['SMB'].v['WordCount'] = 13
743
- pkt['Payload'].v['AndX'] = 255
744
- pkt['Payload'].v['MaxBuff'] = 0xffdf
745
- pkt['Payload'].v['MaxMPX'] = 2
746
- pkt['Payload'].v['VCNum'] = 1
747
- pkt['Payload'].v['PasswordLenLM'] = hash_lm.length
748
- pkt['Payload'].v['PasswordLenNT'] = hash_nt.length
749
- pkt['Payload'].v['Capabilities'] = 64
750
- pkt['Payload'].v['SessionKey'] = self.session_id
751
- pkt['Payload'].v['Payload'] = data
752
-
753
- ret = self.smb_send(pkt.to_s)
754
- return ret if not do_recv
755
-
756
- ack = self.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX)
757
-
758
- if (ack['Payload'].v['Action'] != 1 and user.length > 0)
759
- self.auth_user = user
760
- end
761
-
762
- self.auth_user_id = ack['Payload']['SMB'].v['UserID']
763
-
764
- info = ack['Payload'].v['Payload'].split(/\x00/)
765
-
766
- self.peer_native_os = info[0]
767
- self.peer_native_lm = info[1]
768
- self.default_domain = info[2]
769
-
770
- return ack
771
- end
772
-
773
- # Authenticate using extended security negotiation
774
- def session_setup_with_ntlmssp(user = '', pass = '', domain = '', name = nil, do_recv = true)
775
-
776
- ntlm_options = {
777
- :signing => self.require_signing,
778
- :usentlm2_session => self.usentlm2_session,
779
- :use_ntlmv2 => self.use_ntlmv2,
780
- :send_lm => self.send_lm,
781
- :send_ntlm => self.send_ntlm,
782
- :use_lanman_key => self.use_lanman_key
783
- }
784
-
785
- ntlmssp_flags = NTLM_UTILS.make_ntlm_flags(ntlm_options)
786
-
787
- if (name == nil)
788
- name = Rex::Text.rand_text_alphanumeric(16)
789
- end
790
-
791
- blob = NTLM_UTILS.make_ntlmssp_secblob_init(domain, name, ntlmssp_flags)
792
-
793
- native_data = ''
794
- native_data << self.native_os + "\x00"
795
- native_data << self.native_lm + "\x00"
796
-
797
- pkt = CONST::SMB_SETUP_NTLMV2_PKT.make_struct
798
- self.smb_defaults(pkt['Payload']['SMB'])
799
-
800
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
801
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
802
- if require_signing
803
- #ascii
804
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
805
- else
806
- #ascii
807
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
808
- end
809
- pkt['Payload']['SMB'].v['WordCount'] = 12
810
- pkt['Payload'].v['AndX'] = 255
811
- pkt['Payload'].v['MaxBuff'] = 0xffdf
812
- pkt['Payload'].v['MaxMPX'] = 2
813
- pkt['Payload'].v['VCNum'] = 1
814
- pkt['Payload'].v['SecurityBlobLen'] = blob.length
815
- pkt['Payload'].v['Capabilities'] = 0x800000d4
816
- pkt['Payload'].v['SessionKey'] = self.session_id
817
- pkt['Payload'].v['Payload'] = blob + native_data
818
-
819
- ret = self.smb_send(pkt.to_s)
820
-
821
- return ret if not do_recv
822
-
823
- ack = self.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX, true)
824
-
825
-
826
- # The server doesn't know about NTLM_NEGOTIATE
827
- if (ack['Payload']['SMB'].v['ErrorClass'] == 0x00020002)
828
- return session_setup_no_ntlmssp(user, pass, domain)
829
- end
830
-
831
- # Make sure the error code tells us to continue processing
832
- if (ack['Payload']['SMB'].v['ErrorClass'] != 0xc0000016)
833
- failure = XCEPT::ErrorCode.new
834
- failure.word_count = ack['Payload']['SMB'].v['WordCount']
835
- failure.command = ack['Payload']['SMB'].v['Command']
836
- failure.error_code = ack['Payload']['SMB'].v['ErrorClass']
837
- raise failure
838
- end
839
-
840
- # Extract the SecurityBlob from the response
841
- data = ack['Payload'].v['Payload']
842
- blob = data.slice!(0, ack['Payload'].v['SecurityBlobLen'])
843
-
844
- # Extract the native lanman and os strings
845
- info = data.split(/\x00/)
846
- self.peer_native_os = info[0]
847
- self.peer_native_lm = info[1]
848
-
849
- # Save the temporary UserID for use in the next request
850
- temp_user_id = ack['Payload']['SMB'].v['UserID']
851
-
852
- # Get default data
853
- blob_data = NTLM_UTILS.parse_ntlm_type_2_blob(blob)
854
- self.challenge_key = blob_data[:challenge_key]
855
- server_ntlmssp_flags = blob_data[:server_ntlmssp_flags] #else should raise an error
856
- #netbios name
857
- self.default_name = blob_data[:default_name] || ''
858
- #netbios domain
859
- self.default_domain = blob_data[:default_domain] || ''
860
- #dns name
861
- self.dns_host_name = blob_data[:dns_host_name] || ''
862
- #dns domain
863
- self.dns_domain_name = blob_data[:dns_domain_name] || ''
864
- #Client time
865
- chall_MsvAvTimestamp = blob_data[:chall_MsvAvTimestamp] || ''
866
-
867
-
868
- resp_lm, resp_ntlm, client_challenge, ntlm_cli_challenge = NTLM_UTILS.create_lm_ntlm_responses(user, pass, self.challenge_key, domain,
869
- default_name, default_domain, dns_host_name,
870
- dns_domain_name, chall_MsvAvTimestamp ,
871
- self.spnopt, ntlm_options)
872
- enc_session_key = ''
873
- self.sequence_counter = 0
874
- if self.require_signing
875
- self.signing_key, enc_session_key = NTLM_UTILS.create_session_key(server_ntlmssp_flags, user, pass, domain, self.challenge_key,
876
- client_challenge, ntlm_cli_challenge, ntlm_options)
877
- end
878
-
879
- # Create the security blob data
880
- blob = NTLM_UTILS.make_ntlmssp_secblob_auth(domain, name, user, resp_lm, resp_ntlm, enc_session_key, ntlmssp_flags)
881
-
882
- pkt = CONST::SMB_SETUP_NTLMV2_PKT.make_struct
883
- self.smb_defaults(pkt['Payload']['SMB'])
884
-
885
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
886
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
887
- if self.require_signing
888
- #ascii
889
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
890
- else
891
- #ascii
892
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
893
- end
894
- pkt['Payload']['SMB'].v['WordCount'] = 12
895
- pkt['Payload']['SMB'].v['UserID'] = temp_user_id
896
- pkt['Payload'].v['AndX'] = 255
897
- pkt['Payload'].v['MaxBuff'] = 0xffdf
898
- pkt['Payload'].v['MaxMPX'] = 2
899
- pkt['Payload'].v['VCNum'] = 1
900
- pkt['Payload'].v['Capabilities'] = 0x8000d05c
901
- pkt['Payload'].v['SessionKey'] = self.session_id
902
- pkt['Payload'].v['SecurityBlobLen'] = blob.length
903
- pkt['Payload'].v['Payload'] = blob + native_data
904
-
905
- # NOTE: if do_recv is set to false, we cant reach here...
906
- self.smb_send(pkt.to_s)
907
-
908
- ack = self.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX, true)
909
-
910
- # Make sure that authentication succeeded
911
- if (ack['Payload']['SMB'].v['ErrorClass'] != 0)
912
-
913
- if (user.length == 0)
914
- # Ensure that signing is disabled when we hit this corner case
915
- self.require_signing = false
916
-
917
- # Fall back to the non-ntlmssp authentication method
918
- return self.session_setup_no_ntlmssp(user, pass, domain)
919
- end
920
-
921
- failure = XCEPT::ErrorCode.new
922
- failure.word_count = ack['Payload']['SMB'].v['WordCount']
923
- failure.command = ack['Payload']['SMB'].v['Command']
924
- failure.error_code = ack['Payload']['SMB'].v['ErrorClass']
925
- raise failure
926
- end
927
-
928
- self.auth_user_id = ack['Payload']['SMB'].v['UserID']
929
-
930
- if (ack['Payload'].v['Action'] != 1 and user.length > 0)
931
- self.auth_user = user
932
- end
933
-
934
- return ack
935
- end
936
-
937
-
938
- # An exploit helper function for sending arbitrary SPNEGO blobs
939
- def session_setup_with_ntlmssp_blob(blob = '', do_recv = true)
940
- native_data = ''
941
- native_data << self.native_os + "\x00"
942
- native_data << self.native_lm + "\x00"
943
-
944
- pkt = CONST::SMB_SETUP_NTLMV2_PKT.make_struct
945
- self.smb_defaults(pkt['Payload']['SMB'])
946
-
947
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
948
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
949
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
950
- pkt['Payload']['SMB'].v['WordCount'] = 12
951
- pkt['Payload']['SMB'].v['UserID'] = 0
952
- pkt['Payload'].v['AndX'] = 255
953
- pkt['Payload'].v['MaxBuff'] = 0xffdf
954
- pkt['Payload'].v['MaxMPX'] = 2
955
- pkt['Payload'].v['VCNum'] = 1
956
- pkt['Payload'].v['SecurityBlobLen'] = blob.length
957
- pkt['Payload'].v['Capabilities'] = 0x8000d05c
958
- pkt['Payload'].v['SessionKey'] = self.session_id
959
- pkt['Payload'].v['Payload'] = blob + native_data
960
-
961
- ret = self.smb_send(pkt.to_s)
962
- return ret if not do_recv
963
-
964
- self.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX, false)
965
- end
966
-
967
-
968
- # Authenticate using extended security negotiation (NTLMSSP), but stop half-way, using the temporary ID
969
- def session_setup_with_ntlmssp_temp(domain = '', name = nil, do_recv = true)
970
-
971
- if (name == nil)
972
- name = Rex::Text.rand_text_alphanumeric(16)
973
- end
974
-
975
- blob = NTLM_UTILS.make_ntlmssp_secblob_init(domain, name)
976
-
977
- native_data = ''
978
- native_data << self.native_os + "\x00"
979
- native_data << self.native_lm + "\x00"
980
-
981
- pkt = CONST::SMB_SETUP_NTLMV2_PKT.make_struct
982
- self.smb_defaults(pkt['Payload']['SMB'])
983
-
984
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
985
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
986
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
987
- pkt['Payload']['SMB'].v['WordCount'] = 12
988
- pkt['Payload'].v['AndX'] = 255
989
- pkt['Payload'].v['MaxBuff'] = 0xffdf
990
- pkt['Payload'].v['MaxMPX'] = 2
991
- pkt['Payload'].v['VCNum'] = 1
992
- pkt['Payload'].v['SecurityBlobLen'] = blob.length
993
- pkt['Payload'].v['Capabilities'] = 0x8000d05c
994
- pkt['Payload'].v['SessionKey'] = self.session_id
995
- pkt['Payload'].v['Payload'] = blob + native_data
996
-
997
- ret = self.smb_send(pkt.to_s)
998
- return ret if not do_recv
999
-
1000
- ack = self.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX, true)
1001
-
1002
- # The server doesn't know about NTLM_NEGOTIATE, try ntlmv1
1003
- if (ack['Payload']['SMB'].v['ErrorClass'] == 0x00020002)
1004
- return session_setup_no_ntlmssp(user, pass, domain)
1005
- end
1006
-
1007
- # Make sure the error code tells us to continue processing
1008
- if (ack['Payload']['SMB'].v['ErrorClass'] != 0xc0000016)
1009
- failure = XCEPT::ErrorCode.new
1010
- failure.word_count = ack['Payload']['SMB'].v['WordCount']
1011
- failure.command = ack['Payload']['SMB'].v['Command']
1012
- failure.error_code = ack['Payload']['SMB'].v['ErrorClass']
1013
- raise failure
1014
- end
1015
-
1016
- # Extract the SecurityBlob from the response
1017
- data = ack['Payload'].v['Payload']
1018
- blob = data.slice!(0, ack['Payload'].v['SecurityBlobLen'])
1019
-
1020
- # Extract the native lanman and os strings
1021
- info = data.split(/\x00/)
1022
- self.peer_native_os = info[0]
1023
- self.peer_native_lm = info[1]
1024
-
1025
- # Save the temporary UserID for use in the next request
1026
- self.auth_user_id = ack['Payload']['SMB'].v['UserID']
1027
-
1028
- # Extract the NTLM challenge key the lazy way
1029
- cidx = blob.index("NTLMSSP\x00\x02\x00\x00\x00")
1030
-
1031
- if (cidx == -1)
1032
- raise XCEPT::NTLM2MissingChallenge
1033
- end
1034
-
1035
- # Store the challenge key
1036
- self.challenge_key = blob[cidx + 24, 8]
1037
-
1038
- return ack
1039
- end
1040
-
1041
- # Connect to a specified share with an optional password
1042
- def tree_connect(share = 'IPC$', pass = '', do_recv = true)
1043
-
1044
- data = [ pass, share, '?????' ].collect{ |a| a + "\x00" }.join('');
1045
-
1046
- pkt = CONST::SMB_TREE_CONN_PKT.make_struct
1047
- self.smb_defaults(pkt['Payload']['SMB'])
1048
-
1049
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TREE_CONNECT_ANDX
1050
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1051
- if self.require_signing
1052
- #ascii
1053
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1054
- else
1055
- #ascii
1056
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1057
- end
1058
-
1059
- pkt['Payload']['SMB'].v['WordCount'] = 4
1060
- pkt['Payload'].v['AndX'] = 255
1061
- pkt['Payload'].v['PasswordLen'] = pass.length + 1
1062
- pkt['Payload'].v['Capabilities'] = 64
1063
- pkt['Payload'].v['Payload'] = data
1064
-
1065
- ret = self.smb_send(pkt.to_s)
1066
- return ret if not do_recv
1067
-
1068
- ack = self.smb_recv_parse(CONST::SMB_COM_TREE_CONNECT_ANDX)
1069
-
1070
- self.last_tree_id = ack['Payload']['SMB'].v['TreeID']
1071
- # why bother?
1072
- # info = ack['Payload'].v['Payload'].split(/\x00/)
1073
-
1074
- return ack
1075
- end
1076
-
1077
- # Disconnect from the current tree
1078
- def tree_disconnect(tree_id = self.last_tree_id, do_recv = true)
1079
-
1080
- pkt = CONST::SMB_TREE_DISCONN_PKT.make_struct
1081
- self.smb_defaults(pkt['Payload']['SMB'])
1082
-
1083
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TREE_DISCONNECT
1084
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1085
- if self.require_signing
1086
- #ascii
1087
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1088
- else
1089
- #ascii
1090
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1091
- end
1092
-
1093
- pkt['Payload']['SMB'].v['WordCount'] = 0
1094
- pkt['Payload']['SMB'].v['TreeID'] = tree_id
1095
-
1096
- ret = self.smb_send(pkt.to_s)
1097
- return ret if not do_recv
1098
-
1099
- ack = self.smb_recv_parse(CONST::SMB_COM_TREE_DISCONNECT)
1100
-
1101
- if (tree_id == self.last_tree_id)
1102
- self.last_tree_id = 0
1103
- end
1104
-
1105
- return ack
1106
- end
1107
-
1108
- # Returns a SMB_CREATE_RES response for a given named pipe
1109
- def create_pipe(filename, disposition = 1, impersonation = 2)
1110
- self.create(filename)
1111
- end
1112
-
1113
- # Creates a file or opens an existing pipe
1114
- def create(filename, disposition = 1, impersonation = 2, do_recv = true)
1115
-
1116
- pkt = CONST::SMB_CREATE_PKT.make_struct
1117
- self.smb_defaults(pkt['Payload']['SMB'])
1118
-
1119
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX
1120
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1121
- if self.require_signing
1122
- #ascii
1123
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1124
- else
1125
- #ascii
1126
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1127
- end
1128
-
1129
- pkt['Payload']['SMB'].v['WordCount'] = 24
1130
-
1131
- pkt['Payload'].v['AndX'] = 255
1132
- pkt['Payload'].v['FileNameLen'] = filename.length
1133
- pkt['Payload'].v['CreateFlags'] = 0x16
1134
- pkt['Payload'].v['AccessMask'] = 0x02000000 # Maximum Allowed
1135
- pkt['Payload'].v['ShareAccess'] = 7
1136
- pkt['Payload'].v['CreateOptions'] = 0
1137
- pkt['Payload'].v['Impersonation'] = impersonation
1138
- pkt['Payload'].v['Disposition'] = disposition
1139
- pkt['Payload'].v['Payload'] = filename + "\x00"
1140
-
1141
- ret = self.smb_send(pkt.to_s)
1142
- return ret if not do_recv
1143
-
1144
- ack = self.smb_recv_parse(CONST::SMB_COM_NT_CREATE_ANDX)
1145
-
1146
- # Save off the FileID
1147
- if (ack['Payload'].v['FileID'] > 0)
1148
- self.last_file_id = ack['Payload'].v['FileID']
1149
- end
1150
-
1151
- return ack
1152
- end
1153
-
1154
- # Deletes a file from a share
1155
- def delete(filename, tree_id = self.last_tree_id, do_recv = true)
1156
-
1157
- pkt = CONST::SMB_DELETE_PKT.make_struct
1158
- self.smb_defaults(pkt['Payload']['SMB'])
1159
-
1160
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_DELETE
1161
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1162
- if self.require_signing
1163
- #ascii
1164
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1165
- else
1166
- #ascii
1167
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1168
- end
1169
-
1170
- pkt['Payload']['SMB'].v['TreeID'] = tree_id
1171
- pkt['Payload']['SMB'].v['WordCount'] = 1
1172
-
1173
- pkt['Payload'].v['SearchAttributes'] = 0x06
1174
- pkt['Payload'].v['BufferFormat'] = 4
1175
- pkt['Payload'].v['Payload'] = filename + "\x00"
1176
-
1177
- ret = self.smb_send(pkt.to_s)
1178
- return ret if not do_recv
1179
-
1180
- ack = self.smb_recv_parse(CONST::SMB_COM_DELETE)
1181
-
1182
- return ack
1183
- end
1184
-
1185
- # Opens an existing file or creates a new one
1186
- def open(filename, mode = 0x12, access = 0x42, do_recv = true)
1187
-
1188
- pkt = CONST::SMB_OPEN_PKT.make_struct
1189
- self.smb_defaults(pkt['Payload']['SMB'])
1190
-
1191
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_OPEN_ANDX
1192
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1193
- if self.require_signing
1194
- #ascii
1195
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1196
- else
1197
- #ascii
1198
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1199
- end
1200
-
1201
- pkt['Payload']['SMB'].v['WordCount'] = 15
1202
-
1203
- pkt['Payload'].v['AndX'] = 255
1204
- pkt['Payload'].v['Access'] = access
1205
- pkt['Payload'].v['SearchAttributes'] = 0x06
1206
- pkt['Payload'].v['OpenFunction'] = mode
1207
- pkt['Payload'].v['Payload'] = filename + "\x00"
1208
-
1209
- ret = self.smb_send(pkt.to_s)
1210
- return ret if not do_recv
1211
-
1212
- ack = self.smb_recv_parse(CONST::SMB_COM_OPEN_ANDX)
1213
-
1214
- # Save off the FileID
1215
- if (ack['Payload'].v['FileID'] > 0)
1216
- self.last_file_id = ack['Payload'].v['FileID']
1217
- end
1218
-
1219
- return ack
1220
- end
1221
-
1222
- # Closes an open file handle
1223
- def close(file_id = self.last_file_id, tree_id = self.last_tree_id, do_recv = true)
1224
-
1225
- pkt = CONST::SMB_CLOSE_PKT.make_struct
1226
- self.smb_defaults(pkt['Payload']['SMB'])
1227
-
1228
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_CLOSE
1229
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1230
- if self.require_signing
1231
- #ascii
1232
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1233
- else
1234
- #ascii
1235
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1236
- end
1237
-
1238
- pkt['Payload']['SMB'].v['TreeID'] = tree_id
1239
- pkt['Payload']['SMB'].v['WordCount'] = 3
1240
-
1241
- pkt['Payload'].v['FileID'] = file_id
1242
- pkt['Payload'].v['LastWrite'] = -1
1243
-
1244
- ret = self.smb_send(pkt.to_s)
1245
- return ret if not do_recv
1246
-
1247
- ack = self.smb_recv_parse(CONST::SMB_COM_CLOSE)
1248
-
1249
- return ack
1250
- end
1251
-
1252
- # Writes data to an open file handle
1253
- def write(file_id = self.last_file_id, offset = 0, data = '', do_recv = true)
1254
- pkt = CONST::SMB_WRITE_PKT.make_struct
1255
- self.smb_defaults(pkt['Payload']['SMB'])
1256
-
1257
- data_offset = pkt.to_s.length - 4
1258
-
1259
- filler = EVADE.make_offset_filler(evasion_opts['pad_data'], 4096 - data.length - data_offset)
1260
-
1261
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_WRITE_ANDX
1262
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1263
- if self.require_signing
1264
- #ascii
1265
- pkt['Payload']['SMB'].v['Flags2'] = 0x2805
1266
- else
1267
- #ascii
1268
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1269
- end
1270
-
1271
- pkt['Payload']['SMB'].v['WordCount'] = 14
1272
-
1273
- pkt['Payload'].v['AndX'] = 255
1274
- pkt['Payload'].v['FileID'] = file_id
1275
- pkt['Payload'].v['Offset'] = offset
1276
- pkt['Payload'].v['Reserved2'] = -1
1277
- pkt['Payload'].v['WriteMode'] = 8
1278
- pkt['Payload'].v['Remaining'] = data.length
1279
- # pkt['Payload'].v['DataLenHigh'] = (data.length / 65536).to_i
1280
- pkt['Payload'].v['DataLenLow'] = (data.length % 65536).to_i
1281
- pkt['Payload'].v['DataOffset'] = data_offset + filler.length
1282
- pkt['Payload'].v['Payload'] = filler + data
1283
-
1284
- ret = self.smb_send(pkt.to_s)
1285
- return ret if not do_recv
1286
-
1287
- ack = self.smb_recv_parse(CONST::SMB_COM_WRITE_ANDX)
1288
-
1289
- return ack
1290
- end
1291
-
1292
-
1293
- # Reads data from an open file handle
1294
- def read(file_id = self.last_file_id, offset = 0, data_length = 64000, do_recv = true)
1295
-
1296
- pkt = CONST::SMB_READ_PKT.make_struct
1297
- self.smb_defaults(pkt['Payload']['SMB'])
1298
-
1299
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_READ_ANDX
1300
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1301
- if self.require_signing
1302
- #ascii
1303
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1304
- else
1305
- #ascii
1306
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1307
- end
1308
-
1309
- pkt['Payload']['SMB'].v['WordCount'] = 10
1310
-
1311
- pkt['Payload'].v['AndX'] = 255
1312
- pkt['Payload'].v['FileID'] = file_id
1313
- pkt['Payload'].v['Offset'] = offset
1314
- # pkt['Payload'].v['MaxCountHigh'] = (data_length / 65536).to_i
1315
- pkt['Payload'].v['MaxCountLow'] = (data_length % 65536).to_i
1316
- pkt['Payload'].v['MinCount'] = data_length
1317
- pkt['Payload'].v['Reserved2'] = -1
1318
-
1319
- ret = self.smb_send(pkt.to_s)
1320
- return ret if not do_recv
1321
-
1322
- ack = self.smb_recv_parse(CONST::SMB_COM_READ_ANDX, true)
1323
-
1324
- err = ack['Payload']['SMB'].v['ErrorClass']
1325
-
1326
- # Catch some non-fatal error codes
1327
- if (err != 0 && err != CONST::SMB_ERROR_BUFFER_OVERFLOW)
1328
- failure = XCEPT::ErrorCode.new
1329
- failure.word_count = ack['Payload']['SMB'].v['WordCount']
1330
- failure.command = ack['Payload']['SMB'].v['Command']
1331
- failure.error_code = ack['Payload']['SMB'].v['ErrorClass']
1332
- raise failure
1333
- end
1334
-
1335
- return ack
1336
- end
1337
-
1338
-
1339
- # Perform a transaction against a named pipe
1340
- def trans_named_pipe(file_id, data = '', no_response = nil)
1341
- pipe = EVADE.make_trans_named_pipe_name(evasion_opts['pad_file'])
1342
- self.trans(pipe, '', data, 2, [0x26, file_id].pack('vv'), no_response)
1343
- end
1344
-
1345
- # Perform a mailslot write over SMB
1346
- # Warning: This can kill srv.sys unless MS06-035 is applied
1347
- def trans_mailslot (name, data = '')
1348
- # Setup data must be:
1349
- # Operation: 1 (write)
1350
- # Priority: 0
1351
- # Class: Reliable
1352
- self.trans_maxzero(name, '', data, 3, [1, 0, 1].pack('vvv'), true )
1353
- end
1354
-
1355
- # Perform a transaction against a given pipe name
1356
- def trans(pipe, param = '', body = '', setup_count = 0, setup_data = '', no_response = false, do_recv = true)
1357
-
1358
- # Null-terminate the pipe parameter if needed
1359
- if (pipe[-1,1] != "\x00")
1360
- pipe << "\x00"
1361
- end
1362
-
1363
- pkt = CONST::SMB_TRANS_PKT.make_struct
1364
- self.smb_defaults(pkt['Payload']['SMB'])
1365
-
1366
- # Packets larger than mlen will cause XP SP2 to disconnect us ;-(
1367
- mlen = 4200
1368
-
1369
- # Figure out how much space is taken up by our current arguments
1370
- xlen = pipe.length + param.length + body.length
1371
-
1372
- filler1 = ''
1373
- filler2 = ''
1374
-
1375
- # Fill any available space depending on the evasion settings
1376
- if (xlen < mlen)
1377
- filler1 = EVADE.make_offset_filler(evasion_opts['pad_data'], (mlen-xlen)/2)
1378
- filler2 = EVADE.make_offset_filler(evasion_opts['pad_data'], (mlen-xlen)/2)
1379
- end
1380
-
1381
- # Squish the whole thing together
1382
- data = pipe + filler1 + param + filler2 + body
1383
-
1384
- # Throw some form of a warning out?
1385
- if (data.length > mlen)
1386
- # XXX This call will more than likely fail :-(
1387
- end
1388
-
1389
- # Calculate all of the offsets
1390
- base_offset = pkt.to_s.length + (setup_count * 2) - 4
1391
- param_offset = base_offset + pipe.length + filler1.length
1392
- data_offset = param_offset + filler2.length + param.length
1393
-
1394
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION
1395
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1396
- if self.require_signing
1397
- #ascii
1398
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1399
- else
1400
- #ascii
1401
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1402
- end
1403
-
1404
- pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count
1405
-
1406
- pkt['Payload'].v['ParamCountTotal'] = param.length
1407
- pkt['Payload'].v['DataCountTotal'] = body.length
1408
- pkt['Payload'].v['ParamCountMax'] = 1024
1409
- pkt['Payload'].v['DataCountMax'] = 65504
1410
- pkt['Payload'].v['ParamCount'] = param.length
1411
- pkt['Payload'].v['ParamOffset'] = param_offset
1412
- pkt['Payload'].v['DataCount'] = body.length
1413
- pkt['Payload'].v['DataOffset'] = data_offset
1414
- pkt['Payload'].v['SetupCount'] = setup_count
1415
- pkt['Payload'].v['SetupData'] = setup_data
1416
-
1417
- pkt['Payload'].v['Payload'] = data
1418
-
1419
- if no_response
1420
- pkt['Payload'].v['Flags'] = 2
1421
- end
1422
-
1423
- ret = self.smb_send(pkt.to_s)
1424
- return ret if no_response or not do_recv
1425
-
1426
- self.smb_recv_parse(CONST::SMB_COM_TRANSACTION)
1427
- end
1428
-
1429
-
1430
-
1431
- # Perform a transaction against a given pipe name
1432
- # Difference from trans: sets MaxParam/MaxData to zero
1433
- # This is required to trigger mailslot bug :-(
1434
- def trans_maxzero(pipe, param = '', body = '', setup_count = 0, setup_data = '', no_response = false, do_recv = true)
1435
-
1436
- # Null-terminate the pipe parameter if needed
1437
- if (pipe[-1] != 0)
1438
- pipe << "\x00"
1439
- end
1440
-
1441
- pkt = CONST::SMB_TRANS_PKT.make_struct
1442
- self.smb_defaults(pkt['Payload']['SMB'])
1443
-
1444
- # Packets larger than mlen will cause XP SP2 to disconnect us ;-(
1445
- mlen = 4200
1446
-
1447
- # Figure out how much space is taken up by our current arguments
1448
- xlen = pipe.length + param.length + body.length
1449
-
1450
- filler1 = ''
1451
- filler2 = ''
1452
-
1453
- # Fill any available space depending on the evasion settings
1454
- if (xlen < mlen)
1455
- filler1 = EVADE.make_offset_filler(evasion_opts['pad_data'], (mlen-xlen)/2)
1456
- filler2 = EVADE.make_offset_filler(evasion_opts['pad_data'], (mlen-xlen)/2)
1457
- end
1458
-
1459
- # Squish the whole thing together
1460
- data = pipe + filler1 + param + filler2 + body
1461
-
1462
- # Throw some form of a warning out?
1463
- if (data.length > mlen)
1464
- # XXX This call will more than likely fail :-(
1465
- end
1466
-
1467
- # Calculate all of the offsets
1468
- base_offset = pkt.to_s.length + (setup_count * 2) - 4
1469
- param_offset = base_offset + pipe.length + filler1.length
1470
- data_offset = param_offset + filler2.length + param.length
1471
-
1472
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION
1473
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1474
- if self.require_signing
1475
- #ascii
1476
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1477
- else
1478
- #ascii
1479
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1480
- end
1481
-
1482
- pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count
1483
-
1484
- pkt['Payload'].v['ParamCountTotal'] = param.length
1485
- pkt['Payload'].v['DataCountTotal'] = body.length
1486
- pkt['Payload'].v['ParamCountMax'] = 0
1487
- pkt['Payload'].v['DataCountMax'] = 0
1488
- pkt['Payload'].v['ParamCount'] = param.length
1489
- pkt['Payload'].v['ParamOffset'] = param_offset
1490
- pkt['Payload'].v['DataCount'] = body.length
1491
- pkt['Payload'].v['DataOffset'] = data_offset
1492
- pkt['Payload'].v['SetupCount'] = setup_count
1493
- pkt['Payload'].v['SetupData'] = setup_data
1494
-
1495
- pkt['Payload'].v['Payload'] = data
1496
-
1497
- if no_response
1498
- pkt['Payload'].v['Flags'] = 2
1499
- end
1500
-
1501
- ret = self.smb_send(pkt.to_s)
1502
- return ret if no_response or not do_recv
1503
-
1504
- self.smb_recv_parse(CONST::SMB_COM_TRANSACTION)
1505
- end
1506
-
1507
-
1508
- # Perform a transaction against a given pipe name (no null terminator)
1509
- def trans_nonull(pipe, param = '', body = '', setup_count = 0, setup_data = '', no_response = false, do_recv = true)
1510
-
1511
- pkt = CONST::SMB_TRANS_PKT.make_struct
1512
- self.smb_defaults(pkt['Payload']['SMB'])
1513
-
1514
- # Packets larger than mlen will cause XP SP2 to disconnect us ;-(
1515
- mlen = 4200
1516
-
1517
- # Figure out how much space is taken up by our current arguments
1518
- xlen = pipe.length + param.length + body.length
1519
-
1520
- filler1 = ''
1521
- filler2 = ''
1522
-
1523
- # Fill any available space depending on the evasion settings
1524
- if (xlen < mlen)
1525
- filler1 = EVADE.make_offset_filler(evasion_opts['pad_data'], (mlen-xlen)/2)
1526
- filler2 = EVADE.make_offset_filler(evasion_opts['pad_data'], (mlen-xlen)/2)
1527
- end
1528
-
1529
- # Squish the whole thing together
1530
- data = pipe + filler1 + param + filler2 + body
1531
-
1532
- # Throw some form of a warning out?
1533
- if (data.length > mlen)
1534
- # XXX This call will more than likely fail :-(
1535
- end
1536
-
1537
- # Calculate all of the offsets
1538
- base_offset = pkt.to_s.length + (setup_count * 2) - 4
1539
- param_offset = base_offset + pipe.length + filler1.length
1540
- data_offset = param_offset + filler2.length + param.length
1541
-
1542
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION
1543
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1544
- if self.require_signing
1545
- #ascii
1546
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1547
- else
1548
- #ascii
1549
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1550
- end
1551
-
1552
- pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count
1553
-
1554
- pkt['Payload'].v['ParamCountTotal'] = param.length
1555
- pkt['Payload'].v['DataCountTotal'] = body.length
1556
- pkt['Payload'].v['ParamCountMax'] = 0
1557
- pkt['Payload'].v['DataCountMax'] = 0
1558
- pkt['Payload'].v['ParamCount'] = param.length
1559
- pkt['Payload'].v['ParamOffset'] = param_offset
1560
- pkt['Payload'].v['DataCount'] = body.length
1561
- pkt['Payload'].v['DataOffset'] = data_offset
1562
- pkt['Payload'].v['SetupCount'] = setup_count
1563
- pkt['Payload'].v['SetupData'] = setup_data
1564
-
1565
- pkt['Payload'].v['Payload'] = data
1566
-
1567
- if no_response
1568
- pkt['Payload'].v['Flags'] = 2
1569
- end
1570
-
1571
- ret = self.smb_send(pkt.to_s)
1572
- return ret if no_response or not do_recv
1573
-
1574
- self.smb_recv_parse(CONST::SMB_COM_TRANSACTION)
1575
- end
1576
-
1577
- # Perform a transaction2 request using the specified subcommand, parameters, and data
1578
- def trans2(subcommand, param = '', body = '', do_recv = true)
1579
-
1580
- setup_count = 1
1581
- setup_data = [subcommand].pack('v')
1582
-
1583
- data = param + body
1584
-
1585
- pkt = CONST::SMB_TRANS2_PKT.make_struct
1586
- self.smb_defaults(pkt['Payload']['SMB'])
1587
-
1588
- base_offset = pkt.to_s.length + (setup_count * 2) - 4
1589
- param_offset = base_offset
1590
- data_offset = param_offset + param.length
1591
-
1592
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
1593
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1594
- if self.require_signing
1595
- #ascii
1596
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1597
- else
1598
- #ascii
1599
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1600
- end
1601
-
1602
- pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count
1603
-
1604
- pkt['Payload'].v['ParamCountTotal'] = param.length
1605
- pkt['Payload'].v['DataCountTotal'] = body.length
1606
- pkt['Payload'].v['ParamCountMax'] = 1024
1607
- pkt['Payload'].v['DataCountMax'] = 65504
1608
- pkt['Payload'].v['ParamCount'] = param.length
1609
- pkt['Payload'].v['ParamOffset'] = param_offset
1610
- pkt['Payload'].v['DataCount'] = body.length
1611
- pkt['Payload'].v['DataOffset'] = data_offset
1612
- pkt['Payload'].v['SetupCount'] = setup_count
1613
- pkt['Payload'].v['SetupData'] = setup_data
1614
-
1615
- pkt['Payload'].v['Payload'] = data
1616
-
1617
- ret = self.smb_send(pkt.to_s)
1618
- return ret if not do_recv
1619
-
1620
- ack = self.smb_recv_parse(CONST::SMB_COM_TRANSACTION2)
1621
-
1622
- return ack
1623
- end
1624
-
1625
-
1626
- # Perform a nttransaction request using the specified subcommand, parameters, and data
1627
- def nttrans(subcommand, param = '', body = '', setup_count = 0, setup_data = '', do_recv = true)
1628
-
1629
- data = param + body
1630
-
1631
- pkt = CONST::SMB_NTTRANS_PKT.make_struct
1632
- self.smb_defaults(pkt['Payload']['SMB'])
1633
-
1634
- base_offset = pkt.to_s.length + (setup_count * 2) - 4
1635
- param_offset = base_offset
1636
- data_offset = param_offset + param.length
1637
-
1638
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_TRANSACT
1639
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1640
- if self.require_signing
1641
- #ascii
1642
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1643
- else
1644
- #ascii
1645
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1646
- end
1647
-
1648
- pkt['Payload']['SMB'].v['WordCount'] = 19 + setup_count
1649
-
1650
- pkt['Payload'].v['ParamCountTotal'] = param.length
1651
- pkt['Payload'].v['DataCountTotal'] = body.length
1652
- pkt['Payload'].v['ParamCountMax'] = 1024
1653
- pkt['Payload'].v['DataCountMax'] = 65504
1654
- pkt['Payload'].v['ParamCount'] = param.length
1655
- pkt['Payload'].v['ParamOffset'] = param_offset
1656
- pkt['Payload'].v['DataCount'] = body.length
1657
- pkt['Payload'].v['DataOffset'] = data_offset
1658
- pkt['Payload'].v['SetupCount'] = setup_count
1659
- pkt['Payload'].v['SetupData'] = setup_data
1660
- pkt['Payload'].v['Subcommand'] = subcommand
1661
-
1662
- pkt['Payload'].v['Payload'] = data
1663
-
1664
- ret = self.smb_send(pkt.to_s)
1665
- return ret if not do_recv
1666
-
1667
- ack = self.smb_recv_parse(CONST::SMB_COM_NT_TRANSACT)
1668
- return ack
1669
- end
1670
-
1671
- # Perform a nttransaction request using the specified subcommand, parameters, and data
1672
- def nttrans_secondary(param = '', body = '', do_recv = true)
1673
-
1674
- data = param + body
1675
-
1676
- pkt = CONST::SMB_NTTRANS_SECONDARY_PKT.make_struct
1677
- self.smb_defaults(pkt['Payload']['SMB'])
1678
-
1679
- base_offset = pkt.to_s.length - 4
1680
- param_offset = base_offset
1681
- data_offset = param_offset + param.length
1682
-
1683
- pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_TRANSACT_SECONDARY
1684
- pkt['Payload']['SMB'].v['Flags1'] = 0x18
1685
- if self.require_signing
1686
- #ascii
1687
- pkt['Payload']['SMB'].v['Flags2'] = 0x2807
1688
- else
1689
- #ascii
1690
- pkt['Payload']['SMB'].v['Flags2'] = 0x2801
1691
- end
1692
-
1693
- pkt['Payload']['SMB'].v['WordCount'] = 18
1694
-
1695
- pkt['Payload'].v['ParamCountTotal'] = param.length
1696
- pkt['Payload'].v['DataCountTotal'] = body.length
1697
- pkt['Payload'].v['ParamCount'] = param.length
1698
- pkt['Payload'].v['ParamOffset'] = param_offset
1699
- pkt['Payload'].v['DataCount'] = body.length
1700
- pkt['Payload'].v['DataOffset'] = data_offset
1701
-
1702
- pkt['Payload'].v['Payload'] = data
1703
-
1704
- ret = self.smb_send(pkt.to_s)
1705
- return ret if not do_recv
1706
-
1707
- ack = self.smb_recv_parse(CONST::SMB_COM_NT_TRANSACT_SECONDARY)
1708
- return ack
1709
- end
1710
-
1711
- def queryfs(level)
1712
- parm = [level].pack('v')
1713
-
1714
- begin
1715
- resp = trans2(CONST::TRANS2_QUERY_FS_INFO, parm, '')
1716
-
1717
- pcnt = resp['Payload'].v['ParamCount']
1718
- dcnt = resp['Payload'].v['DataCount']
1719
- poff = resp['Payload'].v['ParamOffset']
1720
- doff = resp['Payload'].v['DataOffset']
1721
-
1722
- # Get the raw packet bytes
1723
- resp_rpkt = resp.to_s
1724
-
1725
- # Remove the NetBIOS header
1726
- resp_rpkt.slice!(0, 4)
1727
-
1728
- resp_parm = resp_rpkt[poff, pcnt]
1729
- resp_data = resp_rpkt[doff, dcnt]
1730
- return resp_data
1731
-
1732
- rescue ::Exception
1733
- raise $!
1734
- end
1735
- end
1736
-
1737
- def symlink(src,dst)
1738
- parm = [513, 0x00000000].pack('vV') + src + "\x00"
1739
-
1740
- begin
1741
- resp = trans2(CONST::TRANS2_SET_PATH_INFO, parm, dst + "\x00")
1742
-
1743
- pcnt = resp['Payload'].v['ParamCount']
1744
- dcnt = resp['Payload'].v['DataCount']
1745
- poff = resp['Payload'].v['ParamOffset']
1746
- doff = resp['Payload'].v['DataOffset']
1747
-
1748
- # Get the raw packet bytes
1749
- resp_rpkt = resp.to_s
1750
-
1751
- # Remove the NetBIOS header
1752
- resp_rpkt.slice!(0, 4)
1753
-
1754
- resp_parm = resp_rpkt[poff, pcnt]
1755
- resp_data = resp_rpkt[doff, dcnt]
1756
- return resp_data
1757
-
1758
- rescue ::Exception
1759
- raise $!
1760
- end
1761
- end
1762
-
1763
- # Obtains allocation information on the mounted tree
1764
- def queryfs_info_allocation
1765
- data = queryfs(CONST::SMB_INFO_ALLOCATION)
1766
- head = %w{fs_id sectors_per_unit unit_total units_available bytes_per_sector}
1767
- vals = data.unpack('VVVVv')
1768
- info = { }
1769
- head.each_index {|i| info[head[i]]=vals[i]}
1770
- return info
1771
- end
1772
-
1773
- # Obtains volume information on the mounted tree
1774
- def queryfs_info_volume
1775
- data = queryfs(CONST::SMB_INFO_VOLUME)
1776
- vals = data.unpack('VCA*')
1777
- return {
1778
- 'serial' => vals[0],
1779
- 'label' => vals[2][0,vals[1]].gsub("\x00", '')
1780
- }
1781
- end
1782
-
1783
- # Obtains file system volume information on the mounted tree
1784
- def queryfs_fs_volume
1785
- data = queryfs(CONST::SMB_QUERY_FS_VOLUME_INFO)
1786
- vals = data.unpack('VVVVCCA*')
1787
- return {
1788
- 'create_time' => (vals[1] << 32) + vals[0],
1789
- 'serial' => vals[2],
1790
- 'label' => vals[6][0,vals[3]].gsub("\x00", '')
1791
- }
1792
- end
1793
-
1794
- # Obtains file system size information on the mounted tree
1795
- def queryfs_fs_size
1796
- data = queryfs(CONST::SMB_QUERY_FS_SIZE_INFO)
1797
- vals = data.unpack('VVVVVV')
1798
- return {
1799
- 'total_alloc_units' => (vals[1] << 32) + vals[0],
1800
- 'total_free_units' => (vals[3] << 32) + vals[2],
1801
- 'sectors_per_unit' => vals[4],
1802
- 'bytes_per_sector' => vals[5]
1803
- }
1804
- end
1805
-
1806
- # Obtains file system device information on the mounted tree
1807
- def queryfs_fs_device
1808
- data = queryfs(CONST::SMB_QUERY_FS_DEVICE_INFO)
1809
- vals = data.unpack('VV')
1810
- return {
1811
- 'device_type' => vals[0],
1812
- 'device_chars' => vals[1],
1813
- }
1814
- end
1815
-
1816
- # Obtains file system attribute information on the mounted tree
1817
- def queryfs_fs_attribute
1818
- data = queryfs(CONST::SMB_QUERY_FS_ATTRIBUTE_INFO)
1819
- vals = data.unpack('VVVA*')
1820
- return {
1821
- 'fs_attributes' => vals[0],
1822
- 'max_file_name' => vals[1],
1823
- 'fs_name' => vals[3][0, vals[2]].gsub("\x00", '')
1824
- }
1825
- end
1826
-
1827
- # Enumerates a specific path on the mounted tree
1828
- def find_first(path)
1829
- files = { }
1830
- parm = [
1831
- 26, # Search for ALL files
1832
- 512, # Maximum search count
1833
- 6, # Resume and Close on End of Search
1834
- 260, # Level of interest
1835
- 0, # Storage type is zero
1836
- ].pack('vvvvV') + path + "\x00"
1837
-
1838
- begin
1839
- resp = trans2(CONST::TRANS2_FIND_FIRST2, parm, '')
1840
-
1841
- pcnt = resp['Payload'].v['ParamCount']
1842
- dcnt = resp['Payload'].v['DataCount']
1843
- poff = resp['Payload'].v['ParamOffset']
1844
- doff = resp['Payload'].v['DataOffset']
1845
-
1846
- # Get the raw packet bytes
1847
- resp_rpkt = resp.to_s
1848
-
1849
- # Remove the NetBIOS header
1850
- resp_rpkt.slice!(0, 4)
1851
-
1852
- resp_parm = resp_rpkt[poff, pcnt]
1853
- resp_data = resp_rpkt[doff, dcnt]
1854
-
1855
- # search id, search count, end of search, error offset, last name offset
1856
- sid, scnt, eos, eoff, loff = resp_parm.unpack('v5')
1857
-
1858
- didx = 0
1859
- while (didx < resp_data.length)
1860
- info_buff = resp_data[didx, 70]
1861
- break if info_buff.length != 70
1862
- info = info_buff.unpack(
1863
- 'V'+ # Next Entry Offset
1864
- 'V'+ # File Index
1865
- 'VV'+ # Time Create
1866
- 'VV'+ # Time Last Access
1867
- 'VV'+ # Time Last Write
1868
- 'VV'+ # Time Change
1869
- 'VV'+ # End of File
1870
- 'VV'+ # Allocation Size
1871
- 'V'+ # File Attributes
1872
- 'V'+ # File Name Length
1873
- 'V'+ # Extended Attr List Length
1874
- 'C'+ # Short File Name Length
1875
- 'C' # Reserved
1876
- )
1877
- name = resp_data[didx + 70 + 24, info[15]].sub!(/\x00+$/, '')
1878
- files[name] =
1879
- {
1880
- 'type' => (info[14] & 0x10) ? 'D' : 'F',
1881
- 'attr' => info[14],
1882
- 'info' => info
1883
- }
1884
-
1885
- break if info[0] == 0
1886
- didx += info[0]
1887
- end
1888
-
1889
- last_search_id = sid
1890
-
1891
- rescue ::Exception
1892
- raise $!
1893
- end
1894
-
1895
- return files
1896
- end
1897
-
1898
- # TODO: Finish this method... requires search_id, resume_key, and filename from first
1899
- =begin
1900
- def find_next(path, sid = last_search_id)
1901
-
1902
- parm = [
1903
- sid, # Search ID
1904
- 512, # Maximum search count
1905
- 260, # Level of interest
1906
- 0, # Resume key from previous
1907
- 1, # Close search if end of search
1908
- ].pack('vvvVv') + path + "\x00"
1909
-
1910
- return files
1911
- end
1912
- =end
1913
-
1914
- # Creates a new directory on the mounted tree
1915
- def create_directory(name)
1916
- files = { }
1917
- parm = [0].pack('V') + name + "\x00"
1918
- resp = trans2(CONST::TRANS2_CREATE_DIRECTORY, parm, '')
1919
- end
1920
-
1921
- # public read/write methods
1922
- attr_accessor :native_os, :native_lm, :encrypt_passwords, :extended_security, :read_timeout, :evasion_opts
1923
- attr_accessor :verify_signature, :use_ntlmv2, :usentlm2_session, :send_lm, :use_lanman_key, :send_ntlm
1924
- attr_accessor :system_time, :system_zone
1925
- #misc
1926
- attr_accessor :spnopt # used for SPN
1927
-
1928
- # public read methods
1929
- attr_reader :dialect, :session_id, :challenge_key, :peer_native_lm, :peer_native_os
1930
- attr_reader :default_domain, :default_name, :auth_user, :auth_user_id
1931
- attr_reader :multiplex_id, :last_tree_id, :last_file_id, :process_id, :last_search_id
1932
- attr_reader :dns_host_name, :dns_domain_name
1933
- attr_reader :security_mode, :server_guid
1934
- #signing related
1935
- attr_reader :sequence_counter,:signing_key, :require_signing
1936
-
1937
- # private methods
1938
- attr_writer :dialect, :session_id, :challenge_key, :peer_native_lm, :peer_native_os
1939
- attr_writer :default_domain, :default_name, :auth_user, :auth_user_id
1940
- attr_writer :dns_host_name, :dns_domain_name
1941
- attr_writer :multiplex_id, :last_tree_id, :last_file_id, :process_id, :last_search_id
1942
- attr_writer :security_mode, :server_guid
1943
- #signing related
1944
- attr_writer :sequence_counter,:signing_key, :require_signing
1945
-
1946
- attr_accessor :socket
1947
-
1948
-
1949
- end
1950
- end
1951
- end
1952
- end