OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: Sam Steinmeyer (SamSteinmeyerwinn-dixie.com)
Date: Tue Jan 08 2002 - 13:04:43 CST

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

    I had an experience with content-length. I had a task to add a line of code
    to all http request for a site. In order to accomplish this task I had to
    modify the content-length to accommodate the new size of the file being
    returned. Here is a snippet of code:

    DWORD CAutoIncludeFilter::OnSendRawData(CHttpFilterContext* pCtxt,
            PHTTP_FILTER_RAW_DATA pRawData)
    {
        char szBuff[] = "<link rel=stylesheet type=text/css
    href=http://info_d/_include/CSS/main.css>";
            char buff[10];
            DWORD dwLen,cbTemp=0;
            int Temp,shift=0;

            //Get usable pointer
            LPTSTR pstrIn;
            pstrIn = (LPTSTR) pRawData->pvInData;
            dwLen = strlen(pstrIn);

            //Loop and don't go past buffer of size pRawData->pvInData
            while (cbTemp < dwLen && pCtxt->m_pFC->pFilterContext == NULL)
            {
                    //Look for Content-Length
                    if (pstrIn[cbTemp] == 'C' && pstrIn[cbTemp+1] == 'o' &&
                            pstrIn[cbTemp+2] == 'n' && pstrIn[cbTemp+3] == 't'
    &&
                            pstrIn[cbTemp+4] == 'e' && pstrIn[cbTemp+5] == 'n'
    &&
                            pstrIn[cbTemp+6] == 't' && pstrIn[cbTemp+7] == '-'
    &&
                            pstrIn[cbTemp+8] == 'L' && pstrIn[cbTemp+9] == 'e'
    &&
                            pstrIn[cbTemp+10] == 'n' && pstrIn[cbTemp+11] == 'g'
    &&
                            pstrIn[cbTemp+12] == 't' && pstrIn[cbTemp+13] == 'h'
    &&
                            pstrIn[cbTemp+14] == ':' && pstrIn[cbTemp+15] == ' '
                            )
                    {
                            
                            cbTemp = cbTemp + 16;

                            //look for the size
                            while (pstrIn[cbTemp] != '\n')
                            {
                                    buff[shift] = pstrIn[cbTemp];
                                    shift++;
                                    cbTemp++;
                            }//while

                            //If it is simple HTML then just set the flag
                            if (pstrIn[cbTemp+2] == '\n')
                            {
                            pCtxt->m_pFC->pFilterContext = (VOID*) 2;
                                    break;
                            }

                            //Keep content length update
                            Temp = atoi(buff) + strlen(szBuff);
                            itoa(Temp,buff,10);

                            //Carefull, keep your place. Don't want to over
    run.. :)
                            while (shift > -1)
                            {
                                    pstrIn[cbTemp] = buff[shift];
                                    shift--;
                                    cbTemp--;
                            }//while

                            //got what I needed so set flag and get next chunk
    of Data
                            pCtxt->m_pFC->pFilterContext = (VOID*) 2;
                            break;

                    }//if
                    cbTemp++;
            }//while

            //Send out the Buffer.....
            if (pCtxt->m_pFC->pFilterContext != NULL)
            {
                            dwLen = strlen(szBuff);
                            pCtxt->WriteClient(szBuff, &dwLen,0);
                            pCtxt->m_pFC->pFilterContext = NULL;
       }//if

            return SF_STATUS_REQ_NEXT_NOTIFICATION;
    }

    Hope it helps,

    Thanks,
    Sam
    -----Original Message-----
    From: Bob at firstcodings [mailto:bobfirstcodings.net]
    Sent: Tuesday, December 18, 2001 2:25 PM
    To: focus-mslists.securityfocus.com
    Subject: ISAPI answer to "Microsoft IIS False Content-Length Field DoS
    Vulnerability" ?

     Hi.

    Here is my OnPreprocHeaders callback :

    DWORD CBlockHeaderFilter::OnPreprocHeaders(CHttpFilterContext* pCtxt,
     PHTTP_FILTER_PREPROC_HEADERS pHeaderInfo)
    {
     pCtxt->AddResponseHeaders("X-CustomDebug: OnPreprocHeaders\r\n", 0);
     pHeaderInfo->SetHeader( pCtxt->m_pFC, "Content-Length:", "");
     return SF_STATUS_REQ_NEXT_NOTIFICATION;
    }

    This piece of code always remove the "Content-Length" header; I think it
    works (tested on my box), but I don't know how IIS reacts when there is no
    more "Content-Length" client header. What is it used for ?
    Could someone tell me ?

    By the way, the following callback seems to reproduce the exploit
    (http://www.securityfocus.com/cgi-bin/vulns-item.pl?section=exploit&id=3667)
    :

    DWORD CBlockHeaderFilter::OnPreprocHeaders(CHttpFilterContext* pCtxt,
     PHTTP_FILTER_PREPROC_HEADERS pHeaderInfo)
    {
     pHeaderInfo->SetHeader( pCtxt->m_pFC, "Content-Length:", "5300643");
     return SF_STATUS_REQ_NEXT_NOTIFICATION;
    }

    Bob.