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,779 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-post_ex - a Ruby API for Post-Exploitation.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-post_ex is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-post_ex is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-post_ex. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/post_ex/sessions/session'
22
+
23
+ module Ronin
24
+ module PostEx
25
+ module Sessions
26
+ #
27
+ # Provides a post-exploitation session which wraps around an RPC client.
28
+ #
29
+ class RPCSession < Session
30
+
31
+ # The RPC client object.
32
+ #
33
+ # @return [#call]
34
+ #
35
+ # @api private
36
+ attr_reader :client
37
+
38
+ #
39
+ # Initializes the RPC session.
40
+ #
41
+ # @param [#call] client
42
+ # The RPC client. It must define a `call` method.
43
+ #
44
+ def initialize(client)
45
+ @client = client
46
+ end
47
+
48
+ #
49
+ # Calls the RPC method.
50
+ #
51
+ # @param [String] method
52
+ # The RPC method name to call.
53
+ #
54
+ # @param [Array] arguments
55
+ # Additional arguments for the RPC method.
56
+ #
57
+ # @return [Object]
58
+ # The result value from the RPC method.
59
+ #
60
+ def call(method,*arguments)
61
+ @client.call(method,*arguments)
62
+ end
63
+
64
+ #
65
+ # @group System Methods
66
+ #
67
+
68
+ #
69
+ # Gets the current time and returns the UNIX timestamp.
70
+ #
71
+ # @return [Integer]
72
+ # The current time as a UNIX timestamp.
73
+ #
74
+ # @note calls the `sys.time` RPC function.
75
+ #
76
+ def sys_time
77
+ call('sys.time')
78
+ end
79
+
80
+ #
81
+ # Gets the system's hostname.
82
+ #
83
+ # @return [String]
84
+ #
85
+ # @note calls the `sys.hostname` RPC function.
86
+ #
87
+ def sys_hostname
88
+ call('sys.hostname')
89
+ end
90
+
91
+ #
92
+ # @group File Methods
93
+ #
94
+
95
+ #
96
+ # Opens a file and returns the file-descriptor number.
97
+ #
98
+ # @param [String] path
99
+ # The remote file path to open.
100
+ #
101
+ # @param [String] mode
102
+ # The mode to open the file.
103
+ #
104
+ # @return [Integer]
105
+ # The opened remote file descriptor.
106
+ #
107
+ # @note calls the `file.open` RPC function.
108
+ #
109
+ def file_open(path,mode='r')
110
+ call('file.open',path,mode)
111
+ end
112
+
113
+ #
114
+ # Reads from an opened file-descriptor and returns the read data.
115
+ #
116
+ # @param [Integer] fd
117
+ # The remote file descriptor to read from.
118
+ #
119
+ # @param [Integer] length
120
+ # The length of data in bytes to read from the file descriptor.
121
+ #
122
+ # @return [String, nil]
123
+ # Returns the read data or `nil` if there is no more data to be read.
124
+ #
125
+ # @note calls the `file.read` RPC function.
126
+ #
127
+ def file_read(fd,length)
128
+ call('file.read',fd,length)
129
+ end
130
+
131
+ #
132
+ # Writes data to the opened file-descriptor.
133
+ #
134
+ # @param [Integer] fd
135
+ # The remote file descriptor to write to.
136
+ #
137
+ # @param [Integer] pos
138
+ # The position to write the data at.
139
+ #
140
+ # @param [String] data
141
+ # The data to write.
142
+ #
143
+ # @return [Integer]
144
+ #
145
+ # @note calls the `file.write` RPC function.
146
+ #
147
+ def file_write(fd,pos,data)
148
+ call('file.write',fd,pos,data)
149
+ end
150
+
151
+ #
152
+ # Seeks to a position within the file.
153
+ #
154
+ # @param [Integer] fd
155
+ # The remote file descriptor to seek.
156
+ #
157
+ # @param [Integer] new_pos
158
+ # The new position to seek to.
159
+ #
160
+ # @param [String] whence
161
+ # How the position should be interpreted. Must be one of the
162
+ # following String values:
163
+ # * `"SEEK_SET"` - seek from beginning of file.
164
+ # * `"SEEK_CUR"` - seek from current position.
165
+ # * `"SEEK_END"` - seek from end of file.
166
+ # * `"SEEK_DATA"` - seek to next data.
167
+ # * `"SEEK_HOLE"` - seek to next hole.
168
+ #
169
+ # @note calls the `file.seek` RPC function.
170
+ #
171
+ def file_seek(fd,new_pos,whence)
172
+ call('file.seek',fd,new_pos,whence)
173
+ end
174
+
175
+ #
176
+ # Queries the current position within the file.
177
+ #
178
+ # @param [Integer] fd
179
+ # The remote file descriptor to query.
180
+ #
181
+ # @return [Integer]
182
+ # The current position of the remote file descriptor.
183
+ #
184
+ # @note calls the `file.tell` RPC function.
185
+ #
186
+ def file_tell(fd)
187
+ call('file.tell',fd)
188
+ end
189
+
190
+ #
191
+ # Performs a `ioctl()` operation on the file-descriptor.
192
+ #
193
+ # @param [Integer] fd
194
+ # The remote file descriptor to perform the `ioctl()` on.
195
+ #
196
+ # @param [String, Array<Integer>] command
197
+ # The `ioctl()` command String or Array of bytes.
198
+ #
199
+ # @param [Object] argument
200
+ # The additional `ioctl()` argument.
201
+ #
202
+ # @return [Integer]
203
+ # The return value of the `ioctl()`.
204
+ #
205
+ # @note calls the `file.ioctl` RPC function.
206
+ #
207
+ def file_ioctl(fd,command,argument)
208
+ call('file.ioctl',fd,command,argument)
209
+ end
210
+
211
+ #
212
+ # Performs a `fcntl()` operation on the file-descriptor.
213
+ #
214
+ # @param [Integer] fd
215
+ # The remote file descriptor to perform the `fcntl()` on.
216
+ #
217
+ # @param [String, Array<Integer>] command
218
+ # The `fcntl()` command String or Array of bytes.
219
+ #
220
+ # @param [Object] argument
221
+ # The additional `fcntl()` argument.
222
+ #
223
+ # @return [Integer]
224
+ # The return value of the `fcntl()`.
225
+ #
226
+ # @note calls the `file.fcntl` RPC function.
227
+ #
228
+ def file_fcntl(fd,command,argument)
229
+ call('file.fcntl',fd,command,argument)
230
+ end
231
+
232
+ #
233
+ # Queries file information from the given file-descriptor and returns a
234
+ # Hash of file metadata.
235
+ #
236
+ # @param [Integer] fd
237
+ # The remote file descriptor to query.
238
+ #
239
+ # @return [Hash{Symbol => Object}, nil]
240
+ # The Hash of file metadata or `nil` if the remote file descriptor
241
+ # could not be stat-ed.
242
+ #
243
+ # @note calls the `file.stat` RPC function.
244
+ #
245
+ def file_stat(fd)
246
+ call('file.stat',fd)
247
+ end
248
+
249
+ #
250
+ # Closes an opened remote file-descriptor.
251
+ #
252
+ # @param [Integer] fd
253
+ # The remote file descriptor to close.
254
+ #
255
+ # @note calls the `file.close` RPC function.
256
+ #
257
+ def file_close(fd)
258
+ call('file.close',fd)
259
+ end
260
+
261
+ #
262
+ # @group File-System methods
263
+ #
264
+
265
+ #
266
+ # Gets the current working directory and returns the directory path.
267
+ #
268
+ # @return [String]
269
+ # The remote current working directory.
270
+ #
271
+ # @note calls the `fs.getcwd` RPC function.
272
+ #
273
+ def fs_getcwd
274
+ call('fs.getcwd')
275
+ end
276
+
277
+ #
278
+ # Changes the current working directory.
279
+ #
280
+ # @param [String] path
281
+ # The new remote current working directory.
282
+ #
283
+ # @note calls the `fs.chdir` RPC function.
284
+ #
285
+ def fs_chdir(path)
286
+ call('fs.chdir',path)
287
+ end
288
+
289
+ #
290
+ # Reads the entire file at the given path and returns the full file's
291
+ # contents.
292
+ #
293
+ # @param [String] path
294
+ # The remote path to read.
295
+ #
296
+ # @return [String, nil]
297
+ # The contents of the remote file or `nil` if the file could not be
298
+ # read.
299
+ #
300
+ # @note calls the `fs.readfile` RPC function.
301
+ #
302
+ def fs_readfile(path)
303
+ call('fs.readfile',path)
304
+ end
305
+
306
+ #
307
+ # Reads the destination path of a remote symbolic link.
308
+ #
309
+ # @param [String] path
310
+ # The remote path to read.
311
+ #
312
+ # @return [String, nil]
313
+ # The destination of the remote symbolic link or `nil` if the symbolic
314
+ # link could not be read.
315
+ #
316
+ # @note calls the `fs.readlink` RPC function.
317
+ #
318
+ def fs_readlink(path)
319
+ call('fs.readlink',path)
320
+ end
321
+
322
+ #
323
+ # Reads the contents of a remote directory and returns an Array of
324
+ # directory entry names.
325
+ #
326
+ # @param [String] path
327
+ # The path of the remote directory to read.
328
+ #
329
+ # @return [Array<String>]
330
+ # The entities within the remote directory.
331
+ #
332
+ # @note calls the `fs.readdir` RPC function.
333
+ #
334
+ def fs_readdir(path)
335
+ call('fs.readdir',path)
336
+ end
337
+
338
+ #
339
+ # Evaluates a directory glob pattern and returns all matching paths.
340
+ #
341
+ # @param [String] pattern
342
+ # The glob pattern to search for remotely.
343
+ #
344
+ # @return [Array<String>]
345
+ # The matching paths.
346
+ #
347
+ # @note calls the `fs.glob` RPC function.
348
+ #
349
+ def fs_glob(pattern)
350
+ call('fs.glob',pattern)
351
+ end
352
+
353
+ #
354
+ # Creates a remote temporary file with the given file basename.
355
+ #
356
+ # @param [String] basename
357
+ # The basename for the new temporary file.
358
+ #
359
+ # @return [String]
360
+ # The path of the newly created temporary file.
361
+ #
362
+ # @note calls the `fs.mktemp` RPC function.
363
+ #
364
+ def fs_mktemp(basename)
365
+ call('fs.mktemp',basename)
366
+ end
367
+
368
+ #
369
+ # Creates a new remote directory at the given path.
370
+ #
371
+ # @param [String] new_path
372
+ # The new remote directory to create.
373
+ #
374
+ # @note calls the `fs.mkdir` RPC function.
375
+ #
376
+ def fs_mkdir(new_path)
377
+ call('fs.mkdir',new_path)
378
+ end
379
+
380
+ #
381
+ # Copies a source file to the destination path.
382
+ #
383
+ # @param [String] src
384
+ # The source file.
385
+ #
386
+ # @param [String] dest
387
+ # The destination path.
388
+ #
389
+ # @note calls the `fs.copy` RPC function.
390
+ #
391
+ def fs_copy(src,dest)
392
+ call('fs.copy',src,dest)
393
+ end
394
+
395
+ #
396
+ # Removes a file at the given path.
397
+ #
398
+ # @param [String] path
399
+ # The remote path to remove.
400
+ #
401
+ # @note calls the `fs.unlink` RPC function.
402
+ #
403
+ def fs_unlink(path)
404
+ call('fs.unlink',path)
405
+ end
406
+
407
+ #
408
+ # Removes an empty directory at the given path.
409
+ #
410
+ # @param [String] path
411
+ # The remote directory path to remove.
412
+ #
413
+ # @note calls the `fs.rmdir` RPC function.
414
+ #
415
+ def fs_rmdir(path)
416
+ call('fs.rmdir',path)
417
+ end
418
+
419
+ #
420
+ # Moves or renames a remote source file to a new destination path.
421
+ #
422
+ # @param [String] src
423
+ # The source file path.
424
+ #
425
+ # @param [String] dest
426
+ # The destination file path.
427
+ #
428
+ # @note calls the `fs.move` RPC function.
429
+ #
430
+ def fs_move(src,dest)
431
+ call('fs.move',src,dest)
432
+ end
433
+
434
+ #
435
+ # Creates a remote symbolic link at the destination path pointing to the
436
+ # source path.
437
+ #
438
+ # @param [String] src
439
+ # The source file path for the new symbolic link.
440
+ #
441
+ # @param [String] dest
442
+ # The remote path of the new symbolic link.
443
+ #
444
+ # @note calls the `fs.link` RPC function.
445
+ #
446
+ def fs_link(src,dest)
447
+ call('fs.link',src,dest)
448
+ end
449
+
450
+ #
451
+ # Changes the group ownership of a remote file or directory.
452
+ #
453
+ # @param [String] group
454
+ # The new group name for the remote file or directory.
455
+ #
456
+ # @param [String] path
457
+ # The path of the remote file or directory.
458
+ #
459
+ # @note calls the `fs.chgrp` RPC function.
460
+ #
461
+ def fs_chgrp(group,path)
462
+ call('fs.chgrp',group,path)
463
+ end
464
+
465
+ #
466
+ # Changes the user ownership of remote a file or directory.
467
+ #
468
+ # @param [String] user
469
+ # The new user for the remote file or directory.
470
+ #
471
+ # @param [String] path
472
+ # The path of the remote file or directory.
473
+ #
474
+ # @note calls the `fs.chown` RPC function.
475
+ #
476
+ def fs_chown(user,path)
477
+ call('fs.chown',user,path)
478
+ end
479
+
480
+ #
481
+ # Changes the permissions on a remote file or directory.
482
+ #
483
+ # @param [Integer] mode
484
+ # The permissions mode for the remote file or directory.
485
+ #
486
+ # @param [String] path
487
+ # The path of the remote file or directory.
488
+ #
489
+ # @note calls the `fs.chmod` RPC function.
490
+ #
491
+ def fs_chmod(mode,path)
492
+ call('fs.chmod',mode,path)
493
+ end
494
+
495
+ #
496
+ # Queries file information for the given remote path and returns a Hash
497
+ # of file metadata.
498
+ #
499
+ # @param [String] path
500
+ # The path to the remote file or directory.
501
+ #
502
+ # @return [Hash{Symbol => Object}, nil]
503
+ # The metadata for the remote file.
504
+ #
505
+ # @note calls the `fs.stat` RPC function.
506
+ #
507
+ def fs_stat(path)
508
+ call('fs.stat',path)
509
+ end
510
+
511
+ #
512
+ # @group Process methods
513
+ #
514
+
515
+ #
516
+ # Gets the current process's Process ID (PID).
517
+ #
518
+ # @return [Integer]
519
+ # The current process's PID.
520
+ #
521
+ # @note calls the `process.getpid` RPC function.
522
+ #
523
+ def process_getpid
524
+ call('process.getpid')
525
+ end
526
+
527
+ #
528
+ # Gets the current process's parent Process ID (PPID).
529
+ #
530
+ # @return [Integer]
531
+ # The current process's PPID.
532
+ #
533
+ # @note calls the `process.getppid` RPC function.
534
+ #
535
+ def process_getppid
536
+ call('process.getppid')
537
+ end
538
+
539
+ #
540
+ # Gets the current process's user ID (UID).
541
+ #
542
+ # @return [Integer]
543
+ # The current process's UID.
544
+ #
545
+ # @note calls the `process.getuid` RPC function.
546
+ #
547
+ def process_getuid
548
+ call('process.getuid')
549
+ end
550
+
551
+ #
552
+ # Sets the current process's user ID (UID) to the given Integer.
553
+ #
554
+ # @param [Integer] uid
555
+ # The new UID for the current process.
556
+ #
557
+ # @note calls the `process.setuid` RPC function.
558
+ #
559
+ def process_setuid(uid)
560
+ call('process.setuid',uid)
561
+ end
562
+
563
+ #
564
+ # Gets the current process's effective UID (EUID).
565
+ #
566
+ # @return [Integer]
567
+ # the effective UID (EUID) for the current process.
568
+ #
569
+ # @note calls the `process.geteuid` RPC function.
570
+ #
571
+ def process_geteuid
572
+ call('process.geteuid')
573
+ end
574
+
575
+ #
576
+ # Sets the current process's effective UID (EUID) to the given Integer.
577
+ #
578
+ # @param [Integer] euid
579
+ # The new effective UID (EUID) for the current process.
580
+ #
581
+ # @note calls the `process_seteuid` RPC function.
582
+ #
583
+ def process_seteuid(euid)
584
+ call('process.seteuid',euid)
585
+ end
586
+
587
+ #
588
+ # Gets the current process's group ID (GID).
589
+ #
590
+ # @return [Integer]
591
+ # The group ID (GID) for the current process.
592
+ #
593
+ # @note calls the `process_getgid` RPC function.
594
+ #
595
+ def process_getgid
596
+ call('process.getgid')
597
+ end
598
+
599
+ #
600
+ # Sets the current process's group ID (GID) to the given Integer.
601
+ #
602
+ # @param [Integer] gid
603
+ # The new group ID (GID) for the current process.
604
+ #
605
+ # @note calls the `process_setgid` RPC function.
606
+ #
607
+ def process_setgid(gid)
608
+ call('process.setgid',gid)
609
+ end
610
+
611
+ #
612
+ # Gets the current process's effective group ID (EGID).
613
+ #
614
+ # @return [Integer]
615
+ # The effective group ID (EGID) of the current process.
616
+ #
617
+ # @note calls the `process_getegid` RPC function.
618
+ #
619
+ def process_getegid
620
+ call('process.getegid')
621
+ end
622
+
623
+ #
624
+ # Sets the current process's effective group ID (EGID) to the given
625
+ # Integer.
626
+ #
627
+ # @param [Integer] egid
628
+ # The new effective group ID (EGID) for the current process.
629
+ #
630
+ # @note calls the `process_setegid` RPC function.
631
+ #
632
+ def process_setegid(egid)
633
+ call('process.setegid',egid)
634
+ end
635
+
636
+ #
637
+ # Gets the current process's session ID (SID).
638
+ #
639
+ # @return [Integer]
640
+ # the session ID (SID) of the current process.
641
+ #
642
+ # @note calls the `process.getsid` RPC function.
643
+ #
644
+ def process_getsid
645
+ call('process.getsid')
646
+ end
647
+
648
+ #
649
+ # Sets the current process's session ID (SID).
650
+ #
651
+ # @param [Integer] sid
652
+ # The new session ID (SID) for the current process.
653
+ #
654
+ # @note calls the `process.setsid` RPC function.
655
+ #
656
+ def process_setsid(sid)
657
+ call('process.setsid',sid)
658
+ end
659
+
660
+ #
661
+ # Queries all environment variables of the current process. Returns a
662
+ # Hash of the env variable names and values.
663
+ #
664
+ # @return [Hash{String => String}]
665
+ # The Hash of environment variables.
666
+ #
667
+ # @note calls the `process.environ` RPC function.
668
+ #
669
+ def process_environ
670
+ call('process.environ')
671
+ end
672
+
673
+ #
674
+ # Gets an individual environment variable. If the environment variable
675
+ # has not been set, `nil` will be returned.
676
+ #
677
+ # @param [String] name
678
+ # The environment variable name to get.
679
+ #
680
+ # @return [String, nil]
681
+ # The environment variable value.
682
+ #
683
+ # @note calls the `process.getenv` RPC function.
684
+ #
685
+ def process_getenv(name)
686
+ call('process.getenv',name)
687
+ end
688
+
689
+ #
690
+ # Sets an environment variable to the given value.
691
+ #
692
+ # @param [String] name
693
+ # The environment variable name to set.
694
+ #
695
+ # @param [String] value
696
+ # The new value for the environment variable.
697
+ #
698
+ # @note calls the `process.setenv` RPC function.
699
+ #
700
+ def process_setenv(name,value)
701
+ call('process.setenv',name,value)
702
+ end
703
+
704
+ #
705
+ # Un-sets an environment variable.
706
+ #
707
+ # @param [String] name
708
+ # The environment variable to unset.
709
+ #
710
+ # @note calls the `process.unsetenv` RPC function.
711
+ #
712
+ def process_unsetenv(name)
713
+ call('process.unsetenv',name)
714
+ end
715
+
716
+ #
717
+ # Kills another process using the given Process ID (POD) and the signal
718
+ # number.
719
+ #
720
+ # @param [Integer] pid
721
+ # The process ID (PID) to kill.
722
+ #
723
+ # @param [Integer] signal
724
+ # The signal to send the process ID (PID).
725
+ #
726
+ # @note calls the `process.kill` RPC function.
727
+ #
728
+ def process_kill(pid,signal)
729
+ call('process.kill',pid,signal)
730
+ end
731
+
732
+ #
733
+ # Spawns a new process using the given program and additional arguments.
734
+ #
735
+ # @param [String] program
736
+ # The program name to spawn.
737
+ #
738
+ # @param [Array<String>] arguments
739
+ # Additional arguments for the program.
740
+ #
741
+ # @return [Integer]
742
+ # The process ID (PID) of the spawned process.
743
+ #
744
+ # @note calls the `process.spawn` RPC function.
745
+ #
746
+ def process_spawn(program,*arguments)
747
+ call('process.spawn',program,*arguments)
748
+ end
749
+
750
+ #
751
+ # Exits the current process.
752
+ #
753
+ # @note calls the `process.exit` RPC function.
754
+ #
755
+ def process_exit
756
+ call('process.exit')
757
+ end
758
+
759
+ #
760
+ # @group Shell Methods
761
+ #
762
+
763
+ #
764
+ # Executes a new shell command using the given program name and
765
+ # additional arguments.
766
+ #
767
+ # @param [String] command
768
+ # The command to execute.
769
+ #
770
+ # @note calls the `shell.exec` RPC function.
771
+ #
772
+ def shell_exec(command)
773
+ call('shell.exec',command)
774
+ end
775
+
776
+ end
777
+ end
778
+ end
779
+ end