ronin-support 0.4.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (224) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +11 -0
  3. data/.github/workflows/ruby.yml +28 -0
  4. data/.ruby-version +1 -0
  5. data/.yardopts +1 -1
  6. data/ChangeLog.md +121 -33
  7. data/Gemfile +17 -18
  8. data/README.md +57 -33
  9. data/Rakefile +10 -3
  10. data/gemspec.yml +16 -7
  11. data/lib/ronin/binary.rb +21 -0
  12. data/lib/ronin/binary/hexdump.rb +20 -0
  13. data/lib/ronin/binary/hexdump/parser.rb +403 -0
  14. data/lib/ronin/binary/struct.rb +567 -0
  15. data/lib/ronin/binary/template.rb +454 -0
  16. data/lib/ronin/extensions.rb +5 -5
  17. data/lib/ronin/extensions/enumerable.rb +5 -5
  18. data/lib/ronin/extensions/file.rb +39 -33
  19. data/lib/ronin/extensions/ip_addr.rb +29 -31
  20. data/lib/ronin/extensions/kernel.rb +5 -5
  21. data/lib/ronin/extensions/meta.rb +5 -5
  22. data/lib/ronin/extensions/regexp.rb +50 -5
  23. data/lib/ronin/extensions/resolv.rb +7 -9
  24. data/lib/ronin/extensions/string.rb +10 -10
  25. data/lib/ronin/formatting.rb +5 -5
  26. data/lib/ronin/formatting/binary.rb +5 -5
  27. data/lib/ronin/formatting/digest.rb +5 -5
  28. data/lib/ronin/formatting/extensions.rb +5 -5
  29. data/lib/ronin/formatting/extensions/binary.rb +7 -5
  30. data/lib/ronin/formatting/extensions/binary/array.rb +61 -0
  31. data/lib/ronin/formatting/extensions/binary/base64.rb +106 -0
  32. data/lib/ronin/formatting/extensions/binary/file.rb +44 -11
  33. data/lib/ronin/formatting/extensions/binary/float.rb +65 -0
  34. data/lib/ronin/formatting/extensions/binary/integer.rb +66 -50
  35. data/lib/ronin/formatting/extensions/binary/string.rb +81 -205
  36. data/lib/ronin/formatting/extensions/digest.rb +5 -5
  37. data/lib/ronin/formatting/extensions/digest/file.rb +5 -5
  38. data/lib/ronin/formatting/extensions/digest/string.rb +5 -5
  39. data/lib/ronin/formatting/extensions/html.rb +5 -5
  40. data/lib/ronin/formatting/extensions/html/integer.rb +9 -13
  41. data/lib/ronin/formatting/extensions/html/string.rb +31 -39
  42. data/lib/ronin/formatting/extensions/http.rb +5 -5
  43. data/lib/ronin/formatting/extensions/http/integer.rb +6 -6
  44. data/lib/ronin/formatting/extensions/http/string.rb +7 -7
  45. data/lib/ronin/formatting/extensions/sql.rb +5 -5
  46. data/lib/ronin/formatting/extensions/sql/string.rb +22 -24
  47. data/lib/ronin/formatting/extensions/text.rb +5 -5
  48. data/lib/ronin/formatting/extensions/text/array.rb +13 -11
  49. data/lib/ronin/formatting/extensions/text/string.rb +70 -13
  50. data/lib/ronin/formatting/html.rb +5 -5
  51. data/lib/ronin/formatting/http.rb +5 -5
  52. data/lib/ronin/formatting/sql.rb +5 -5
  53. data/lib/ronin/formatting/text.rb +5 -5
  54. data/lib/ronin/fuzzing.rb +5 -5
  55. data/lib/ronin/fuzzing/extensions.rb +5 -5
  56. data/lib/ronin/fuzzing/extensions/string.rb +42 -213
  57. data/lib/ronin/fuzzing/fuzzer.rb +110 -0
  58. data/lib/ronin/fuzzing/fuzzing.rb +33 -26
  59. data/lib/ronin/fuzzing/mutator.rb +161 -0
  60. data/lib/ronin/fuzzing/repeater.rb +81 -0
  61. data/lib/ronin/fuzzing/template.rb +133 -0
  62. data/lib/ronin/mixin.rb +2 -2
  63. data/lib/ronin/network.rb +7 -5
  64. data/lib/ronin/network/dns.rb +64 -24
  65. data/lib/ronin/network/esmtp.rb +5 -5
  66. data/lib/ronin/network/extensions.rb +5 -5
  67. data/lib/ronin/network/extensions/dns.rb +5 -5
  68. data/lib/ronin/network/extensions/dns/net.rb +5 -5
  69. data/lib/ronin/network/extensions/esmtp.rb +5 -5
  70. data/lib/ronin/network/extensions/esmtp/net.rb +5 -5
  71. data/lib/ronin/network/extensions/http.rb +5 -5
  72. data/lib/ronin/network/extensions/http/net.rb +5 -5
  73. data/lib/ronin/network/extensions/http/uri/http.rb +5 -5
  74. data/lib/ronin/network/extensions/imap.rb +5 -5
  75. data/lib/ronin/network/extensions/imap/net.rb +5 -5
  76. data/lib/ronin/network/extensions/pop3.rb +5 -5
  77. data/lib/ronin/network/extensions/pop3/net.rb +5 -5
  78. data/lib/ronin/network/extensions/smtp.rb +5 -5
  79. data/lib/ronin/network/extensions/smtp/net.rb +5 -5
  80. data/lib/ronin/network/extensions/ssl.rb +5 -5
  81. data/lib/ronin/network/extensions/ssl/net.rb +5 -5
  82. data/lib/ronin/network/extensions/tcp.rb +5 -5
  83. data/lib/ronin/network/extensions/tcp/net.rb +5 -5
  84. data/lib/ronin/network/extensions/telnet.rb +5 -5
  85. data/lib/ronin/network/extensions/telnet/net.rb +5 -5
  86. data/lib/ronin/network/extensions/udp.rb +5 -5
  87. data/lib/ronin/network/extensions/udp/net.rb +5 -5
  88. data/lib/ronin/network/ftp.rb +149 -0
  89. data/lib/ronin/network/http.rb +5 -5
  90. data/lib/ronin/network/http/exceptions.rb +5 -5
  91. data/lib/ronin/network/http/exceptions/unknown_request.rb +5 -5
  92. data/lib/ronin/network/http/http.rb +65 -70
  93. data/lib/ronin/network/http/proxy.rb +5 -5
  94. data/lib/ronin/network/imap.rb +16 -15
  95. data/lib/ronin/network/mixins.rb +6 -5
  96. data/lib/ronin/network/mixins/dns.rb +5 -5
  97. data/lib/ronin/network/mixins/esmtp.rb +5 -5
  98. data/lib/ronin/network/mixins/ftp.rb +155 -0
  99. data/lib/ronin/network/mixins/http.rb +58 -587
  100. data/lib/ronin/network/mixins/imap.rb +5 -5
  101. data/lib/ronin/network/mixins/mixin.rb +5 -5
  102. data/lib/ronin/network/mixins/pop3.rb +5 -5
  103. data/lib/ronin/network/mixins/smtp.rb +5 -5
  104. data/lib/ronin/network/mixins/ssl.rb +5 -5
  105. data/lib/ronin/network/mixins/tcp.rb +43 -10
  106. data/lib/ronin/network/mixins/telnet.rb +5 -5
  107. data/lib/ronin/network/mixins/udp.rb +126 -6
  108. data/lib/ronin/network/mixins/unix.rb +279 -0
  109. data/lib/ronin/network/network.rb +5 -5
  110. data/lib/ronin/network/pop3.rb +10 -10
  111. data/lib/ronin/network/proxy.rb +578 -0
  112. data/lib/ronin/network/smtp.rb +5 -5
  113. data/lib/ronin/network/smtp/email.rb +6 -6
  114. data/lib/ronin/network/smtp/smtp.rb +12 -13
  115. data/lib/ronin/network/ssl.rb +16 -17
  116. data/lib/ronin/network/tcp.rb +7 -310
  117. data/lib/ronin/network/tcp/proxy.rb +417 -0
  118. data/lib/ronin/network/tcp/tcp.rb +452 -0
  119. data/lib/ronin/network/telnet.rb +34 -28
  120. data/lib/ronin/network/udp.rb +7 -271
  121. data/lib/ronin/network/udp/proxy.rb +191 -0
  122. data/lib/ronin/network/udp/udp.rb +452 -0
  123. data/lib/ronin/network/unix.rb +286 -0
  124. data/lib/ronin/path.rb +35 -39
  125. data/lib/ronin/spec/ui/output.rb +6 -12
  126. data/lib/ronin/support.rb +6 -5
  127. data/lib/ronin/support/inflector.rb +8 -12
  128. data/lib/ronin/support/support.rb +7 -5
  129. data/lib/ronin/support/version.rb +6 -6
  130. data/lib/ronin/templates.rb +5 -5
  131. data/lib/ronin/templates/erb.rb +5 -5
  132. data/lib/ronin/templates/template.rb +5 -5
  133. data/lib/ronin/ui/output.rb +5 -5
  134. data/lib/ronin/ui/output/helpers.rb +42 -28
  135. data/lib/ronin/ui/output/output.rb +17 -21
  136. data/lib/ronin/ui/output/terminal.rb +5 -5
  137. data/lib/ronin/ui/output/terminal/color.rb +15 -9
  138. data/lib/ronin/ui/output/terminal/raw.rb +5 -5
  139. data/lib/ronin/ui/shell.rb +8 -11
  140. data/lib/ronin/wordlist.rb +110 -30
  141. data/ronin-support.gemspec +39 -109
  142. data/spec/binary/hexdump/helpers/hexdumps.rb +13 -0
  143. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/ascii.bin +0 -0
  144. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_decimal_shorts.txt +0 -0
  145. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_hex_bytes.txt +0 -0
  146. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_hex_shorts.txt +0 -0
  147. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_octal_bytes.txt +0 -0
  148. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_octal_shorts.txt +0 -0
  149. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_repeated.txt +0 -0
  150. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_bytes.txt +0 -0
  151. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_ints.txt +0 -0
  152. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_quads.txt +0 -0
  153. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_shorts.txt +0 -0
  154. data/spec/binary/hexdump/helpers/hexdumps/od_doubles.txt +17 -0
  155. data/spec/binary/hexdump/helpers/hexdumps/od_floats.txt +17 -0
  156. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_bytes.txt +0 -0
  157. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_ints.txt +0 -0
  158. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_quads.txt +0 -0
  159. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_shorts.txt +0 -0
  160. data/spec/binary/hexdump/helpers/hexdumps/od_named_chars.txt +17 -0
  161. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_bytes.txt +0 -0
  162. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_ints.txt +0 -0
  163. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_quads.txt +0 -0
  164. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_shorts.txt +0 -0
  165. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_repeated.txt +0 -0
  166. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/repeated.bin +0 -0
  167. data/spec/binary/hexdump/parser_spec.rb +302 -0
  168. data/spec/binary/struct_spec.rb +496 -0
  169. data/spec/binary/template_spec.rb +416 -0
  170. data/spec/extensions/enumerable_spec.rb +4 -4
  171. data/spec/extensions/file_spec.rb +12 -14
  172. data/spec/extensions/ip_addr_spec.rb +76 -50
  173. data/spec/extensions/kernel_spec.rb +7 -7
  174. data/spec/extensions/regexp_spec.rb +119 -59
  175. data/spec/extensions/resolv_spec.rb +2 -2
  176. data/spec/extensions/string_spec.rb +31 -30
  177. data/spec/formatting/binary/array_spec.rb +26 -0
  178. data/spec/formatting/binary/base64_spec.rb +50 -0
  179. data/spec/formatting/binary/float_spec.rb +36 -0
  180. data/spec/formatting/binary/integer_spec.rb +76 -50
  181. data/spec/formatting/binary/string_spec.rb +91 -198
  182. data/spec/formatting/digest/string_spec.rb +5 -5
  183. data/spec/formatting/html/integer_spec.rb +6 -6
  184. data/spec/formatting/html/string_spec.rb +10 -10
  185. data/spec/formatting/http/integer_spec.rb +3 -3
  186. data/spec/formatting/http/string_spec.rb +5 -5
  187. data/spec/formatting/sql/string_spec.rb +21 -19
  188. data/spec/formatting/text/array_spec.rb +15 -15
  189. data/spec/formatting/text/string_spec.rb +58 -28
  190. data/spec/fuzzing/extensions/string_spec.rb +87 -0
  191. data/spec/fuzzing/fuzzer_spec.rb +109 -0
  192. data/spec/fuzzing/fuzzing_spec.rb +24 -0
  193. data/spec/fuzzing/mutator_spec.rb +112 -0
  194. data/spec/fuzzing/repeater_spec.rb +57 -0
  195. data/spec/fuzzing/template_spec.rb +54 -0
  196. data/spec/mixin_spec.rb +10 -12
  197. data/spec/network/dns_spec.rb +89 -23
  198. data/spec/network/ftp_spec.rb +81 -0
  199. data/spec/network/http/http_spec.rb +237 -144
  200. data/spec/network/http/proxy_spec.rb +37 -37
  201. data/spec/network/network_spec.rb +2 -2
  202. data/spec/network/proxy_spec.rb +121 -0
  203. data/spec/network/shared/unix_server.rb +31 -0
  204. data/spec/network/smtp/email_spec.rb +14 -14
  205. data/spec/network/ssl_spec.rb +53 -3
  206. data/spec/network/tcp/proxy_spec.rb +118 -0
  207. data/spec/network/tcp/tcp_spec.rb +316 -0
  208. data/spec/network/telnet_spec.rb +67 -0
  209. data/spec/network/udp/udp_spec.rb +298 -0
  210. data/spec/network/unix_spec.rb +182 -0
  211. data/spec/path_spec.rb +43 -18
  212. data/spec/spec_helper.rb +2 -3
  213. data/spec/support/inflector_spec.rb +4 -4
  214. data/spec/support_spec.rb +1 -1
  215. data/spec/templates/erb_spec.rb +3 -3
  216. data/spec/templates/template_spec.rb +10 -10
  217. data/spec/ui/shell_spec.rb +15 -15
  218. data/spec/wordlist_spec.rb +80 -19
  219. metadata +176 -121
  220. data/.gemtest +0 -0
  221. data/spec/formatting/binary/helpers/hexdumps.rb +0 -16
  222. data/spec/fuzzing/string_spec.rb +0 -158
  223. data/spec/network/tcp_spec.rb +0 -247
  224. data/spec/network/udp_spec.rb +0 -248
