ronin-post_ex 0.1.0.beta1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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