librex 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. data/README +4 -0
  2. data/lib/rex.rb +101 -0
  3. data/lib/rex.rb.ts.rb +70 -0
  4. data/lib/rex/LICENSE +29 -0
  5. data/lib/rex/arch.rb +103 -0
  6. data/lib/rex/arch/sparc.rb +75 -0
  7. data/lib/rex/arch/sparc.rb.ut.rb +18 -0
  8. data/lib/rex/arch/x86.rb +513 -0
  9. data/lib/rex/arch/x86.rb.ut.rb +93 -0
  10. data/lib/rex/assembly/nasm.rb +100 -0
  11. data/lib/rex/assembly/nasm.rb.ut.rb +22 -0
  12. data/lib/rex/codepage.map +104 -0
  13. data/lib/rex/compat.rb +281 -0
  14. data/lib/rex/constants.rb +113 -0
  15. data/lib/rex/elfparsey.rb +11 -0
  16. data/lib/rex/elfparsey/elf.rb +123 -0
  17. data/lib/rex/elfparsey/elfbase.rb +260 -0
  18. data/lib/rex/elfparsey/exceptions.rb +27 -0
  19. data/lib/rex/elfscan.rb +12 -0
  20. data/lib/rex/elfscan/scanner.rb +207 -0
  21. data/lib/rex/elfscan/search.rb +46 -0
  22. data/lib/rex/encoder/alpha2.rb +31 -0
  23. data/lib/rex/encoder/alpha2/alpha_mixed.rb +68 -0
  24. data/lib/rex/encoder/alpha2/alpha_upper.rb +79 -0
  25. data/lib/rex/encoder/alpha2/generic.rb +113 -0
  26. data/lib/rex/encoder/alpha2/unicode_mixed.rb +117 -0
  27. data/lib/rex/encoder/alpha2/unicode_upper.rb +129 -0
  28. data/lib/rex/encoder/ndr.rb +89 -0
  29. data/lib/rex/encoder/ndr.rb.ut.rb +44 -0
  30. data/lib/rex/encoder/nonalpha.rb +61 -0
  31. data/lib/rex/encoder/nonupper.rb +64 -0
  32. data/lib/rex/encoder/xdr.rb +106 -0
  33. data/lib/rex/encoder/xdr.rb.ut.rb +29 -0
  34. data/lib/rex/encoder/xor.rb +69 -0
  35. data/lib/rex/encoder/xor/dword.rb +13 -0
  36. data/lib/rex/encoder/xor/dword_additive.rb +13 -0
  37. data/lib/rex/encoders/xor_dword.rb +35 -0
  38. data/lib/rex/encoders/xor_dword_additive.rb +53 -0
  39. data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +12 -0
  40. data/lib/rex/encoding/xor.rb +20 -0
  41. data/lib/rex/encoding/xor.rb.ts.rb +14 -0
  42. data/lib/rex/encoding/xor/byte.rb +15 -0
  43. data/lib/rex/encoding/xor/byte.rb.ut.rb +21 -0
  44. data/lib/rex/encoding/xor/dword.rb +21 -0
  45. data/lib/rex/encoding/xor/dword.rb.ut.rb +15 -0
  46. data/lib/rex/encoding/xor/dword_additive.rb +92 -0
  47. data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +15 -0
  48. data/lib/rex/encoding/xor/exceptions.rb +17 -0
  49. data/lib/rex/encoding/xor/generic.rb +146 -0
  50. data/lib/rex/encoding/xor/generic.rb.ut.rb +120 -0
  51. data/lib/rex/encoding/xor/qword.rb +15 -0
  52. data/lib/rex/encoding/xor/word.rb +21 -0
  53. data/lib/rex/encoding/xor/word.rb.ut.rb +13 -0
  54. data/lib/rex/exceptions.rb +275 -0
  55. data/lib/rex/exceptions.rb.ut.rb +44 -0
  56. data/lib/rex/exploitation/cmdstager.rb +133 -0
  57. data/lib/rex/exploitation/egghunter.rb +143 -0
  58. data/lib/rex/exploitation/egghunter.rb.ut.rb +25 -0
  59. data/lib/rex/exploitation/encryptjs.rb +77 -0
  60. data/lib/rex/exploitation/heaplib.js.b64 +331 -0
  61. data/lib/rex/exploitation/heaplib.rb +94 -0
  62. data/lib/rex/exploitation/javascriptosdetect.rb +735 -0
  63. data/lib/rex/exploitation/obfuscatejs.rb +335 -0
  64. data/lib/rex/exploitation/opcodedb.rb +818 -0
  65. data/lib/rex/exploitation/opcodedb.rb.ut.rb +279 -0
  66. data/lib/rex/exploitation/seh.rb +92 -0
  67. data/lib/rex/exploitation/seh.rb.ut.rb +19 -0
  68. data/lib/rex/file.rb +84 -0
  69. data/lib/rex/file.rb.ut.rb +16 -0
  70. data/lib/rex/image_source.rb +12 -0
  71. data/lib/rex/image_source/disk.rb +60 -0
  72. data/lib/rex/image_source/image_source.rb +46 -0
  73. data/lib/rex/image_source/memory.rb +37 -0
  74. data/lib/rex/io/bidirectional_pipe.rb +157 -0
  75. data/lib/rex/io/datagram_abstraction.rb +35 -0
  76. data/lib/rex/io/stream.rb +313 -0
  77. data/lib/rex/io/stream_abstraction.rb +186 -0
  78. data/lib/rex/io/stream_server.rb +211 -0
  79. data/lib/rex/job_container.rb +202 -0
  80. data/lib/rex/logging.rb +4 -0
  81. data/lib/rex/logging/log_dispatcher.rb +179 -0
  82. data/lib/rex/logging/log_sink.rb +42 -0
  83. data/lib/rex/logging/sinks/flatfile.rb +55 -0
  84. data/lib/rex/logging/sinks/stderr.rb +43 -0
  85. data/lib/rex/machparsey.rb +9 -0
  86. data/lib/rex/machparsey/exceptions.rb +34 -0
  87. data/lib/rex/machparsey/mach.rb +209 -0
  88. data/lib/rex/machparsey/machbase.rb +408 -0
  89. data/lib/rex/machscan.rb +9 -0
  90. data/lib/rex/machscan/scanner.rb +217 -0
  91. data/lib/rex/mime.rb +9 -0
  92. data/lib/rex/mime/header.rb +75 -0
  93. data/lib/rex/mime/message.rb +112 -0
  94. data/lib/rex/mime/part.rb +20 -0
  95. data/lib/rex/nop/opty2.rb +108 -0
  96. data/lib/rex/nop/opty2.rb.ut.rb +23 -0
  97. data/lib/rex/nop/opty2_tables.rb +300 -0
  98. data/lib/rex/ole.rb +128 -0
  99. data/lib/rex/ole/clsid.rb +47 -0
  100. data/lib/rex/ole/difat.rb +141 -0
  101. data/lib/rex/ole/directory.rb +230 -0
  102. data/lib/rex/ole/direntry.rb +240 -0
  103. data/lib/rex/ole/fat.rb +99 -0
  104. data/lib/rex/ole/header.rb +204 -0
  105. data/lib/rex/ole/minifat.rb +77 -0
  106. data/lib/rex/ole/samples/create_ole.rb +27 -0
  107. data/lib/rex/ole/samples/dir.rb +35 -0
  108. data/lib/rex/ole/samples/dump_stream.rb +34 -0
  109. data/lib/rex/ole/samples/ole_info.rb +23 -0
  110. data/lib/rex/ole/storage.rb +395 -0
  111. data/lib/rex/ole/stream.rb +53 -0
  112. data/lib/rex/ole/substorage.rb +49 -0
  113. data/lib/rex/ole/util.rb +157 -0
  114. data/lib/rex/parser/arguments.rb +97 -0
  115. data/lib/rex/parser/arguments.rb.ut.rb +67 -0
  116. data/lib/rex/parser/ini.rb +185 -0
  117. data/lib/rex/parser/ini.rb.ut.rb +29 -0
  118. data/lib/rex/parser/nmap_xml.rb +111 -0
  119. data/lib/rex/payloads.rb +1 -0
  120. data/lib/rex/payloads/win32.rb +2 -0
  121. data/lib/rex/payloads/win32/common.rb +26 -0
  122. data/lib/rex/payloads/win32/kernel.rb +53 -0
  123. data/lib/rex/payloads/win32/kernel/common.rb +54 -0
  124. data/lib/rex/payloads/win32/kernel/migration.rb +12 -0
  125. data/lib/rex/payloads/win32/kernel/recovery.rb +50 -0
  126. data/lib/rex/payloads/win32/kernel/stager.rb +171 -0
  127. data/lib/rex/peparsey.rb +12 -0
  128. data/lib/rex/peparsey/exceptions.rb +32 -0
  129. data/lib/rex/peparsey/pe.rb +188 -0
  130. data/lib/rex/peparsey/pe_memdump.rb +63 -0
  131. data/lib/rex/peparsey/pebase.rb +1655 -0
  132. data/lib/rex/peparsey/section.rb +136 -0
  133. data/lib/rex/pescan.rb +13 -0
  134. data/lib/rex/pescan/analyze.rb +309 -0
  135. data/lib/rex/pescan/scanner.rb +206 -0
  136. data/lib/rex/pescan/search.rb +56 -0
  137. data/lib/rex/platforms.rb +1 -0
  138. data/lib/rex/platforms/windows.rb +51 -0
  139. data/lib/rex/poly.rb +132 -0
  140. data/lib/rex/poly/block.rb +468 -0
  141. data/lib/rex/poly/register.rb +100 -0
  142. data/lib/rex/poly/register/x86.rb +40 -0
  143. data/lib/rex/post.rb +8 -0
  144. data/lib/rex/post/dir.rb +51 -0
  145. data/lib/rex/post/file.rb +172 -0
  146. data/lib/rex/post/file_stat.rb +220 -0
  147. data/lib/rex/post/gen.pl +13 -0
  148. data/lib/rex/post/io.rb +182 -0
  149. data/lib/rex/post/meterpreter.rb +4 -0
  150. data/lib/rex/post/meterpreter/channel.rb +438 -0
  151. data/lib/rex/post/meterpreter/channel_container.rb +54 -0
  152. data/lib/rex/post/meterpreter/channels/pool.rb +160 -0
  153. data/lib/rex/post/meterpreter/channels/pools/file.rb +62 -0
  154. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +103 -0
  155. data/lib/rex/post/meterpreter/channels/stream.rb +87 -0
  156. data/lib/rex/post/meterpreter/client.rb +335 -0
  157. data/lib/rex/post/meterpreter/client_core.rb +274 -0
  158. data/lib/rex/post/meterpreter/dependencies.rb +3 -0
  159. data/lib/rex/post/meterpreter/extension.rb +32 -0
  160. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +58 -0
  161. data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +16 -0
  162. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +94 -0
  163. data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +21 -0
  164. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +118 -0
  165. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +61 -0
  166. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +104 -0
  167. data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +28 -0
  168. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +100 -0
  169. data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +24 -0
  170. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +333 -0
  171. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +273 -0
  172. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +235 -0
  173. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +103 -0
  174. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +48 -0
  175. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +144 -0
  176. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +73 -0
  177. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +56 -0
  178. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +137 -0
  179. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +167 -0
  180. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +167 -0
  181. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +192 -0
  182. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +139 -0
  183. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +97 -0
  184. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +184 -0
  185. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +41 -0
  186. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +61 -0
  187. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +361 -0
  188. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +129 -0
  189. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +55 -0
  190. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +336 -0
  191. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +141 -0
  192. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +279 -0
  193. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +182 -0
  194. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +102 -0
  195. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +174 -0
  196. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +185 -0
  197. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +227 -0
  198. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +30 -0
  199. data/lib/rex/post/meterpreter/object_aliases.rb +83 -0
  200. data/lib/rex/post/meterpreter/packet.rb +596 -0
  201. data/lib/rex/post/meterpreter/packet_dispatcher.rb +409 -0
  202. data/lib/rex/post/meterpreter/packet_parser.rb +94 -0
  203. data/lib/rex/post/meterpreter/packet_response_waiter.rb +83 -0
  204. data/lib/rex/post/meterpreter/ui/console.rb +135 -0
  205. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +62 -0
  206. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +595 -0
  207. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +108 -0
  208. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +241 -0
  209. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +61 -0
  210. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +98 -0
  211. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +51 -0
  212. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +132 -0
  213. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +187 -0
  214. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +63 -0
  215. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +376 -0
  216. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +270 -0
  217. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +484 -0
  218. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +315 -0
  219. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +95 -0
  220. data/lib/rex/post/permission.rb +26 -0
  221. data/lib/rex/post/process.rb +57 -0
  222. data/lib/rex/post/thread.rb +57 -0
  223. data/lib/rex/post/ui.rb +52 -0
  224. data/lib/rex/proto.rb +12 -0
  225. data/lib/rex/proto.rb.ts.rb +8 -0
  226. data/lib/rex/proto/dcerpc.rb +6 -0
  227. data/lib/rex/proto/dcerpc.rb.ts.rb +9 -0
  228. data/lib/rex/proto/dcerpc/client.rb +358 -0
  229. data/lib/rex/proto/dcerpc/client.rb.ut.rb +491 -0
  230. data/lib/rex/proto/dcerpc/exceptions.rb +150 -0
  231. data/lib/rex/proto/dcerpc/handle.rb +47 -0
  232. data/lib/rex/proto/dcerpc/handle.rb.ut.rb +85 -0
  233. data/lib/rex/proto/dcerpc/ndr.rb +72 -0
  234. data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +41 -0
  235. data/lib/rex/proto/dcerpc/packet.rb +253 -0
  236. data/lib/rex/proto/dcerpc/packet.rb.ut.rb +56 -0
  237. data/lib/rex/proto/dcerpc/response.rb +186 -0
  238. data/lib/rex/proto/dcerpc/response.rb.ut.rb +15 -0
  239. data/lib/rex/proto/dcerpc/uuid.rb +84 -0
  240. data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +46 -0
  241. data/lib/rex/proto/drda.rb +5 -0
  242. data/lib/rex/proto/drda.rb.ts.rb +17 -0
  243. data/lib/rex/proto/drda/constants.rb +49 -0
  244. data/lib/rex/proto/drda/constants.rb.ut.rb +23 -0
  245. data/lib/rex/proto/drda/packet.rb +252 -0
  246. data/lib/rex/proto/drda/packet.rb.ut.rb +109 -0
  247. data/lib/rex/proto/drda/utils.rb +123 -0
  248. data/lib/rex/proto/drda/utils.rb.ut.rb +84 -0
  249. data/lib/rex/proto/http.rb +5 -0
  250. data/lib/rex/proto/http.rb.ts.rb +12 -0
  251. data/lib/rex/proto/http/client.rb +817 -0
  252. data/lib/rex/proto/http/client.rb.ut.rb +93 -0
  253. data/lib/rex/proto/http/handler.rb +46 -0
  254. data/lib/rex/proto/http/handler/erb.rb +128 -0
  255. data/lib/rex/proto/http/handler/erb.rb.ut.rb +21 -0
  256. data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +1 -0
  257. data/lib/rex/proto/http/handler/proc.rb +54 -0
  258. data/lib/rex/proto/http/handler/proc.rb.ut.rb +24 -0
  259. data/lib/rex/proto/http/header.rb +161 -0
  260. data/lib/rex/proto/http/header.rb.ut.rb +46 -0
  261. data/lib/rex/proto/http/packet.rb +394 -0
  262. data/lib/rex/proto/http/packet.rb.ut.rb +165 -0
  263. data/lib/rex/proto/http/request.rb +356 -0
  264. data/lib/rex/proto/http/request.rb.ut.rb +214 -0
  265. data/lib/rex/proto/http/response.rb +85 -0
  266. data/lib/rex/proto/http/response.rb.ut.rb +149 -0
  267. data/lib/rex/proto/http/server.rb +367 -0
  268. data/lib/rex/proto/http/server.rb.ut.rb +79 -0
  269. data/lib/rex/proto/smb.rb +7 -0
  270. data/lib/rex/proto/smb.rb.ts.rb +8 -0
  271. data/lib/rex/proto/smb/client.rb +1733 -0
  272. data/lib/rex/proto/smb/client.rb.ut.rb +223 -0
  273. data/lib/rex/proto/smb/constants.rb +1062 -0
  274. data/lib/rex/proto/smb/constants.rb.ut.rb +18 -0
  275. data/lib/rex/proto/smb/crypt.rb +95 -0
  276. data/lib/rex/proto/smb/crypt.rb.ut.rb +20 -0
  277. data/lib/rex/proto/smb/evasions.rb +65 -0
  278. data/lib/rex/proto/smb/exceptions.rb +846 -0
  279. data/lib/rex/proto/smb/simpleclient.rb +292 -0
  280. data/lib/rex/proto/smb/simpleclient.rb.ut.rb +128 -0
  281. data/lib/rex/proto/smb/utils.rb +514 -0
  282. data/lib/rex/proto/smb/utils.rb.ut.rb +20 -0
  283. data/lib/rex/proto/sunrpc.rb +1 -0
  284. data/lib/rex/proto/sunrpc/client.rb +195 -0
  285. data/lib/rex/script.rb +42 -0
  286. data/lib/rex/script/base.rb +59 -0
  287. data/lib/rex/script/meterpreter.rb +9 -0
  288. data/lib/rex/script/shell.rb +9 -0
  289. data/lib/rex/service.rb +48 -0
  290. data/lib/rex/service_manager.rb +141 -0
  291. data/lib/rex/service_manager.rb.ut.rb +32 -0
  292. data/lib/rex/services/local_relay.rb +423 -0
  293. data/lib/rex/socket.rb +586 -0
  294. data/lib/rex/socket.rb.ut.rb +86 -0
  295. data/lib/rex/socket/comm.rb +119 -0
  296. data/lib/rex/socket/comm/local.rb +409 -0
  297. data/lib/rex/socket/comm/local.rb.ut.rb +75 -0
  298. data/lib/rex/socket/ip.rb +129 -0
  299. data/lib/rex/socket/parameters.rb +345 -0
  300. data/lib/rex/socket/parameters.rb.ut.rb +51 -0
  301. data/lib/rex/socket/range_walker.rb +295 -0
  302. data/lib/rex/socket/range_walker.rb.ut.rb +55 -0
  303. data/lib/rex/socket/ssl_tcp.rb +184 -0
  304. data/lib/rex/socket/ssl_tcp.rb.ut.rb +39 -0
  305. data/lib/rex/socket/ssl_tcp_server.rb +122 -0
  306. data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +51 -0
  307. data/lib/rex/socket/subnet_walker.rb +75 -0
  308. data/lib/rex/socket/subnet_walker.rb.ut.rb +28 -0
  309. data/lib/rex/socket/switch_board.rb +272 -0
  310. data/lib/rex/socket/switch_board.rb.ut.rb +52 -0
  311. data/lib/rex/socket/tcp.rb +76 -0
  312. data/lib/rex/socket/tcp.rb.ut.rb +64 -0
  313. data/lib/rex/socket/tcp_server.rb +67 -0
  314. data/lib/rex/socket/tcp_server.rb.ut.rb +44 -0
  315. data/lib/rex/socket/udp.rb +157 -0
  316. data/lib/rex/socket/udp.rb.ut.rb +44 -0
  317. data/lib/rex/struct2.rb +5 -0
  318. data/lib/rex/struct2/c_struct.rb +181 -0
  319. data/lib/rex/struct2/c_struct_template.rb +39 -0
  320. data/lib/rex/struct2/constant.rb +26 -0
  321. data/lib/rex/struct2/element.rb +44 -0
  322. data/lib/rex/struct2/generic.rb +73 -0
  323. data/lib/rex/struct2/restraint.rb +54 -0
  324. data/lib/rex/struct2/s_string.rb +72 -0
  325. data/lib/rex/struct2/s_struct.rb +111 -0
  326. data/lib/rex/sync.rb +6 -0
  327. data/lib/rex/sync/event.rb +94 -0
  328. data/lib/rex/sync/read_write_lock.rb +176 -0
  329. data/lib/rex/sync/ref.rb +57 -0
  330. data/lib/rex/sync/thread_safe.rb +82 -0
  331. data/lib/rex/test.rb +35 -0
  332. data/lib/rex/text.rb +1029 -0
  333. data/lib/rex/text.rb.ut.rb +168 -0
  334. data/lib/rex/time.rb +65 -0
  335. data/lib/rex/transformer.rb +115 -0
  336. data/lib/rex/transformer.rb.ut.rb +38 -0
  337. data/lib/rex/ui.rb +21 -0
  338. data/lib/rex/ui/interactive.rb +252 -0
  339. data/lib/rex/ui/output.rb +80 -0
  340. data/lib/rex/ui/output/none.rb +18 -0
  341. data/lib/rex/ui/progress_tracker.rb +96 -0
  342. data/lib/rex/ui/subscriber.rb +149 -0
  343. data/lib/rex/ui/text/color.rb +97 -0
  344. data/lib/rex/ui/text/color.rb.ut.rb +18 -0
  345. data/lib/rex/ui/text/dispatcher_shell.rb +382 -0
  346. data/lib/rex/ui/text/input.rb +117 -0
  347. data/lib/rex/ui/text/input/buffer.rb +75 -0
  348. data/lib/rex/ui/text/input/readline.rb +129 -0
  349. data/lib/rex/ui/text/input/socket.rb +95 -0
  350. data/lib/rex/ui/text/input/stdio.rb +45 -0
  351. data/lib/rex/ui/text/irb_shell.rb +55 -0
  352. data/lib/rex/ui/text/output.rb +80 -0
  353. data/lib/rex/ui/text/output/buffer.rb +65 -0
  354. data/lib/rex/ui/text/output/file.rb +37 -0
  355. data/lib/rex/ui/text/output/socket.rb +43 -0
  356. data/lib/rex/ui/text/output/stdio.rb +40 -0
  357. data/lib/rex/ui/text/progress_tracker.rb +56 -0
  358. data/lib/rex/ui/text/progress_tracker.rb.ut.rb +34 -0
  359. data/lib/rex/ui/text/shell.rb +321 -0
  360. data/lib/rex/ui/text/table.rb +254 -0
  361. data/lib/rex/ui/text/table.rb.ut.rb +55 -0
  362. data/lib/rex/zip.rb +93 -0
  363. data/lib/rex/zip/archive.rb +91 -0
  364. data/lib/rex/zip/blocks.rb +182 -0
  365. data/lib/rex/zip/entry.rb +95 -0
  366. data/lib/rex/zip/samples/comment.rb +32 -0
  367. data/lib/rex/zip/samples/mkwar.rb +138 -0
  368. data/lib/rex/zip/samples/mkzip.rb +19 -0
  369. data/lib/rex/zip/samples/recursive.rb +58 -0
  370. metadata +435 -0
