ronin-post_ex 0.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.document +6 -0
  3. data/.github/workflows/ruby.yml +31 -0
  4. data/.gitignore +13 -0
  5. data/.rspec +1 -0
  6. data/.ruby-version +1 -0
  7. data/.yardopts +1 -0
  8. data/API_SPEC.md +235 -0
  9. data/COPYING.txt +165 -0
  10. data/ChangeLog.md +23 -0
  11. data/Gemfile +36 -0
  12. data/README.md +245 -0
  13. data/Rakefile +34 -0
  14. data/examples/bind_shell.rb +19 -0
  15. data/gemspec.yml +25 -0
  16. data/lib/ronin/post_ex/cli/shell_shell.rb +66 -0
  17. data/lib/ronin/post_ex/cli/system_shell.rb +811 -0
  18. data/lib/ronin/post_ex/remote_dir.rb +190 -0
  19. data/lib/ronin/post_ex/remote_file/stat.rb +174 -0
  20. data/lib/ronin/post_ex/remote_file.rb +417 -0
  21. data/lib/ronin/post_ex/remote_process.rb +170 -0
  22. data/lib/ronin/post_ex/resource.rb +144 -0
  23. data/lib/ronin/post_ex/sessions/bind_shell.rb +60 -0
  24. data/lib/ronin/post_ex/sessions/remote_shell_session.rb +48 -0
  25. data/lib/ronin/post_ex/sessions/reverse_shell.rb +67 -0
  26. data/lib/ronin/post_ex/sessions/rpc_session.rb +779 -0
  27. data/lib/ronin/post_ex/sessions/session.rb +73 -0
  28. data/lib/ronin/post_ex/sessions/shell_session.rb +618 -0
  29. data/lib/ronin/post_ex/system/fs.rb +650 -0
  30. data/lib/ronin/post_ex/system/process.rb +422 -0
  31. data/lib/ronin/post_ex/system/shell.rb +1037 -0
  32. data/lib/ronin/post_ex/system.rb +191 -0
  33. data/lib/ronin/post_ex/version.rb +26 -0
  34. data/lib/ronin/post_ex.rb +22 -0
  35. data/ronin-post_ex.gemspec +61 -0
  36. data/spec/sessions/bind_shell_spec.rb +31 -0
  37. data/spec/sessions/remote_shell_session_spec.rb +28 -0
  38. data/spec/sessions/reverse_shell_spec.rb +49 -0
  39. data/spec/sessions/rpc_session_spec.rb +500 -0
  40. data/spec/sessions/session_spec.rb +61 -0
  41. data/spec/sessions/shell_session_spec.rb +482 -0
  42. data/spec/spec_helper.rb +9 -0
  43. data/spec/system_spec.rb +66 -0
  44. metadata +155 -0
