Skip to content
Accueil » Vulnerability Research – Null pointer dereference in Curl

Vulnerability Research – Null pointer dereference in Curl

Introduction

Few days ago I was reading the code of Curl with the intend to find vulnerabilities. After some investigations I found that the idn module contains a Null pointer dereference bug.

An internationalized domain name (IDN) is an Internet domain name that contains at least one label displayed in software applications, in whole or in part, in non-latin script or alphabet[a] or in the Latin alphabet-based characters with diacritics or ligatures.[b] These writing systems are encoded by computers in multibyte Unicode. Internationalized domain names are stored in the Domain Name System (DNS) as ASCII strings using Punycode transcription.

Analysis

The commented code below describes the bug. Basically when the idn_decode() function is called it pass null to the *decoded pointer which is later on used by the function Curl_idn_free()

static CURLcode idn_decode(const char *input, char **output)
{

char *decoded = NULL;
/* 4. 'decoded' initialized to a null pointer value	*/

CURLcode result = CURLE_OK;
#ifdef USE_LIBIDN2
if(idn2_check_version(IDN2_VERSION)) {
	
/* 5. Assuming the condition is false	*/
/* 6. Taking false branch	*/

int flags = IDN2_NFC_INPUT
#if IDN2_VERSION_NUMBER >= 0x00140000 | IDN2_NONTRANSITIONAL
#endif;
int rc = IDN2_LOOKUP(input, &decoded, flags);
if(rc != IDN2_OK)
rc = IDN2_LOOKUP(input, &decoded, IDN2_TRANSITIONAL);
if(rc != IDN2_OK)
result = CURLE_URL_MALFORMAT;
}
#elif defined(USE_WIN32_IDN)
result = win32_idn_to_ascii(input, &decoded);
#endif

if(!result)
/* 7. Taking true branch */
*output = decoded;
/* 8. Null pointer value stored to 'decoded'	*/
return result;
/* 9. Returning zero (loaded from 'result'), which participates in a condition later */

...

#ifdef USE_IDN

if(!Curl_is_ASCII_name(host->name)) {
/* 1. Assuming condition is True */
char *decoded;

/* 2  Calling idn_decode */
CURLcode result = idn_decode(host->name, &decoded); 

/* 10. Returning from idn_decode*/
if(!result) 
/* 11. Taking True branch */
{
    if(!*decoded) 
    {
	/* 12.  Dereference of null pointer (loaded from variable 'decoded') */
    Curl_idn_free(decoded);
    return CURLE_URL_MALFORMAT;
	}

host->encalloc = decoded;
host->name = host->encalloc;
}
else
    return result;
}
#endif
return CURLE_OK;
}

Exploitation

This exploit would be very hard to craft since it would require some sort of EIP control to make the CPU execute a ROP chain then obtaining a shellcode or an LPE. This scenario is very unlikely, I’m not saying it’s not exploitable but it would be very hard to actually execute it.

Report and mitigation

I’ve reported the bug to the Curl team via the HackerOne platform. The following git pull is fixing the issue: https://github.com/curl/curl/pull/11898