@@ -0,0 +1,356 @@
1
+ require 'uri'
2
+ require 'rex/proto/http'
3
+
4
+ module Rex
5
+ module Proto
6
+ module Http
7
+
8
+ ###
9
+ #
10
+ # HTTP request class.
11
+ #
12
+ ###
13
+ class Request < Packet
14
+
15
+ PostRequests = ['POST', 'SEARCH']
16
+
17
+ ##
18
+ #
19
+ # Some individual request types.
20
+ #
21
+ ##
22
+
23
+ #
24
+ # HTTP GET request class wrapper.
25
+ #
26
+ class Get < Request
27
+ def initialize(uri = '/', proto = DefaultProtocol)
28
+ super('GET', uri, proto)
29
+ end
30
+ end
31
+
32
+ #
33
+ # HTTP POST request class wrapper.
34
+ #
35
+ class Post < Request
36
+ def initialize(uri = '/', proto = DefaultProtocol)
37
+ super('POST', uri, proto)
38
+ end
39
+ end
40
+
41
+ #
42
+ # HTTP PUT request class wrapper.
43
+ #
44
+ class Put < Request
45
+ def initialize(uri = '/', proto = DefaultProtocol)
46
+ super('PUT', uri, proto)
47
+ end
48
+ end
49
+
50
+ #
51
+ # Initializes an instance of an HTTP request with the supplied method, URI,
52
+ # and protocol.
53
+ #
54
+ def initialize(method = 'GET', uri = '/', proto = DefaultProtocol)
55
+ super()
56
+
57
+ self.method = method
58
+ self.raw_uri = uri
59
+ self.uri_parts = {}
60
+ self.proto = proto || DefaultProtocol
61
+ self.chunk_min_size = 1
62
+ self.chunk_max_size = 10
63
+ self.uri_encode_mode = 'hex-normal'
64
+
65
+ update_uri_parts
66
+ end
67
+
68
+ #
69
+ # Updates the command parts for this specific packet type.
70
+ #
71
+ def update_cmd_parts(str)
72
+ if (md = str.match(/^(.+?)\s+(.+?)\s+HTTP\/(.+?)\r?\n?$/))
73
+ self.method = md[1]
74
+ self.raw_uri = URI.decode(md[2])
75
+ self.proto = md[3]
76
+
77
+ update_uri_parts
78
+ else
79
+ raise RuntimeError, "Invalid request command string", caller
80
+ end
81
+ end
82
+
83
+ #
84
+ # Split the URI into the resource being requested and its query string.
85
+ #
86
+ def update_uri_parts
87
+ # If it has a query string, get the parts.
88
+ if ((self.raw_uri) and (md = self.raw_uri.match(/(.+?)\?(.*)$/)))
89
+ self.uri_parts['QueryString'] = parse_cgi_qstring(md[2])
90
+ self.uri_parts['Resource'] = md[1]
91
+ # Otherwise, just assume that the URI is equal to the resource being
92
+ # requested.
93
+ else
94
+ self.uri_parts['QueryString'] = {}
95
+ self.uri_parts['Resource'] = self.raw_uri
96
+ end
97
+
98
+ self.normalize!(resource)
99
+ # Set the relative resource to the actual resource.
100
+ self.relative_resource = resource
101
+ end
102
+
103
+ # normalize out multiple slashes, directory traversal, and self referrential directories
104
+ def normalize!(str)
105
+ i = 0
106
+ while (str.gsub!(/(\/\.\/|\/\w+\/\.\.\/|\/\/)/,'/')); i += 1; end
107
+ i
108
+ end
109
+
110
+ # Puts a URI back together based on the URI parts
111
+ def uri
112
+ str = self.uri_parts['Resource'].dup || '/'
113
+
114
+ # /././././
115
+ if self.junk_self_referring_directories
116
+ str.gsub!(/\//) {
117
+ '/.' * (rand(3) + 1) + '/'
118
+ }
119
+ end
120
+
121
+ # /%3faaa=bbbbb
122
+ # which could possibly decode to "/?aaa=bbbbb", which if the IDS normalizes first, then splits the URI on ?, then it can be bypassed
123
+ if self.junk_param_start
124
+ str.sub!(/\//, '/%3f' + Rex::Text.rand_text_alpha(rand(5) + 1) + '=' + Rex::Text.rand_text_alpha(rand(10) + 1) + '/../')
125
+ end
126
+
127
+ # /RAND/../RAND../
128
+ if self.junk_directories
129
+ str.gsub!(/\//) {
130
+ dirs = ''
131
+ (rand(5)+5).times {
132
+ dirs << '/' + Rex::Text.rand_text_alpha(rand(5) + 1) + '/..'
133
+ }
134
+ dirs + '/'
135
+ }
136
+ end
137
+
138
+ # ////
139
+ #
140
+ # NOTE: this must be done after all other odd directory junk, since they would cancel this out, except junk_end_of_uri, since that a specific slash in a specific place
141
+ if self.junk_slashes
142
+ str.gsub!(/\//) {
143
+ '/' * (rand(3) + 2)
144
+ }
145
+ str.sub!(/^[\/]+/, '/') # only one beginning slash!
146
+ end
147
+
148
+ # /%20HTTP/1.0%0d%0a/../../
149
+ # which decodes to "/ HTTP/1.0\r\n"
150
+ if self.junk_end_of_uri
151
+ str.sub!(/^\//, '/%20HTTP/1.0%0d%0a/../../')
152
+ end
153
+
154
+ Rex::Text.uri_encode(str, self.uri_encode_mode)
155
+
156
+ if !PostRequests.include?(self.method)
157
+ if param_string.size > 0
158
+ str << '?' + param_string
159
+ end
160
+ end
161
+ str
162
+ end
163
+
164
+ def param_string
165
+ params=[]
166
+ self.uri_parts['QueryString'].each_pair { |param, value|
167
+ # inject a random number of params in between each param
168
+ if self.junk_params
169
+ rand(10)+5.times {
170
+ params.push(Rex::Text.rand_text_alpha(rand(16) + 5) + '=' + Rex::Text.rand_text_alpha(rand(10) + 1))
171
+ }
172
+ end
173
+ if value.kind_of?(Array)
174
+ value.each { |subvalue|
175
+ params.push(Rex::Text.uri_encode(param, self.uri_encode_mode) + '=' + Rex::Text.uri_encode(subvalue, self.uri_encode_mode))
176
+ }
177
+ else
178
+ if !value.nil?
179
+ params.push(Rex::Text.uri_encode(param, self.uri_encode_mode) + '=' + Rex::Text.uri_encode(value, self.uri_encode_mode))
180
+ else
181
+ params.push(Rex::Text.uri_encode(param, self.uri_encode_mode))
182
+ end
183
+ end
184
+ }
185
+
186
+ # inject some junk params at the end of the param list, just to be sure :P
187
+ if self.junk_params
188
+ rand(10)+5.times {
189
+ params.push(Rex::Text.rand_text_alpha(rand(32) + 5) + '=' + Rex::Text.rand_text_alpha(rand(64) + 5))
190
+ }
191
+ end
192
+ params.join('&')
193
+ end
194
+
195
+ # Updates the underlying URI structure
196
+ def uri=(str)
197
+ self.raw_uri = str
198
+ update_uri_parts
199
+ end
200
+
201
+ # Returns a request packet
202
+ def to_s
203
+ str = ''
204
+ if self.junk_pipeline
205
+ host = ''
206
+ if self.headers['Host']
207
+ host = "Host: #{self.headers['Host']}\r\n"
208
+ end
209
+ str << "GET / HTTP/1.1\r\n#{host}Connection: Keep-Alive\r\n\r\n" * self.junk_pipeline
210
+ self.headers['Connection'] = 'Closed'
211
+ end
212
+ str + super
213
+ end
214
+
215
+ def body
216
+ str = super || ''
217
+ if str.length > 0
218
+ return str
219
+ end
220
+
221
+ if PostRequests.include?(self.method)
222
+ return param_string
223
+ end
224
+ ''
225
+ end
226
+
227
+ #
228
+ # Returns the command string derived from the three values.
229
+ #
230
+ def cmd_string
231
+ proto_str = (self.proto =~ /^\d/) ? "HTTP/#{self.proto}" : self.proto
232
+
233
+ "#{self.method} #{self.uri} #{proto_str}\r\n"
234
+ end
235
+
236
+ #
237
+ # Returns the resource that is being requested.
238
+ #
239
+ def resource
240
+ self.uri_parts['Resource']
241
+ end
242
+
243
+ #
244
+ # Changes the resource URI. This is used when making a request relative to
245
+ # a given mount point.
246
+ #
247
+ def resource=(rsrc)
248
+ self.uri_parts['Resource'] = rsrc
249
+ end
250
+
251
+ #
252
+ # If there were CGI parameters in the URI, this will hold a hash of each
253
+ # variable to value. If there is more than one value for a given variable,
254
+ # an array of each value is returned.
255
+ #
256
+ def qstring
257
+ self.uri_parts['QueryString']
258
+ end
259
+
260
+ #
261
+ # Returns a hash of variables that contain information about the request,
262
+ # such as the remote host information.
263
+ #
264
+ # TODO
265
+ #
266
+ def meta_vars
267
+ end
268
+
269
+ #
270
+ # The method being used for the request (e.g. GET).
271
+ #
272
+ attr_accessor :method
273
+ #
274
+ # The raw URI being requested, before any mucking gets to it
275
+ #
276
+ attr_accessor :raw_uri
277
+
278
+ #
279
+ # The split up parts of the URI.
280
+ #
281
+ attr_accessor :uri_parts
282
+ #
283
+ # The protocol to be sent with the request.
284
+ #
285
+ attr_accessor :proto
286
+
287
+ #
288
+ # The resource path relative to the root of a server mount point.
289
+ #
290
+ attr_accessor :relative_resource
291
+
292
+ # add junk directories
293
+ attr_accessor :junk_directories
294
+
295
+ # add junk slashes
296
+ attr_accessor :junk_slashes
297
+
298
+ # add junk self referring directories (aka /././././)
299
+ attr_accessor :junk_self_referring_directories
300
+
301
+ # add junk params
302
+ attr_accessor :junk_params
303
+
304
+ # add junk pipeline requests
305
+ attr_accessor :junk_pipeline
306
+
307
+ # add junk start of params
308
+ attr_accessor :junk_param_start
309
+
310
+ # add junk end of URI
311
+ attr_accessor :junk_end_of_uri
312
+
313
+ # encoding uri
314
+ attr_accessor :uri_encode_mode
315
+
316
+
317
+ protected
318
+
319
+ #
320
+ # Parses a CGI query string into the var/val combinations.
321
+ #
322
+ def parse_cgi_qstring(str)
323
+ qstring = {}
324
+
325
+ # Delimit on each variable
326
+ str.split(/[;&]/).each { |vv|
327
+ var = vv
328
+ val = ''
329
+
330
+ if (md = vv.match(/(.+?)=(.*)/))
331
+ var = md[1]
332
+ val = md[2]
333
+ end
334
+
335
+ # Add the item to the hash with logic to convert values to an array
336
+ # if so desired.
337
+ if (qstring.include?(var))
338
+ if (qstring[var].kind_of?(Array))
339
+ qstring[var] << val
340
+ else
341
+ curr = self.qstring[var]
342
+ qstring[var] = [ curr, val ]
343
+ end
344
+ else
345
+ qstring[var] = val
346
+ end
347
+ }
348
+
349
+ return qstring
350
+ end
351
+
352
+ end
353
+
354
+ end
355
+ end
356
+ end
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..'))
4
+
5
+ require 'test/unit'
6
+ require 'rex/proto/http'
7
+
8
+ class Rex::Proto::Http::Request::UnitTest < Test::Unit::TestCase
9
+
10
+ Klass = Rex::Proto::Http::Request
11
+
12
+ def test_to_s
13
+ h = Klass.new
14
+
15
+ h.headers['Foo'] = 'Fishing'
16
+ h.headers['Chicken'] = 47
17
+ h.auto_cl = true
18
+
19
+ assert_equal(
20
+ "GET / HTTP/1.1\r\n" +
21
+ "Foo: Fishing\r\n" +
22
+ "Content-Length: 0\r\n" +
23
+ "Chicken: 47\r\n\r\n", h.to_s)
24
+ end
25
+
26
+ def test_from_s
27
+ h = Klass.new
28
+
29
+ h.from_s(
30
+ "POST /foo HTTP/1.0\r\n" +
31
+ "Lucifer: Beast\r\n" +
32
+ "HoHo: Satan\r\n" +
33
+ "Eat: Babies\r\n" +
34
+ "\r\n")
35
+
36
+ assert_equal('POST', h.method, 'method')
37
+ assert_equal('/foo', h.uri, 'uri')
38
+ assert_equal('1.0', h.proto, 'proto')
39
+ assert_equal('Babies', h['Eat'], 'header')
40
+
41
+ assert_equal("POST /foo HTTP/1.0\r\n", h.cmd_string, 'cmd_string')
42
+
43
+ h.method = 'GET'
44
+ assert_equal("GET /foo HTTP/1.0\r\n", h.cmd_string, 'set method')
45
+
46
+ h.uri = '/bar'
47
+ assert_equal("GET /bar HTTP/1.0\r\n", h.cmd_string, 'set uri')
48
+
49
+ h.proto = '1.2'
50
+ assert_equal("GET /bar HTTP/1.2\r\n", h.cmd_string, 'set proto')
51
+ end
52
+
53
+ def junk_request
54
+ h = Klass.new
55
+ h.from_s("GET /foo/bar.html HTTP/1.0\r\n" + "Foo: Bar\r\n\r\n")
56
+ return h
57
+ end
58
+
59
+ def test_junk_slashes
60
+ srand(0)
61
+
62
+ h = junk_request
63
+ assert_equal('GET', h.method, 'method')
64
+ assert_equal('1.0', h.proto, 'proto')
65
+ assert_equal('Bar', h['Foo'], 'header')
66
+ assert_equal('/foo/bar.html', h.uri, 'uri')
67
+
68
+ h = junk_request
69
+ h.junk_directories = 1
70
+ assert_equal('/D/../DnJT/../kXG/../Y/../BmnXu/../foo/lZ/../J/../zQzFP/../S/../Yxzd/../bar.html', h.uri, 'junk directories')
71
+
72
+ h = junk_request
73
+ h.junk_slashes = 1
74
+ assert_equal('/foo//bar.html', h.uri, 'junk slashes')
75
+
76
+ h = junk_request
77
+ h.junk_self_referring_directories = 1
78
+ assert_equal('/././foo/././bar.html', h.uri, 'junk referring directories')
79
+
80
+ h = junk_request
81
+ h.junk_param_start = 1
82
+ assert_equal('/%3fgf=XjLyc/../foo/bar.html', h.uri, 'junk start of params')
83
+
84
+ h = junk_request
85
+ h.junk_end_of_uri = 1
86
+ assert_equal('/%20HTTP/1.0%0d%0a/../../foo/bar.html', h.uri, 'junk end of URI')
87
+ end
88
+
89
+ def test_params
90
+ srand(0)
91
+
92
+ h = junk_request
93
+ assert_equal('/foo/bar.html', h.uri, 'uri')
94
+
95
+ h.uri_parts['QueryString']['B'] = 'a'
96
+ assert_equal('/foo/bar.html?B=a', h.uri, 'uri with param')
97
+
98
+ h.uri_parts['QueryString']['B'] = ['a','b']
99
+ assert_equal('/foo/bar.html?B=a&B=b', h.uri, 'uri with a param with multiple values')
100
+
101
+ h.uri_parts['QueryString']['B'] = '='
102
+ assert_equal('/foo/bar.html?B=%3d', h.uri, 'uri with a param that requires escaping')
103
+
104
+ assert_equal(
105
+ "GET /foo/bar.html?B=%3d HTTP/1.0\r\n" +
106
+ "Foo: Bar\r\n" +
107
+ "Content-Length: 0\r\n" +
108
+ "\r\n", h.to_s, 'GET to_s'
109
+ )
110
+
111
+ h.method = 'POST'
112
+ assert_equal(
113
+ "POST /foo/bar.html HTTP/1.0\r\n" +
114
+ "Foo: Bar\r\n" +
115
+ "Content-Length: 5\r\n" +
116
+ "\r\n" +
117
+ 'B=%3d',
118
+ h.to_s, 'POST to_s'
119
+ )
120
+
121
+ h.body = 'FOO'
122
+ assert_equal(
123
+ "POST /foo/bar.html HTTP/1.0\r\n" +
124
+ "Foo: Bar\r\n" +
125
+ "Content-Length: 3\r\n" +
126
+ "\r\n" +
127
+ 'FOO',
128
+ h.to_s, 'POST to_s, with hardcoded body'
129
+ )
130
+
131
+ end
132
+
133
+ def test_junk_params
134
+ srand(0)
135
+ h = junk_request
136
+
137
+ h.junk_params = 1
138
+ h.uri_parts['QueryString']['a'] = 'b'
139
+ h.uri_parts['QueryString']['c'] = 'd'
140
+
141
+ assert_equal("GET /foo/bar.html?eZUhlXbdhzzW=HpxJATk&UwDqBU=EQwvK&oebrfUGJbvjTMSxKih=MkBx&nYkjF=DiohcEa&tzJFh=eIUHDVbs&a=b&UHTfAFbreJT=VlcIruAo&mZKziXgT=z&hsytpEdbRjC=tPkpE&yNetXi=JaaW&PiazmuQvoAKLNHeGt=ePpmrS&c=d&BpCycOlbkfdyudyhMgpQCIzKwabBAFYiP=ulrTYGUG&zGCccmlFtJkNVfRjtzIZVtlWQZulBFGMa=OIHtFvqDKybZDOS&ERFeYDFokx=YhShOxHruwhRdMugizXZuyrpuAMJSEHDwMltwtSzxHaxudDKUqBUQqycaXwC&JCspZkaEpKM=hlnghajZyYSUecISZYnqcYSDsTtAKDGbjGTiyymUrAktp&hMPhXMF=BKGGmmLyVyyzCMdJzIFrBrPMvMVSZNecspVGkwoaeFP HTTP/1.0\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n", h.to_s, 'junk params (GET)')
142
+
143
+ h.method = 'POST'
144
+ assert_equal("POST /foo/bar.html HTTP/1.0\r\nFoo: Bar\r\nContent-Length: 591\r\n\r\nxfgwQgKMdA=WTFkTkFc&axTMmHQdAXPKDDQwJ=lwRJs&PmOhEQkHXbuHWieQbvv=LXO&eaiRjHtwlENl=rIgR&kBdFQmoWeT=UqKDW&a=b&dpoRzoqedheulYQ=ndBX&AXlvaZZGYPlpR=w&uFTvWtLLhHawHvgk=XVC&KFmmkBkFFmjYx=yJExY&CTDNLNkRaGviVUqRlZV=kEviLihu&c=d&LhZhftGZYtmzQXaDaudCF=HPOjnHzmzdxLDNYEzWdmLOSZsDlHdOLJLQnBScAVYJISLczRPDqYVcVOvBMLZn&atiBQBQhhsmoINqT=gXEfWAlfPTPzMtKpQGVeDQABygrSSWPPcHbYYMNSOOUHsrbsPXLNdfu&EcBxxXQpawCvRUmAGsWPKio=VigqsjpnbwKERDleXdmeLCdHzJXAwRozVeaPwRKRDnJ&DHQiEakGgRlbzOWfIdcfiRcvQIsHMgUrLd=AUtcNlvnyEuMlwEpkQSleujwAxJyhwxMGzkjmkeyTmsjO&zRDdbDhzbkVnqKdxdYyQAkiNBCCTMenVNx=zMxABkKqgcCcBNTvRkHGJPSdqSCdRjT",h.to_s, 'junk params (POST)')
145
+
146
+ h.method = 'SEARCH'
147
+ assert_equal("SEARCH /foo/bar.html HTTP/1.0\r\nFoo: Bar\r\nContent-Length: 522\r\n\r\nMjtCUDRsmqKl=vbEzWljeH&YvPKTNnlnSHYg=ovkqQaoQ&geUXPsTibtiRXbNwXeF=nhxicBEVIy&jwjZFB=HBBH&kNsybgrTitkQwq=rDITuAUgir&a=b&YCHsLzcfBQ=SOV&vFhqCboTPHsdjhwxQYFz=RtgW&mJFMqQ=EZ&tRdGcKFkkUyyWKreOzw=BoHFPpgXO&dzZEAaU=YREgxR&c=d&kfeJswjgOXgcrh=usIlCRPDVwydlWSHxaEtZazvTOSgbkmUsDSNzxfhSMvbniHetQBYQtb&yYwMEwzuoO=KbOmNEWPdOqZLfbWurUCZAfuGSWuZNMlTfcTooZvdcqKURAnmiBwWt&xWncBVCgyGmjkXzSmZuPxbVBJzRLADk=TvFUEpQQFgWDIcpKmcfsLibxH&mFJYMohOtPEW=CHtIFnPPpZWZZTdJLjanSIBjyxuKKYfrbNOFXqnxlmLrYRVeSZdlxoxqf&LOgBBkZMIyMY=DKHcOIujjRXMtHvuneTqtyBr", h.to_s, 'junk params (SEARCH)')
148
+ end
149
+
150
+ def test_junk_pipelining
151
+ srand(0)
152
+
153
+ h = Klass.new
154
+ h.from_s("GET /foo HTTP/1.0\r\n" + "Foo: Bar\r\n\r\n")
155
+ h.junk_pipeline = 1
156
+ assert_equal("GET / HTTP/1.1\r\nConnection: Keep-Alive\r\n\r\nGET /foo HTTP/1.0\r\nFoo: Bar\r\nContent-Length: 0\r\nConnection: Closed\r\n\r\n", h.to_s, 'pipeline')
157
+ end
158
+
159
+ def test_junk_all
160
+ srand(0)
161
+
162
+ h = junk_request
163
+ h.junk_slashes = 1
164
+ h.junk_directories = 1
165
+ h.junk_self_referring_directories = 1
166
+ h.junk_end_of_uri = 1
167
+ h.junk_param_start = 1
168
+
169
+ seen = {}
170
+ expect = [
171
+ {"//"=>145, "/./"=>35, "param"=>1, "http"=>1, "/w/../"=>3},
172
+ {"//"=>149, "/./"=>35, "param"=>1, "http"=>1, "/w/../"=>3},
173
+ {"//"=>130, "/./"=>30, "param"=>1, "http"=>1, "/w/../"=>2},
174
+ {"//"=>165, "/./"=>40, "param"=>1, "http"=>1, "/w/../"=>4},
175
+ {"//"=>145, "/./"=>35, "param"=>1, "http"=>1, "/w/../"=>3},
176
+ ]
177
+ i = 0
178
+ 5.times {
179
+ str = h.uri.dup
180
+ assert_not_equal('/foo/bar.html', str, 'all the junk')
181
+ assert_nil(seen[str], 'all the junk, not a dup rand')
182
+ seen[str] = 1
183
+
184
+ seen = { '/./' => 0, '//' => 0, '/w/../' => 0, 'http' => 0, 'param' => 0}
185
+ matched = 1
186
+ while matched == 1
187
+ # p str
188
+ if str.sub!(/\/%20HTTP\/1.0%0d%0a\/\.\.\/\.\.\//, '/')
189
+ seen['http'] += 1;
190
+ elsif str.sub!(/\/%3f\w+=\w+\/\.\.\//i, '/')
191
+ seen['param'] += 1;
192
+ elsif str.sub!(/\/\w+\/\.\.\//, '/')
193
+ seen['/./'] += 1;
194
+ elsif str.sub!(/\/\//, '/')
195
+ seen['//'] += 1;
196
+ elsif str.sub!(/\/.\//, '/')
197
+ seen['/w/../'] += 1;
198
+ else
199
+ matched = 0
200
+ end
201
+ end
202
+
203
+ assert_equal('/foo/bar.html', str, 'normalized')
204
+ assert_equal(expect[i], seen, 'expected counts')
205
+ i += 1
206
+ }
207
+ end
208
+
209
+ def test_normalize
210
+ h = junk_request
211
+ h.uri = '/foo/..////./././asdf/././//../bar.html'
212
+ assert_equal('/bar.html', h.uri, 'normalize on set')
213
+ end
214
+ end