CVE-2019-15790
Apport PID recycling exploit
- CVSS 3.3
- CWE-269
- Authentication, Authorization, and Session Management
- Local
Apport reads and writes information on a crashed process to /proc/pid with elevated privileges. Apport then determines which user the crashed process belongs to by reading /proc/pid through get_pid_info() in data/apport. An unprivileged user could exploit this to read information about a privileged running process by exploiting PID recycling. This information could then be used to obtain ASLR offsets for a process with an existing memory corruption vulnerability. The initial fix introduced regressions in the Python Apport library due to a missing argument in Report.add_proc_environ in apport/report.py. It also caused an autopkgtest failure when reading /proc/pid and with Python 2 compatibility by reading /proc maps. The initial and subsequent regression fixes are in 2.20.11-0ubuntu16, 2.20.11-0ubuntu8.6, 2.20.9-0ubuntu7.12, 2.20.1-0ubuntu2.22 and 2.14.1-0ubuntu3.29+esm3.
- CWE
- CWE-269
- CVSS base score
- 3.3
- Published
- 2020-04-28
- OWASP
- A07 Identification and Authentication Failures
- Orthogonal defect classification
- Function
- Code defect classification
- Incorrect Functionality
- Category
- Authentication, Authorization, and Session Management
- Subcategory
- Privilege Escalation
- Accessibility scope
- Local
- Impact
- Information Disclosure
- Fixed by upgrading
- Yes
Solution
Update Apport to version 2.20.11-0ubuntu16 or higher.
Vulnerable code sample
import os
def get_pid_info(pid):
try:
with open(f'/proc/{pid}/status') as f:
return f.read()
except FileNotFoundError:
return None
def read_process_info(pid):
proc_info = get_pid_info(pid)
if proc_info:
print(f"Process {pid} info:\n{proc_info}")
else:
print(f"No information found for PID {pid}")Patched code sample
import os
import pwd
def get_pid_info(pid):
try:
with open(f'/proc/{pid}/status') as f:
status_info = f.read()
uid = int(status_info.split('Uid:')[1].split()[0])
user = pwd.getpwuid(uid).pw_name
return user, status_info
except FileNotFoundError:
return None, None
def read_process_info(pid):
user, status_info = get_pid_info(pid)
if user is None:
raise ValueError("Invalid PID or process does not exist.")
current_user = pwd.getpwuid(os.getuid()).pw_name
if user != current_user:
raise PermissionError("Attempt to read information from a process owned by another user.")
return status_infoCite this entry
@misc{vaitp:cve201915790,
title = {{Apport PID recycling exploit}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2020},
note = {VAITP Python Vulnerability Dataset, entry CVE-2019-15790},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2019-15790/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