@@ -0,0 +1,452 @@
1
+ #
2
+ # Copyright (c) 2006-2021 Hal Brodigan (postmodern.mod3 at gmail.com)
3
+ #
4
+ # This file is part of ronin-support.
5
+ #
6
+ # ronin-support is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # ronin-support is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with ronin-support. If not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ require 'socket'
21
+ require 'timeout'
22
+
23
+ module Ronin
24
+ module Network
25
+ #
26
+ # Provides helper methods for using the UDP protocol.
27
+ #
28
+ module UDP
29
+ #
30
+ # Tests whether a remote UDP port is open.
31
+ #
32
+ # @param [String] host
33
+ # The host to connect to.
34
+ #
35
+ # @param [Integer] port
36
+ # The port to connect to.
37
+ #
38
+ # @param [String] local_host (nil)
39
+ # The local host to bind to.
40
+ #
41
+ # @param [Integer] local_port (nil)
42
+ # The local port to bind to.
43
+ #
44
+ # @param [Integer] timeout (5)
45
+ # The maximum time to attempt connecting.
46
+ #
47
+ # @return [Boolean, nil]
48
+ # Specifies whether the remote UDP port is open.
49
+ # If no data or ICMP error were received, `nil` will be returned.
50
+ #
51
+ # @example
52
+ # udp_open?('4.2.2.1',53)
53
+ # # => true
54
+ #
55
+ # @example Using a timeout:
56
+ # udp_open?('example.com',1111,nil,nil,5)
57
+ # # => nil
58
+ #
59
+ # @api public
60
+ #
61
+ # @since 0.5.0
62
+ #
63
+ def udp_open?(host,port,local_host=nil,local_port=nil,timeout=nil)
64
+ timeout ||= 5
65
+
66
+ begin
67
+ Timeout.timeout(timeout) do
68
+ udp_session(host,port,local_host,local_port) do |socket|
69
+ # send an empty UDP packet, just like nmap
70
+ socket.syswrite('')
71
+
72
+ # send an empty UDP packet again, to elicit an Errno::ECONNREFUSED
73
+ socket.syswrite('')
74
+ end
75
+ end
76
+
77
+ return true
78
+ rescue Timeout::Error
79
+ return nil
80
+ rescue SocketError, SystemCallError
81
+ return false
82
+ end
83
+ end
84
+
85
+ #
86
+ # Creates a new UDPSocket object connected to a given host and port.
87
+ #
88
+ # @param [String] host
89
+ # The host to connect to.
90
+ #
91
+ # @param [Integer] port
92
+ # The port to connect to.
93
+ #
94
+ # @param [String] local_host (nil)
95
+ # The local host to bind to.
96
+ #
97
+ # @param [Integer] local_port (nil)
98
+ # The local port to bind to.
99
+ #
100
+ # @yield [socket]
101
+ # If a block is given, it will be passed the newly created socket.
102
+ #
103
+ # @yieldparam [UDPsocket] socket
104
+ # The newly created UDPSocket object.
105
+ #
106
+ # @return [UDPSocket]
107
+ # The newly created UDPSocket object.
108
+ #
109
+ # @example
110
+ # udp_connect('www.hackety.org',80)
111
+ # # => UDPSocket
112
+ #
113
+ # @example
114
+ # udp_connect('www.wired.com',80) do |socket|
115
+ # puts socket.readlines
116
+ # end
117
+ #
118
+ # @see https://rubydoc.info/stdlib/socket/UDPSocket
119
+ #
120
+ # @api public
121
+ #
122
+ def udp_connect(host,port,local_host=nil,local_port=nil)
123
+ host = host.to_s
124
+ port = port.to_i
125
+
126
+ socket = UDPSocket.new
127
+
128
+ if local_host || local_port
129
+ local_host = local_host.to_s
130
+ local_port = local_port.to_i
131
+
132
+ socket.bind(local_host,local_port)
133
+ end
134
+
135
+ socket.connect(host,port)
136
+
137
+ yield socket if block_given?
138
+ return socket
139
+ end
140
+
141
+ #
142
+ # Creates a new UDPSocket object, connected to a given host and port.
143
+ # The given data will then be written to the newly created UDPSocket.
144
+ #
145
+ # @param [String] data
146
+ # The data to send through the connection.
147
+ #
148
+ # @param [String] host
149
+ # The host to connect to.
150
+ #
151
+ # @param [Integer] port
152
+ # The port to connect to.
153
+ #
154
+ # @param [String] local_host (nil)
155
+ # The local host to bind to.
156
+ #
157
+ # @param [Integer] local_port (nil)
158
+ # The local port to bind to.
159
+ #
160
+ # @yield [socket]
161
+ # If a block is given, it will be passed the newly created socket.
162
+ #
163
+ # @yieldparam [UDPsocket] socket
164
+ # The newly created UDPSocket object.
165
+ #
166
+ # @return [UDPSocket]
167
+ # The newly created UDPSocket object.
168
+ #
169
+ # @api public
170
+ #
171
+ def udp_connect_and_send(data,host,port,local_host=nil,local_port=nil)
172
+ socket = udp_connect(host,port,local_host,local_port)
173
+ socket.write(data)
174
+
175
+ yield socket if block_given?
176
+ return socket
177
+ end
178
+
179
+ #
180
+ # Creates a new temporary UDPSocket object, connected to the given host
181
+ # and port.
182
+ #
183
+ # @param [String] host
184
+ # The host to connect to.
185
+ #
186
+ # @param [Integer] port
187
+ # The port to connect to.
188
+ #
189
+ # @param [String] local_host (nil)
190
+ # The local host to bind to.
191
+ #
192
+ # @param [Integer] local_port (nil)
193
+ # The local port to bind to.
194
+ #
195
+ # @yield [socket]
196
+ # If a block is given, it will be passed the newly created socket.
197
+ # After the block has returned, the socket will then be closed.
198
+ #
199
+ # @yieldparam [UDPsocket] socket
200
+ # The newly created UDPSocket object.
201
+ #
202
+ # @return [nil]
203
+ #
204
+ # @api public
205
+ #
206
+ def udp_session(host,port,local_host=nil,local_port=nil)
207
+ socket = udp_connect(host,port,local_host,local_port)
208
+
209
+ yield socket if block_given?
210
+ socket.close
211
+ return nil
212
+ end
213
+
214
+ #
215
+ # Connects to a specified host and port, sends the given data and then
216
+ # closes the connection.
217
+ #
218
+ # @param [String] data
219
+ # The data to send through the connection.
220
+ #
221
+ # @param [String] host
222
+ # The host to connect to.
223
+ #
224
+ # @param [Integer] port
225
+ # The port to connect to.
226
+ #
227
+ # @param [String] local_host (nil)
228
+ # The local host to bind to.
229
+ #
230
+ # @param [Integer] local_port (nil)
231
+ # The local port to bind to.
232
+ #
233
+ # @return [true]
234
+ # The data was successfully sent.
235
+ #
236
+ # @example
237
+ # buffer = "GET /" + ('A' * 4096) + "\n\r"
238
+ # udp_send(buffer,'victim.com',80)
239
+ # # => true
240
+ #
241
+ # @api public
242
+ #
243
+ # @since 0.4.0
244
+ #
245
+ def udp_send(data,host,port,local_host=nil,local_port=nil)
246
+ udp_session(host,port,local_host,local_port) do |socket|
247
+ socket.write(data)
248
+ end
249
+
250
+ return true
251
+ end
252
+
253
+ #
254
+ # Reads the banner from the service running on the given host and port.
255
+ #
256
+ # @param [String] host
257
+ # The host to connect to.
258
+ #
259
+ # @param [Integer] port
260
+ # The port to connect to.
261
+ #
262
+ # @param [String] local_host (nil)
263
+ # The local host to bind to.
264
+ #
265
+ # @param [Integer] local_port (nil)
266
+ # The local port to bind to.
267
+ #
268
+ # @yield [banner]
269
+ # If a block is given, it will be passed the grabbed banner.
270
+ #
271
+ # @yieldparam [String] banner
272
+ # The grabbed banner.
273
+ #
274
+ # @return [String]
275
+ # The grabbed banner.
276
+ #
277
+ # @api public
278
+ #
279
+ def udp_banner(host,port,local_host=nil,local_port=nil)
280
+ banner = nil
281
+
282
+ udp_session(host,port,local_host,local_port) do |socket|
283
+ banner = socket.readline
284
+ end
285
+
286
+ yield banner if block_given?
287
+ return banner
288
+ end
289
+
290
+ #
291
+ # Creates a new UDPServer listening on a given host and port.
292
+ #
293
+ # @param [Integer] port (nil)
294
+ # The local port to listen on.
295
+ #
296
+ # @param [String] host (nil)
297
+ # The host to bind to.
298
+ #
299
+ # @return [UDPServer]
300
+ # The new UDP server.
301
+ #
302
+ # @example
303
+ # udp_server(1337)
304
+ #
305
+ # @see https://rubydoc.info/stdlib/socket/UDPSocket
306
+ #
307
+ # @api public
308
+ #
309
+ def udp_server(port=nil,host=nil)
310
+ port = port.to_i
311
+ host = host.to_s
312
+
313
+ server = UDPSocket.new
314
+ server.bind(host,port)
315
+
316
+ yield server if block_given?
317
+ return server
318
+ end
319
+
320
+ #
321
+ # Creates a new temporary UDPServer listening on a given host and port.
322
+ #
323
+ # @param [Integer] port (nil)
324
+ # The local port to bind to.
325
+ #
326
+ # @param [String] host (nil)
327
+ # The host to bind to.
328
+ #
329
+ # @yield [server]
330
+ # The block which will be called after the server has been created.
331
+ # After the block has finished, the server will be closed.
332
+ #
333
+ # @yieldparam [UDPServer] server
334
+ # The newly created UDP server.
335
+ #
336
+ # @return [nil]
337
+ #
338
+ # @example
339
+ # udp_server_session(1337) do |server|
340
+ # data, sender = server.recvfrom(1024)
341
+ # end
342
+ #
343
+ # @api public
344
+ #
345
+ def udp_server_session(port=nil,host=nil,&block)
346
+ server = udp_server(port,host,&block)
347
+ server.close()
348
+ return nil
349
+ end
350
+
351
+ #
352
+ # Creates a new UDPServer listening on a given host and port,
353
+ # accepting messages from clients in a loop.
354
+ #
355
+ # @param [Integer] port (nil)
356
+ # The port the UDPServer will listen on.
357
+ #
358
+ # @param [String] host (nil)
359
+ # The optional host the UDPServer will bind to.
360
+ #
361
+ # @yield [server, (client_host, client_port), mesg]
362
+ # The given block will be passed the client host/port and the received
363
+ # message.
364
+ #
365
+ # @yieldparam [UDPServer] server
366
+ # The UDPServer.
367
+ #
368
+ # @yieldparam [String] client_host
369
+ # The source host of the message.
370
+ #
371
+ # @yieldparam [Integer] client_port
372
+ # The source port of the message.
373
+ #
374
+ # @yieldparam [String] mesg
375
+ # The received message.
376
+ #
377
+ # @return [nil]
378
+ #
379
+ # @example
380
+ # udp_server_loop(1337) do |server,(host,port),mesg|
381
+ # server.send('hello',host,port)
382
+ # end
383
+ #
384
+ # @api public
385
+ #
386
+ # @since 0.5.0
387
+ #
388
+ def udp_server_loop(port=nil,host=nil)
389
+ udp_server_session(port,host) do |server|
390
+ loop do
391
+ mesg, addrinfo = server.recvfrom(4096)
392
+
393
+ yield server, [addrinfo[3], addrinfo[1]], mesg if block_given?
394
+ end
395
+ end
396
+ end
397
+
398
+ #
399
+ # Creates a new UDPServer listening on a given host and port,
400
+ # accepts only one message from a client.
401
+ #
402
+ # @param [Integer] port (nil)
403
+ # The port the UDPServer will listen on.
404
+ #
405
+ # @param [String] host (nil)
406
+ # The optional host the UDPServer will bind to.
407
+ #
408
+ # @yield [server, (client_host, client_port), mesg]
409
+ # The given block will be passed the client host/port and the received
410
+ # message.
411
+ #
412
+ # @yieldparam [UDPServer] server
413
+ # The UDPServer.
414
+ #
415
+ # @yieldparam [String] client_host
416
+ # The source host of the message.
417
+ #
418
+ # @yieldparam [Integer] client_port
419
+ # The source port of the message.
420
+ #
421
+ # @yieldparam [String] mesg
422
+ # The received message.
423
+ #
424
+ # @return [nil]
425
+ #
426
+ # @example
427
+ # udp_recv(1337) do |server,(host,port),mesg|
428
+ # server.send('hello',host,port)
429
+ # end
430
+ #
431
+ # @api public
432
+ #
433
+ # @since 0.5.0
434
+ #
435
+ def udp_recv(port=nil,host=nil)
436
+ udp_server_session(port,host) do |server|
437
+ mesg, addrinfo = server.recvfrom(4096)
438
+
439
+ yield server, [addrinfo[3], addrinfo[1]], mesg if block_given?
440
+ end
441
+ end
442
+
443
+ #
444
+ # @deprecated
445
+ # Deprecated as of 0.5.0. Use {#udp_recv} instead.
446
+ #
447
+ def udp_single_server(port=nil,host=nil)
448
+ udp_recv(port,host)
449
+ end
450
+ end
451
+ end
452
+ end
@@ -0,0 +1,286 @@
1
+ #
2
+ # Copyright (c) 2006-2021 Hal Brodigan (postmodern.mod3 at gmail.com)
3
+ #
4
+ # This file is part of ronin-support.
5
+ #
6
+ # ronin-support is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # ronin-support is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with ronin-support. If not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ require 'socket'
21
+ require 'timeout'
22
+
23
+ module Ronin
24
+ module Network
25
+ #
26
+ # Provides helper methods for communicating with UNIX sockets.
27
+ #
28
+ # @since 0.5.0
29
+ #
30
+ module UNIX
31
+ #
32
+ # Tests whether a UNIX socket is open.
33
+ #
34
+ # @param [String] path
35
+ # The path to the socket.
36
+ #
37
+ # @param [Integer] timeout (5)
38
+ # The maximum time to attempt connecting.
39
+ #
40
+ # @return [Boolean, nil]
41
+ # Specifies whether the UNIX socket is open.
42
+ # If the connection was not accepted, `nil` will be returned.
43
+ #
44
+ # @api public
45
+ #
46
+ # @since 0.5.0
47
+ #
48
+ def unix_open?(path,timeout=nil)
49
+ timeout ||= 5
50
+
51
+ begin
52
+ Timeout.timeout(timeout) { unix_session(path) }
53
+ return true
54
+ rescue Timeout::Error
55
+ return nil
56
+ rescue SocketError, SystemCallError
57
+ return false
58
+ end
59
+ end
60
+
61
+ #
62
+ # Connects to a UNIX socket.
63
+ #
64
+ # @param [String] path
65
+ # The path to the UNIX socket.
66
+ #
67
+ # @yield [socket]
68
+ # If a block is given, it will be passed an UNIX socket object.
69
+ #
70
+ # @yieldparam [UNIXSocket] socket
71
+ # The UNIX socket.
72
+ #
73
+ # @return [UNIXSocket]
74
+ # The UNIX socket.
75
+ #
76
+ # @example
77
+ # unix_connect('/tmp/haproxy.stats.socket')
78
+ #
79
+ # @see https://rubydoc.info/stdlib/socket/UNIXSocket
80
+ #
81
+ # @api public
82
+ #
83
+ def unix_connect(path)
84
+ socket = UNIXSocket.new(path)
85
+
86
+ yield socket if block_given?
87
+ return socket
88
+ end
89
+
90
+ #
91
+ # Connects to a UNIX Socket and sends the given data.
92
+ #
93
+ # @param [String] data
94
+ # The data to send to the socket.
95
+ #
96
+ # @param [String] path
97
+ # The path to the socket.
98
+ #
99
+ # @yield [socket]
100
+ # If a block is given, it will be passed the newly created socket.
101
+ #
102
+ # @yieldparam [UNIXSocket] socket
103
+ # The newly created UNIXSocket object.
104
+ #
105
+ # @return [UNIXSocket]
106
+ # The newly created UNIXSocket object.
107
+ #
108
+ # @api public
109
+ #
110
+ def unix_connect_and_send(data,path)
111
+ socket = unix_connect(path)
112
+ socket.write(data)
113
+
114
+ yield socket if block_given?
115
+ return socket
116
+ end
117
+
118
+ #
119
+ # Temporarily connects to a UNIX socket.
120
+ #
121
+ # @param [String] path
122
+ # The path to the UNIX socket.
123
+ #
124
+ # @yield [socket]
125
+ # If a block is given, it will be passed an UNIX socket object.
126
+ #
127
+ # @yieldparam [UNIXSocket] socket
128
+ # The UNIX socket.
129
+ #
130
+ # @example
131
+ # unix_session('/tmp/haproxy.stats.socket') do |socket|
132
+ # # ...
133
+ # end
134
+ #
135
+ # @api public
136
+ #
137
+ def unix_session(path)
138
+ socket = unix_connect(path)
139
+
140
+ yield socket if block_given?
141
+ socket.close
142
+ return nil
143
+ end
144
+
145
+ #
146
+ # Connects to a UNIX socket, sends the given data and then closes the
147
+ # socket.
148
+ #
149
+ # @param [String] data
150
+ # The data to send to the UNIX socket.
151
+ #
152
+ # @param [String] path
153
+ # The UNIX socket to connect to.
154
+ #
155
+ # @return [true]
156
+ # The data was successfully sent.
157
+ #
158
+ # @example
159
+ # buffer = "GET /" + ('A' * 4096) + "\n\r"
160
+ # unix_send(buffer,'/tmp/thin.socket')
161
+ # # => true
162
+ #
163
+ # @api public
164
+ #
165
+ def unix_send(data,path)
166
+ unix_session(path) do |socket|
167
+ socket.write(data)
168
+ end
169
+
170
+ return true
171
+ end
172
+
173
+ #
174
+ # Opens a UNIX socket.
175
+ #
176
+ # @param [String] path
177
+ # The path for the new UNIX socket.
178
+ #
179
+ # @yield [server]
180
+ # If a block is given, it will be passed an UNIX socket object.
181
+ #
182
+ # @yieldparam [UNIXServer] server
183
+ # The new UNIX socket.
184
+ #
185
+ # @return [UNIXServer]
186
+ # The new UNIX socket.
187
+ #
188
+ # @example
189
+ # unix_server('/tmp/test.socket')
190
+ #
191
+ # @see https://rubydoc.info/stdlib/socket/UNIXServer
192
+ #
193
+ # @api public
194
+ #
195
+ def unix_server(path)
196
+ socket = UNIXServer.new(path)
197
+
198
+ yield socket if block_given?
199
+ return socket
200
+ end
201
+
202
+ #
203
+ # Temporarily opens a UNIX socket.
204
+ #
205
+ # @param [String] path
206
+ # The path for the new UNIX socket.
207
+ #
208
+ # @yield [server]
209
+ # If a block is given, it will be passed an UNIX socket object.
210
+ #
211
+ # @yieldparam [UNIXServer] server
212
+ # The new UNIX socket.
213
+ #
214
+ # @example
215
+ # unix_server_session('/tmp/test.socket') do |server|
216
+ # # ...
217
+ # end
218
+ #
219
+ # @api public
220
+ #
221
+ def unix_server_session(path,&block)
222
+ socket = unix_server(path,&block)
223
+ socket.close
224
+ return nil
225
+ end
226
+
227
+ #
228
+ # Opens a UNIX socket, accepts connections in a loop.
229
+ #
230
+ # @param [String] path
231
+ # The path for the new UNIX socket.
232
+ #
233
+ # @yield [client]
234
+ # If a block is given, it will be passed each accepted connection.
235
+ #
236
+ # @yieldparam [UNIXSocket] client
237
+ # An accepted connection to UNIX socket.
238
+ #
239
+ # @example
240
+ # unix_server_loop('/tmp/test.socket') do |client|
241
+ # # ...
242
+ # end
243
+ #
244
+ # @api public
245
+ #
246
+ def unix_server_loop(path)
247
+ unix_server_session(path) do |server|
248
+ loop do
249
+ client = server.accept
250
+
251
+ yield client if block_given?
252
+ client.close
253
+ end
254
+ end
255
+ end
256
+
257
+ #
258
+ # Opens a UNIX socket, accepts a connection, then closes the socket.
259
+ #
260
+ # @param [String] path
261
+ # The path for the new UNIX socket.
262
+ #
263
+ # @yield [client]
264
+ # If a block is given, it will be passed the accepted connection.
265
+ #
266
+ # @yieldparam [UNIXSocket] client
267
+ # The accepted connection to UNIX socket.
268
+ #
269
+ # @example
270
+ # unix_accept('/tmp/test.socket') do |client|
271
+ # # ...
272
+ # end
273
+ #
274
+ # @api public
275
+ #
276
+ def unix_accept(path)
277
+ unix_server_session(path) do |server|
278
+ client = server.accept
279
+
280
+ yield client if block_given?
281
+ client.close
282
+ end
283
+ end
284
+ end
285
+ end
286
+ end