@@ -0,0 +1,500 @@
1
+ require 'spec_helper'
2
+ require 'ronin/post_ex/sessions/rpc_session'
3
+
4
+ describe Ronin::PostEx::Sessions::RPCSession do
5
+ let(:rpc_client) { double('RPC Client') }
6
+
7
+ subject { described_class.new(rpc_client) }
8
+
9
+ describe "#initialize" do
10
+ it "must set #client" do
11
+ expect(subject.client).to be(rpc_client)
12
+ end
13
+ end
14
+
15
+ let(:response) { double('response value') }
16
+
17
+ describe "#sys_time" do
18
+ it "must call 'sys.time'" do
19
+ expect(rpc_client).to receive(:call).with('sys.time').and_return(response)
20
+
21
+ expect(subject.sys_time).to be(response)
22
+ end
23
+ end
24
+
25
+ describe "#sys_hostname" do
26
+ it "must call 'sys.time'" do
27
+ expect(rpc_client).to receive(:call).with('sys.hostname').and_return(response)
28
+
29
+ expect(subject.sys_hostname).to be(response)
30
+ end
31
+ end
32
+
33
+ describe "#file_open" do
34
+ let(:path) { '/path/to/file' }
35
+
36
+ it "must call 'file.open' with a path and 'r' arguments" do
37
+ expect(rpc_client).to receive(:call).with('file.open',path,'r').and_return(response)
38
+
39
+ expect(subject.file_open(path)).to be(response)
40
+ end
41
+
42
+ context "when given the additional mode argument" do
43
+ let(:mode) { 'rb' }
44
+
45
+ it "must call 'file.open' with a path and mode arguments" do
46
+ expect(rpc_client).to receive(:call).with('file.open',path,mode).and_return(response)
47
+
48
+ expect(subject.file_open(path,mode)).to be(response)
49
+ end
50
+ end
51
+ end
52
+
53
+ describe "#file_read" do
54
+ let(:fd) { double('fd') }
55
+ let(:length) { double('length') }
56
+
57
+ it "must call 'file.read' with a length arguments" do
58
+ expect(rpc_client).to receive(:call).with('file.read',fd,length).and_return(response)
59
+
60
+ expect(subject.file_read(fd,length)).to be(response)
61
+ end
62
+ end
63
+
64
+ describe "#file_write" do
65
+ let(:fd) { double('fd') }
66
+ let(:pos) { double('pos') }
67
+ let(:data) { double('data') }
68
+
69
+ it "must call 'file.read' with fd, pos, and data arguments" do
70
+ expect(rpc_client).to receive(:call).with('file.write',fd,pos,data).and_return(response)
71
+
72
+ expect(subject.file_write(fd,pos,data)).to be(response)
73
+ end
74
+ end
75
+
76
+ describe "#file_seek" do
77
+ let(:fd) { double('fd') }
78
+ let(:new_pos) { double('new_pos') }
79
+ let(:whence) { double('whence') }
80
+
81
+ it "must call 'file.seek' with fd, new_pos, and whence arguments" do
82
+ expect(rpc_client).to receive(:call).with('file.seek',fd,new_pos,whence).and_return(response)
83
+
84
+ expect(subject.file_seek(fd,new_pos,whence)).to be(response)
85
+ end
86
+ end
87
+
88
+ describe "#file_tell" do
89
+ let(:fd) { double('fd') }
90
+
91
+ it "must call 'file.seek' with a fd argument" do
92
+ expect(rpc_client).to receive(:call).with('file.tell',fd).and_return(response)
93
+
94
+ expect(subject.file_tell(fd)).to be(response)
95
+ end
96
+ end
97
+
98
+ describe "#file_ioctl" do
99
+ let(:fd) { double('fd') }
100
+ let(:command) { double('command') }
101
+ let(:argument) { double('argument') }
102
+
103
+ it "must call 'file.ioctl' with a fd, command, and 'argument' arguments" do
104
+ expect(rpc_client).to receive(:call).with('file.ioctl',fd,command,argument).and_return(response)
105
+
106
+ expect(subject.file_ioctl(fd,command,argument)).to be(response)
107
+ end
108
+ end
109
+
110
+ describe "#file_fcntl" do
111
+ let(:fd) { double('fd') }
112
+ let(:command) { double('command') }
113
+ let(:argument) { double('argument') }
114
+
115
+ it "must call 'file.fcntl' with a fd, command, and 'argument' arguments" do
116
+ expect(rpc_client).to receive(:call).with('file.fcntl',fd,command,argument).and_return(response)
117
+
118
+ expect(subject.file_fcntl(fd,command,argument)).to be(response)
119
+ end
120
+ end
121
+
122
+ describe "#file_stat" do
123
+ let(:fd) { double('fd') }
124
+
125
+ it "must call 'file.stat' with a fd argument" do
126
+ expect(rpc_client).to receive(:call).with('file.stat',fd).and_return(response)
127
+
128
+ expect(subject.file_stat(fd)).to be(response)
129
+ end
130
+ end
131
+
132
+ describe "#file_close" do
133
+ let(:fd) { double('fd') }
134
+
135
+ it "must call 'file.fcntl' with a fd argument" do
136
+ expect(rpc_client).to receive(:call).with('file.close',fd).and_return(response)
137
+
138
+ expect(subject.file_close(fd)).to be(response)
139
+ end
140
+ end
141
+
142
+ describe "#fs_gtecwd" do
143
+ it "must call 'fs.getcwd'" do
144
+ expect(rpc_client).to receive(:call).with('fs.getcwd').and_return(response)
145
+
146
+ expect(subject.fs_getcwd).to be(response)
147
+ end
148
+ end
149
+
150
+ describe "#fs_chdir" do
151
+ let(:path) { double('path') }
152
+
153
+ it "must call 'fs.chdir' with a path argument" do
154
+ expect(rpc_client).to receive(:call).with('fs.chdir',path).and_return(response)
155
+
156
+ expect(subject.fs_chdir(path)).to be(response)
157
+ end
158
+ end
159
+
160
+ describe "#fs_readfile" do
161
+ let(:path) { double('path') }
162
+
163
+ it "must call 'fs.readfile' with a path argument" do
164
+ expect(rpc_client).to receive(:call).with('fs.readfile',path).and_return(response)
165
+
166
+ expect(subject.fs_readfile(path)).to be(response)
167
+ end
168
+ end
169
+
170
+ describe "#fs_readlink" do
171
+ let(:path) { double('path') }
172
+
173
+ it "must call 'fs.readlink' with a path argument" do
174
+ expect(rpc_client).to receive(:call).with('fs.readlink',path).and_return(response)
175
+
176
+ expect(subject.fs_readlink(path)).to be(response)
177
+ end
178
+ end
179
+
180
+ describe "#fs_readdir" do
181
+ let(:path) { double('path') }
182
+
183
+ it "must call 'fs.readdir' with a path argument" do
184
+ expect(rpc_client).to receive(:call).with('fs.readdir',path).and_return(response)
185
+
186
+ expect(subject.fs_readdir(path)).to be(response)
187
+ end
188
+ end
189
+
190
+ describe "#fs_glob" do
191
+ let(:pattern) { double('pattern') }
192
+
193
+ it "must call 'fs.glob' with a pattern argument" do
194
+ expect(rpc_client).to receive(:call).with('fs.glob',pattern).and_return(response)
195
+
196
+ expect(subject.fs_glob(pattern)).to be(response)
197
+ end
198
+ end
199
+
200
+ describe "#fs_mktemp" do
201
+ let(:basename) { double('basename') }
202
+
203
+ it "must call 'fs.mktemp' with a basename argument" do
204
+ expect(rpc_client).to receive(:call).with('fs.mktemp',basename).and_return(response)
205
+
206
+ expect(subject.fs_mktemp(basename)).to be(response)
207
+ end
208
+ end
209
+
210
+ describe "#fs_mkdir" do
211
+ let(:new_path) { double('new_path') }
212
+
213
+ it "must call 'fs.mkdir' with a new_path argument" do
214
+ expect(rpc_client).to receive(:call).with('fs.mkdir',new_path).and_return(response)
215
+
216
+ expect(subject.fs_mkdir(new_path)).to be(response)
217
+ end
218
+ end
219
+
220
+ describe "#fs_copy" do
221
+ let(:src) { double('src') }
222
+ let(:dest) { double('dest') }
223
+
224
+ it "must call 'fs.copy' with src and dest arguments" do
225
+ expect(rpc_client).to receive(:call).with('fs.copy',src,dest).and_return(response)
226
+
227
+ expect(subject.fs_copy(src,dest)).to be(response)
228
+ end
229
+ end
230
+
231
+ describe "#fs_unlink" do
232
+ let(:path) { double('path') }
233
+
234
+ it "must call 'fs.unlink' with a path arguments" do
235
+ expect(rpc_client).to receive(:call).with('fs.unlink',path).and_return(response)
236
+
237
+ expect(subject.fs_unlink(path)).to be(response)
238
+ end
239
+ end
240
+
241
+ describe "#fs_rmdir" do
242
+ let(:path) { double('path') }
243
+
244
+ it "must call 'fs.rmdir' with a path arguments" do
245
+ expect(rpc_client).to receive(:call).with('fs.rmdir',path).and_return(response)
246
+
247
+ expect(subject.fs_rmdir(path)).to be(response)
248
+ end
249
+ end
250
+
251
+ describe "#fs_move" do
252
+ let(:src) { double('src') }
253
+ let(:dest) { double('dest') }
254
+
255
+ it "must call 'fs.move' with src and dest arguments" do
256
+ expect(rpc_client).to receive(:call).with('fs.move',src,dest).and_return(response)
257
+
258
+ expect(subject.fs_move(src,dest)).to be(response)
259
+ end
260
+ end
261
+
262
+ describe "#fs_link" do
263
+ let(:src) { double('src') }
264
+ let(:dest) { double('dest') }
265
+
266
+ it "must call 'fs.link' with src and dest arguments" do
267
+ expect(rpc_client).to receive(:call).with('fs.link',src,dest).and_return(response)
268
+
269
+ expect(subject.fs_link(src,dest)).to be(response)
270
+ end
271
+ end
272
+
273
+ describe "#fs_chgrp" do
274
+ let(:group) { double('group') }
275
+ let(:path) { double('path') }
276
+
277
+ it "must call 'fs.chgrp' with group and path arguments" do
278
+ expect(rpc_client).to receive(:call).with('fs.chgrp',group,path).and_return(response)
279
+
280
+ expect(subject.fs_chgrp(group,path)).to be(response)
281
+ end
282
+ end
283
+
284
+ describe "#fs_chown" do
285
+ let(:user) { double('user') }
286
+ let(:path) { double('path') }
287
+
288
+ it "must call 'fs.chown' with user and path arguments" do
289
+ expect(rpc_client).to receive(:call).with('fs.chown',user,path).and_return(response)
290
+
291
+ expect(subject.fs_chown(user,path)).to be(response)
292
+ end
293
+ end
294
+
295
+ describe "#fs_chmod" do
296
+ let(:mode) { double('mode') }
297
+ let(:path) { double('path') }
298
+
299
+ it "must call 'fs.chmod' with mode and path arguments" do
300
+ expect(rpc_client).to receive(:call).with('fs.chmod',mode,path).and_return(response)
301
+
302
+ expect(subject.fs_chmod(mode,path)).to be(response)
303
+ end
304
+ end
305
+
306
+ describe "#fs_stat" do
307
+ let(:path) { double('path') }
308
+
309
+ it "must call 'fs.stat' with a path argument" do
310
+ expect(rpc_client).to receive(:call).with('fs.stat',path).and_return(response)
311
+
312
+ expect(subject.fs_stat(path)).to be(response)
313
+ end
314
+ end
315
+
316
+ describe "#process_getpid" do
317
+ it "must call 'process.getpid'" do
318
+ expect(rpc_client).to receive(:call).with('process.getpid').and_return(response)
319
+
320
+ expect(subject.process_getpid).to be(response)
321
+ end
322
+ end
323
+
324
+ describe "#process_getppid" do
325
+ it "must call 'process.getppid'" do
326
+ expect(rpc_client).to receive(:call).with('process.getppid').and_return(response)
327
+
328
+ expect(subject.process_getppid).to be(response)
329
+ end
330
+ end
331
+
332
+ describe "#process_getuid" do
333
+ it "must call 'process.getuid'" do
334
+ expect(rpc_client).to receive(:call).with('process.getuid').and_return(response)
335
+
336
+ expect(subject.process_getuid).to be(response)
337
+ end
338
+ end
339
+
340
+ describe "#process_setuid" do
341
+ let(:uid) { double('uid') }
342
+
343
+ it "must call 'process.setuid' with a uid argument" do
344
+ expect(rpc_client).to receive(:call).with('process.setuid',uid).and_return(response)
345
+
346
+ expect(subject.process_setuid(uid)).to be(response)
347
+ end
348
+ end
349
+
350
+ describe "#process_geteuid" do
351
+ it "must call 'process.geteuid'" do
352
+ expect(rpc_client).to receive(:call).with('process.geteuid').and_return(response)
353
+
354
+ expect(subject.process_geteuid).to be(response)
355
+ end
356
+ end
357
+
358
+ describe "#process_seteuid" do
359
+ let(:euid) { double('euid') }
360
+
361
+ it "must call 'process.seteuid' with a euid argument" do
362
+ expect(rpc_client).to receive(:call).with('process.seteuid',euid).and_return(response)
363
+
364
+ expect(subject.process_seteuid(euid)).to be(response)
365
+ end
366
+ end
367
+
368
+ describe "#process_getgid" do
369
+ it "must call 'process.getgid'" do
370
+ expect(rpc_client).to receive(:call).with('process.getgid').and_return(response)
371
+
372
+ expect(subject.process_getgid).to be(response)
373
+ end
374
+ end
375
+
376
+ describe "#process_setgid" do
377
+ let(:gid) { double('gid') }
378
+
379
+ it "must call 'process.setgid' with a gid argument" do
380
+ expect(rpc_client).to receive(:call).with('process.setgid',gid).and_return(response)
381
+
382
+ expect(subject.process_setgid(gid)).to be(response)
383
+ end
384
+ end
385
+
386
+ describe "#process_getegid" do
387
+ it "must call 'process.getegid'" do
388
+ expect(rpc_client).to receive(:call).with('process.getegid').and_return(response)
389
+
390
+ expect(subject.process_getegid).to be(response)
391
+ end
392
+ end
393
+
394
+ describe "#process_setegid" do
395
+ let(:egid) { double('egid') }
396
+
397
+ it "must call 'process.setegid' with a egid argument" do
398
+ expect(rpc_client).to receive(:call).with('process.setegid',egid).and_return(response)
399
+
400
+ expect(subject.process_setegid(egid)).to be(response)
401
+ end
402
+ end
403
+
404
+ describe "#process_getsid" do
405
+ it "must call 'process.getsid'" do
406
+ expect(rpc_client).to receive(:call).with('process.getsid').and_return(response)
407
+
408
+ expect(subject.process_getsid).to be(response)
409
+ end
410
+ end
411
+
412
+ describe "#process_setsid" do
413
+ let(:sid) { double('sid') }
414
+
415
+ it "must call 'process.setsid' with a sid argument" do
416
+ expect(rpc_client).to receive(:call).with('process.setsid',sid).and_return(response)
417
+
418
+ expect(subject.process_setsid(sid)).to be(response)
419
+ end
420
+ end
421
+
422
+ describe "#process_environ" do
423
+ it "must call 'process.environ'" do
424
+ expect(rpc_client).to receive(:call).with('process.environ').and_return(response)
425
+
426
+ expect(subject.process_environ).to be(response)
427
+ end
428
+ end
429
+
430
+ describe "#process_getenv" do
431
+ let(:name) { double('name') }
432
+
433
+ it "must call 'process.getenv' with a name argument" do
434
+ expect(rpc_client).to receive(:call).with('process.getenv',name).and_return(response)
435
+
436
+ expect(subject.process_getenv(name)).to be(response)
437
+ end
438
+ end
439
+
440
+ describe "#process_getenv" do
441
+ let(:name) { double('name') }
442
+ let(:value) { double('value') }
443
+
444
+ it "must call 'process.setenv' with name and value arguments" do
445
+ expect(rpc_client).to receive(:call).with('process.setenv',name,value).and_return(response)
446
+
447
+ expect(subject.process_setenv(name,value)).to be(response)
448
+ end
449
+ end
450
+
451
+ describe "#process_unsetenv" do
452
+ let(:name) { double('name') }
453
+
454
+ it "must call 'process.unsetenv' with a name argument" do
455
+ expect(rpc_client).to receive(:call).with('process.unsetenv',name).and_return(response)
456
+
457
+ expect(subject.process_unsetenv(name)).to be(response)
458
+ end
459
+ end
460
+
461
+ describe "#process_kill" do
462
+ let(:pid) { double('pid') }
463
+ let(:signal) { double('signal') }
464
+
465
+ it "must call 'process.kill' with pid and signal arguments" do
466
+ expect(rpc_client).to receive(:call).with('process.kill',pid,signal).and_return(response)
467
+
468
+ expect(subject.process_kill(pid,signal)).to be(response)
469
+ end
470
+ end
471
+
472
+ describe "#process_spawn" do
473
+ let(:program) { double('program') }
474
+ let(:arguments) { [double('arg1'), double('arg2')] }
475
+
476
+ it "must call 'process.spawn' with program and 'arguments' arguments" do
477
+ expect(rpc_client).to receive(:call).with('process.spawn',program,*arguments).and_return(response)
478
+
479
+ expect(subject.process_spawn(program,*arguments)).to be(response)
480
+ end
481
+ end
482
+
483
+ describe "#process_exit" do
484
+ it "must call 'process.exit'" do
485
+ expect(rpc_client).to receive(:call).with('process.exit').and_return(response)
486
+
487
+ expect(subject.process_exit).to be(response)
488
+ end
489
+ end
490
+
491
+ describe "#shell_exec" do
492
+ let(:command) { double('command') }
493
+
494
+ it "must call 'shell.exec' with a command argument" do
495
+ expect(rpc_client).to receive(:call).with('shell.exec',command).and_return(response)
496
+
497
+ expect(subject.shell_exec(command)).to be(response)
498
+ end
499
+ end
500
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require 'ronin/post_ex/sessions/session'
3
+
4
+ describe Ronin::PostEx::Sessions::Session do
5
+ describe "#name" do
6
+ context "when #name is set" do
7
+ module TestSession
8
+ class SessionWithNameSet < Ronin::PostEx::Sessions::Session
9
+
10
+ def initialize(name)
11
+ @name = name
12
+ end
13
+
14
+ end
15
+ end
16
+
17
+ let(:name) { 'example-session' }
18
+
19
+ subject { TestSession::SessionWithNameSet.new(name) }
20
+
21
+ it "must return @name" do
22
+ expect(subject.name).to eq(name)
23
+ end
24
+ end
25
+
26
+ context "when @name is not set" do
27
+ module TestSession
28
+ class SessionWithoutNameSet < Ronin::PostEx::Sessions::Session
29
+ end
30
+ end
31
+
32
+ subject { TestSession::SessionWithoutNameSet.new }
33
+
34
+ it do
35
+ expect {
36
+ subject.name
37
+ }.to raise_error(NotImplementedError,"#{subject.class}#name was not set")
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "#system" do
43
+ it "must return a Ronin::PostEx::System object" do
44
+ expect(subject.system).to be_kind_of(Ronin::PostEx::System)
45
+ end
46
+
47
+ it "must return the same object each time" do
48
+ expect(subject.system).to be(subject.system)
49
+ end
50
+ end
51
+
52
+ describe "#to_s" do
53
+ let(:name) { "host:port" }
54
+
55
+ it "must call #name" do
56
+ expect(subject).to receive(:name).and_return(name)
57
+
58
+ expect(subject.to_s).to be(name)
59
+ end
60
+ end
61
+ end