pdfresurrect 0.15 – Buffer Overflow

  • 作者: j0lama
    日期: 2019-07-26
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/47178/
  • # Exploit Title: pdfresurrect 0.15 Buffer Overflow
    # Date: 2019-07-26
    # Exploit Author: j0lama
    # Vendor Homepage: https://github.com/enferex/pdfresurrect
    # Software Link: https://github.com/enferex/pdfresurrect
    # Version: 0.15
    # Tested on: Ubuntu 18.04
    # CVE : CVE-2019-14267
    
    Description
    ===========
    
    PDFResurrect 0.15 has a buffer overflow via a crafted PDF file because
    data associated with startxref and %%EOF is mishandled.
    
    
    Additional Information
    ======================
    
    There is a buffer overflow in pdfresurrect 0.14 caused by a malicious
     crafted pdf file.
    
    In function pdf_load_xrefs at pdf.c file, it counts how many times the
    strings '%%EOF' appear in the pdf file. Then for each xref the code
    starts to rewind incrementing the pos_count variable until found a 'f'
    character (the last character of the 'startxref' string). Then these
    bytes between the 'f' and '%%EOF' will be read with the 'fread'
    function and copied to a 256 char buffer. The 'pos_count' variable
    tells 'freads' how many bytes has to copy. If malicious user crafted a
    pdf file with more that 256 bytes between '%%EOF' and the immediately
    previous 'f' then a buffer overflow will occur overwriting everything
    after the 'buf' buffer.
    
    In the code:
    int pdf_load_xrefs(FILE *fp, pdf_t *pdf)
    {
    inti, ver, is_linear;
    long pos, pos_count;
    char x, *c, buf[256];
    
    c = NULL;
    
    /* Count number of xrefs */
    pdf->n_xrefs = 0;
    fseek(fp, 0, SEEK_SET);
    while (get_next_eof(fp) >= 0)
    ++pdf->n_xrefs;
    
    if (!pdf->n_xrefs)
    return 0;
    
    /* Load in the start/end positions */
    fseek(fp, 0, SEEK_SET);
    pdf->xrefs = calloc(1, sizeof(xref_t) * pdf->n_xrefs);
    ver = 1;
    for (i=0; i<pdf->n_xrefs; i++)
    {
    /* Seek to %%EOF */
    if ((pos = get_next_eof(fp)) < 0)
    break;
    
    /* Set and increment the version */
    pdf->xrefs[i].version = ver++;
    
    /* Rewind until we find end of "startxref" */
    pos_count = 0;
    while (SAFE_F(fp, ((x = fgetc(fp)) != 'f'))) <== The loop will continue incrementing pos_count until find a 'f' char
    fseek(fp, pos - (++pos_count), SEEK_SET);
    
    /* Suck in end of "startxref" to start of %%EOF */
    memset(buf, 0, sizeof(buf));
    SAFE_E(fread(buf, 1, pos_count, fp), pos_count, <== If pos_count > 256 then a buffer overflow occur
     "Failed to read startxref.\n");
    c = buf;
    while (*c == ' ' || *c == '\n' || *c == '\r')
    ++c;
    
    /* xref start position */
    pdf->xrefs[i].start = atol(c);
    
    This is a crafted PDF that produces a buffer overflow: 
    
    http://www.mediafire.com/file/3540cyrl7o8p1rq/example_error.pdf/file
    https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47178.zip