ronin-post_ex 0.1.0.beta1 → 0.1.0

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.
@@ -1,482 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/post_ex/sessions/shell_session'
3
-
4
- require 'socket'
5
-
6
- describe Ronin::PostEx::Sessions::ShellSession do
7
- let(:pipe) { UNIXSocket.pair }
8
- let(:io) { pipe[0] }
9
- let(:shell) { pipe[1] }
10
-
11
- subject { described_class.new(io) }
12
-
13
- describe "#initialize" do
14
- it "must set #io" do
15
- expect(subject.io).to be(io)
16
- end
17
- end
18
-
19
- describe "#shell_gets" do
20
- it "must read a line of text from #io" do
21
- thread = Thread.new do
22
- sleep 0.1
23
- shell.write("foo bar\n")
24
- end
25
-
26
- expect(subject.shell_gets).to eq("foo bar\n")
27
- end
28
- end
29
-
30
- describe "#shell_puts" do
31
- let(:line) { "foo bar" }
32
-
33
- it "must write a line of text to #io" do
34
- subject.shell_puts(line)
35
-
36
- expect(shell.gets).to eq("#{line}\n")
37
- end
38
- end
39
-
40
- describe "#shell_exec" do
41
- let(:command) { 'ls' }
42
- let(:output) do
43
- [
44
- "API_SPEC.md",
45
- "ChangeLog.md",
46
- "COPYING.txt",
47
- "Gemfile",
48
- "Gemfile.lock",
49
- "gemspec.yml",
50
- "lib",
51
- "Rakefile",
52
- "README.md",
53
- "ronin-post_ex.gemspec",
54
- "spec",
55
- "vendor"
56
- ].map { |line| "#{line}\n" }.join
57
- end
58
-
59
- it "must print a beginning deliminator, pipe the command into base64, and print an ending deliminator" do
60
- thread = Thread.new do
61
- sleep 0.1
62
- subject.shell_exec(command)
63
- end
64
-
65
- expect(shell.gets).to eq("echo #{described_class::DELIMINATOR}; #{command} 2>/dev/null | base64; echo #{described_class::DELIMINATOR}\n")
66
- shell.puts(described_class::DELIMINATOR)
67
- shell.write(Base64.encode64(output))
68
- shell.puts(described_class::DELIMINATOR)
69
- end
70
-
71
- it "must return the output of the command" do
72
- thread = Thread.new do
73
- sleep 0.1
74
-
75
- shell.gets
76
- shell.puts(described_class::DELIMINATOR)
77
- shell.write(Base64.encode64(output))
78
- shell.puts(described_class::DELIMINATOR)
79
- end
80
-
81
- expect(subject.shell_exec(command)).to eq(output)
82
- end
83
- end
84
-
85
- describe "#sys_time" do
86
- let(:timestamp) { 1668692783 }
87
- let(:output) { "#{timestamp}\n" }
88
-
89
- it "must run the 'date +%s' and parse the output as an Integer" do
90
- expect(subject).to receive(:shell_exec).with('date +%s').and_return(output)
91
-
92
- expect(subject.sys_time).to eq(timestamp)
93
- end
94
- end
95
-
96
- describe "#sys_hostname" do
97
- let(:hostname) { 'computer' }
98
- let(:output) { "#{hostname}\n" }
99
-
100
- it "must run the 'echo $HOSTNAME' and parse the output as an Integer" do
101
- expect(subject).to receive(:shell_exec).with('echo $HOSTNAME').and_return(output)
102
-
103
- expect(subject.sys_hostname).to eq(hostname)
104
- end
105
- end
106
-
107
- describe "#fs_getcwd" do
108
- let(:pwd) { '/current/directory' }
109
- let(:output) { "#{pwd}\n" }
110
-
111
- it "must run the 'pwd' command and return the path" do
112
- expect(subject).to receive(:shell_exec).with('pwd').and_return(output)
113
-
114
- expect(subject.fs_getcwd).to eq(pwd)
115
- end
116
- end
117
-
118
- describe "#fs_chdir" do
119
- let(:new_dir) { '/path/to/directory' }
120
- let(:output) { "\n" }
121
-
122
- it "must run the 'cd <path> 2>/dev/null' command" do
123
- expect(subject).to receive(:shell_puts).with("cd #{new_dir} 2>/dev/null")
124
-
125
- subject.fs_chdir(new_dir)
126
- end
127
- end
128
-
129
- describe "#fs_readfile" do
130
- let(:path) { '/path/to/file' }
131
- let(:contents) { "foo bar\nbaz qux\n" }
132
-
133
- it "must run the 'cat <path>' command and return the file contents" do
134
- expect(subject).to receive(:command_exec).with('cat',path).and_return(contents)
135
-
136
- expect(subject.fs_readfile(path)).to eq(contents)
137
- end
138
- end
139
-
140
- describe "#fs_readlink" do
141
- let(:path) { '/path/to/link' }
142
- let(:dest_path) { 'path/to/file' }
143
- let(:output) { "#{dest_path}\n" }
144
-
145
- it "must run the 'readlink -f <path>' command and return the link's path" do
146
- expect(subject).to receive(:command_exec).with('readlink','-f',path).and_return(output)
147
-
148
- expect(subject.fs_readlink(path)).to eq(dest_path)
149
- end
150
- end
151
-
152
- describe "#fs_readdir" do
153
- let(:path) { '/path/to/dir' }
154
- let(:entries) do
155
- %w[
156
- API_SPEC.md
157
- ChangeLog.md
158
- COPYING.txt
159
- examples
160
- Gemfile
161
- Gemfile.lock
162
- gemspec.yml
163
- lib
164
- Rakefile
165
- README.md
166
- ronin-post_ex.gemspec
167
- spec
168
- vendor
169
- ]
170
- end
171
- let(:output) { "#{entries.join("\n")}\n" }
172
-
173
- it "must run the 'ls <path>' command and return the directories entries" do
174
- expect(subject).to receive(:command_exec).with('ls',path).and_return(output)
175
-
176
- expect(subject.fs_readdir(path)).to eq(entries)
177
- end
178
- end
179
-
180
- describe "#fs_glob" do
181
- let(:pattern) { '*.md' }
182
- let(:entries) do
183
- %w[
184
- API_SPEC.md
185
- ChangeLog.md
186
- README.md
187
- ]
188
- end
189
- let(:output) { "#{entries.join("\n")}\n" }
190
-
191
- it "must run the 'ls <pattern>' command and return the matching paths" do
192
- expect(subject).to receive(:shell_exec).with("ls #{pattern}").and_return(output)
193
-
194
- expect(subject.fs_glob(pattern)).to eq(entries)
195
- end
196
- end
197
-
198
- describe "#fs_mktemp" do
199
- let(:basename) { 'ronin-XXXX.txt' }
200
- let(:tempfile) { 'ronin-LtFK.txt' }
201
- let(:output) { "#{tempfile}\n" }
202
-
203
- it "must run the 'mktemp <basename>' command and return the tempfile name" do
204
- expect(subject).to receive(:command_exec).with('mktemp',basename).and_return(output)
205
-
206
- expect(subject.fs_mktemp(basename)).to eq(tempfile)
207
- end
208
- end
209
-
210
- describe "#fs_mkdir" do
211
- let(:path) { '/path/to/new_dir' }
212
-
213
- it "must run the 'mkdir <pattern>' command" do
214
- expect(subject).to receive(:command_exec).with('mkdir',path)
215
-
216
- subject.fs_mkdir(path)
217
- end
218
- end
219
-
220
- describe "#fs_copy" do
221
- let(:src) { '/path/to/src' }
222
- let(:dest) { '/path/to/dest' }
223
-
224
- it "must run the 'cp -r <src> <dest>' command" do
225
- expect(subject).to receive(:command_exec).with('cp','-r',src,dest)
226
-
227
- subject.fs_copy(src,dest)
228
- end
229
- end
230
-
231
- describe "#fs_unlink" do
232
- let(:path) { '/path/to/file' }
233
-
234
- it "must run the 'rm <path>' command" do
235
- expect(subject).to receive(:command_exec).with('rm',path)
236
-
237
- subject.fs_unlink(path)
238
- end
239
- end
240
-
241
- describe "#fs_rmdir" do
242
- let(:path) { '/path/to/dir' }
243
-
244
- it "must run the 'rmdir <path>' command" do
245
- expect(subject).to receive(:command_exec).with('rmdir',path)
246
-
247
- subject.fs_rmdir(path)
248
- end
249
- end
250
-
251
- describe "#fs_move" do
252
- let(:src) { '/path/to/src' }
253
- let(:dest) { '/path/to/dest' }
254
-
255
- it "must run the 'mv <src> <dest>' command" do
256
- expect(subject).to receive(:command_exec).with('mv',src,dest)
257
-
258
- subject.fs_move(src,dest)
259
- end
260
- end
261
-
262
- describe "#fs_link" do
263
- let(:src) { '/path/to/src' }
264
- let(:dest) { '/path/to/dest' }
265
-
266
- it "must run the 'ln -s <src> <dest>' command" do
267
- expect(subject).to receive(:command_exec).with('ln','-s',src,dest)
268
-
269
- subject.fs_link(src,dest)
270
- end
271
- end
272
-
273
- describe "#fs_chgrp" do
274
- let(:group) { 'wheel' }
275
- let(:path) { '/path/to/file' }
276
-
277
- it "must run the 'chgrp <group> <path>' command" do
278
- expect(subject).to receive(:command_exec).with('chgrp',group,path)
279
-
280
- subject.fs_chgrp(group,path)
281
- end
282
- end
283
-
284
- describe "#fs_chown" do
285
- let(:user) { 'root' }
286
- let(:path) { '/path/to/file' }
287
-
288
- it "must run the 'chown <user> <path>' command" do
289
- expect(subject).to receive(:command_exec).with('chown',user,path)
290
-
291
- subject.fs_chown(user,path)
292
- end
293
- end
294
-
295
- describe "#fs_chmod" do
296
- let(:mode) { 0777 }
297
- let(:umask) { "%.4o" % mode }
298
- let(:path) { '/path/to/file' }
299
-
300
- it "must run the 'chown <user> <path>' command" do
301
- expect(subject).to receive(:command_exec).with('chmod',umask,path)
302
-
303
- subject.fs_chmod(mode,path)
304
- end
305
- end
306
-
307
- describe "#fs_stat" do
308
- let(:path) { '/path/to/file' }
309
- let(:size) { 420 }
310
- let(:blocks) { 16 }
311
- let(:uid) { 1000 }
312
- let(:gid) { 1000 }
313
- let(:inode) { 12345 }
314
- let(:links) { 1 }
315
- let(:atime) { Time.at(1668608914) }
316
- let(:mtime) { Time.at(1668427627) }
317
- let(:ctime) { Time.at(1668427627) }
318
- let(:blocksize) { 1668427627 }
319
-
320
- let(:output) do
321
- "#{path} #{size} #{blocks} 81a4 #{uid} #{gid} fd01 #{inode} #{links} 0 0 #{atime.to_i} #{mtime.to_i} #{ctime.to_i} #{blocksize} 4096 unconfined_u:object_r:unlabeled_t:s0\n"
322
- end
323
-
324
- it "must run the 'stat -t <path>' command and return a Hash of parsed stat information" do
325
- expect(subject).to receive(:command_exec).with('stat','-t',path).and_return(output)
326
-
327
- expect(subject.fs_stat(path)).to eq(
328
- {
329
- path: path,
330
- size: size,
331
- blocks: blocks,
332
- uid: uid,
333
- gid: gid,
334
- inode: inode,
335
- links: links,
336
- atime: atime,
337
- mtime: mtime,
338
- ctime: ctime,
339
- blocksize: blocksize
340
- }
341
- )
342
- end
343
- end
344
-
345
- describe "#process_getpid" do
346
- let(:pid) { 1234 }
347
- let(:output) { "#{pid}\n" }
348
-
349
- it "must run the 'echo $$' command and return the parsed PID" do
350
- expect(subject).to receive(:shell_exec).with('echo $$').and_return(output)
351
-
352
- expect(subject.process_getpid).to eq(pid)
353
- end
354
- end
355
-
356
- describe "#process_getppid" do
357
- let(:ppid) { 1234 }
358
- let(:output) { "#{ppid}\n" }
359
-
360
- it "must run the 'echo $PPID' command and return the parsed PPID" do
361
- expect(subject).to receive(:shell_exec).with('echo $PPID').and_return(output)
362
-
363
- expect(subject.process_getppid).to eq(ppid)
364
- end
365
- end
366
-
367
- describe "#process_getuid" do
368
- let(:uid) { 1000 }
369
- let(:output) { "#{uid}\n" }
370
-
371
- it "must run the 'id -u' command and return the parsed UID" do
372
- expect(subject).to receive(:command_exec).with('id','-u').and_return(output)
373
-
374
- expect(subject.process_getuid).to eq(uid)
375
- end
376
- end
377
-
378
- describe "#process_getgid" do
379
- let(:gid) { 1000 }
380
- let(:output) { "#{gid}\n" }
381
-
382
- it "must run the 'id -g' command and return the parsed GID" do
383
- expect(subject).to receive(:command_exec).with('id','-g').and_return(output)
384
-
385
- expect(subject.process_getgid).to eq(gid)
386
- end
387
- end
388
-
389
- describe "#process_getgid" do
390
- let(:env) do
391
- {
392
- 'FOO' => 'foo',
393
- 'BAR' => 'bar'
394
- }
395
- end
396
- let(:output) do
397
- "#{env.keys[0]}=#{env.values[0]}\n#{env.keys[1]}=#{env.values[1]}\n"
398
- end
399
-
400
- it "must run the 'env' command and return the parsed env Hash" do
401
- expect(subject).to receive(:command_exec).with('env').and_return(output)
402
-
403
- expect(subject.process_environ).to eq(env)
404
- end
405
- end
406
-
407
- describe "#process_getenv" do
408
- let(:name) { 'FOO' }
409
- let(:value) { 'foo bar baz' }
410
- let(:output) { "#{value}\n" }
411
-
412
- it "must run the 'echo $<name>' command and return the parsed value" do
413
- expect(subject).to receive(:shell_exec).with("echo $#{name}").and_return(output)
414
-
415
- expect(subject.process_getenv(name)).to eq(value)
416
- end
417
- end
418
-
419
- describe "#process_setenv" do
420
- let(:name) { 'FOO' }
421
- let(:value) { 'foo bar baz' }
422
-
423
- it "must run the 'export <name>=<value>' command and return the parsed value" do
424
- expect(subject).to receive(:shell_puts).with("export #{name}=#{value}")
425
-
426
- subject.process_setenv(name,value)
427
- end
428
- end
429
-
430
- describe "#process_unsetenv" do
431
- let(:name) { 'FOO' }
432
-
433
- it "must run the 'unset <name>' command" do
434
- expect(subject).to receive(:shell_puts).with("unset #{name}")
435
-
436
- subject.process_unsetenv(name)
437
- end
438
- end
439
-
440
- describe "#process_kill" do
441
- let(:pid) { 1234 }
442
- let(:signal) { 'TERM' }
443
-
444
- it "must run the 'kill -s <signal> <pid>' command" do
445
- expect(subject).to receive(:command_exec).with('kill','-s',signal,pid)
446
-
447
- subject.process_kill(pid,signal)
448
- end
449
- end
450
-
451
- describe "#process_spawn" do
452
- let(:command_name) { 'cmd' }
453
- let(:arguments) { ['foo', 'bar baz'] }
454
-
455
- let(:pid) { 1234 }
456
- let(:output) { "#{pid}\n" }
457
-
458
- it "must run the command with arguments and return the parsed PID" do
459
- command = Shellwords.join([command_name, *arguments])
460
-
461
- expect(subject).to receive(:shell_exec).with("#{command} 2>&1 >/dev/null &; echo $!").and_return(output)
462
-
463
- expect(subject.process_spawn(command_name,*arguments)).to eq(pid)
464
- end
465
- end
466
-
467
- describe "#process_exit" do
468
- it "must run the 'exit' command" do
469
- expect(subject).to receive(:shell_puts).with('exit')
470
-
471
- subject.process_exit
472
- end
473
- end
474
-
475
- describe "#close" do
476
- it "must call #close on #io" do
477
- expect(io).to receive(:close)
478
-
479
- subject.close
480
- end
481
- end
482
- end
data/spec/spec_helper.rb DELETED
@@ -1,9 +0,0 @@
1
- require 'rspec'
2
- require 'simplecov'
3
- require 'ronin/post_ex/version'
4
-
5
- SimpleCov.start
6
-
7
- RSpec.configure do |c|
8
- c.include Ronin::PostEx
9
- end
data/spec/system_spec.rb DELETED
@@ -1,66 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/post_ex/system'
3
- require 'ronin/post_ex/sessions/session'
4
-
5
- describe Ronin::PostEx::System do
6
- let(:session) { Ronin::PostEx::Sessions::Session.new }
7
-
8
- subject { described_class.new(session) }
9
-
10
- describe "#initialize" do
11
- it "must set #session" do
12
- expect(subject.session).to be(session)
13
- end
14
-
15
- it "must initialize #fs" do
16
- expect(subject.fs).to be_kind_of(described_class::FS)
17
- end
18
-
19
- it "must initialize #process" do
20
- expect(subject.process).to be_kind_of(described_class::Process)
21
- end
22
-
23
- it "must initialize #shell" do
24
- expect(subject.shell).to be_kind_of(described_class::Shell)
25
- end
26
- end
27
-
28
- describe "#fs" do
29
- it "must return a System::FS object" do
30
- expect(subject.fs).to be_kind_of(described_class::FS)
31
- end
32
- end
33
-
34
- describe "#process" do
35
- it "must return a System::Process object" do
36
- expect(subject.process).to be_kind_of(described_class::Process)
37
- end
38
- end
39
-
40
- describe "#shell" do
41
- it "must return a System::Shell object" do
42
- expect(subject.shell).to be_kind_of(described_class::Shell)
43
- end
44
- end
45
-
46
- describe "#time" do
47
- let(:unix_timestamp) { 1642775495 }
48
- let(:time) { Time.at(unix_timestamp) }
49
-
50
- it "must call the 'sys_time' API function and return a Time object" do
51
- expect(session).to receive(:sys_time).and_return(unix_timestamp)
52
-
53
- expect(subject.time).to eq(time)
54
- end
55
- end
56
-
57
- describe "#hostname" do
58
- let(:hostname) { 'computer' }
59
-
60
- it "must call the 'sys_hostname' API function and return the hostname" do
61
- expect(session).to receive(:sys_hostname).and_return(hostname)
62
-
63
- expect(subject.hostname).to eq(hostname)
64
- end
65
- end
66
- end