@@ -194,7 +194,10 @@ public function serialize($gc, $parameters)
194194 $ parameters = $ this ->process_parameters ($ gc , $ parameters );
195195 $ object = $ gc ->generate ($ parameters );
196196 $ object = $ this ->process_object ($ gc , $ object );
197- $ serialized = serialize ($ object );
197+ if (in_array ('session-encode ' , $ this ->options ))
198+ $ serialized = $ this ->session_encode ($ object );
199+ else
200+ $ serialized = serialize ($ object );
198201 $ serialized = $ this ->process_serialized ($ gc , $ serialized );
199202 return $ serialized ;
200203 }
@@ -367,6 +370,26 @@ function phar_generate($serialized)
367370 return $ phar ->generate ();
368371 }
369372
373+ #
374+ # Session Encode
375+ #
376+
377+ /**
378+ * Uses session_encode() instead of serialize().
379+ *
380+ * This is useful if you have an existing arbitrary file write primitive, but the
381+ * web root directory is non-writable. In such cases, it is possible to forge a
382+ * session file containing an unserialize() payload and trigger the chain by
383+ * visiting any webpage that invokes session_start().
384+ */
385+ function session_encode ($ object )
386+ {
387+ $ _SESSION ['_ ' ] = $ object ;
388+ $ serialized = session_encode ();
389+ session_destroy ();
390+ return $ serialized ;
391+ }
392+
370393 /**
371394 * Applies command line parameters and options to the gadget chain
372395 * parameters.
@@ -555,6 +578,10 @@ protected function help()
555578 $ this ->o (' -pf, --phar-filename <filename> ' );
556579 $ this ->o (' Defines the name of the file contained in the generated PHAR (default: test.txt) ' );
557580 $ this ->o ('' );
581+ $ this ->o ('SESSION ENCODE ' );
582+ $ this ->o (' -se, --session-encode ' );
583+ $ this ->o (' Uses session_encode() instead of serialize() to generate the payload. ' );
584+ $ this ->o ('' );
558585 $ this ->o ('ENHANCEMENTS ' );
559586 $ this ->o (' -f, --fast-destruct ' );
560587 $ this ->o (' Applies the fast-destruct technique, so that the object is destroyed ' );
@@ -649,6 +676,8 @@ function _parse_cmdline_arg(&$i, &$argv, &$parameters, &$options)
649676 'phar-jpeg ' => true ,
650677 'phar-prefix ' => true ,
651678 'phar-filename ' => true ,
679+ # Session Encode
680+ 'session-encode ' => false ,
652681 # Enhancements
653682 'fast-destruct ' => false ,
654683 'ascii-strings ' => false ,
@@ -676,7 +705,8 @@ function _parse_cmdline_arg(&$i, &$argv, &$parameters, &$options)
676705 'phar-filename ' => 'pf ' ,
677706 'new ' => 'N ' ,
678707 'ascii-strings ' => 'a ' ,
679- 'armor-strings ' => 'A '
708+ 'armor-strings ' => 'A ' ,
709+ 'session-encode ' => 'se ' ,
680710 ] + $ abbreviations ;
681711
682712 # If we are in this function, the argument starts with a dash, so we
@@ -783,6 +813,10 @@ protected function parse_cmdline($argv)
783813 $ this ->o ($ gc , 2 );
784814 $ this ->o ($ this ->_get_command_line_gc ($ gc ));
785815 return ;
816+ case 'session-encode ' :
817+ session_name ('phpggc ' );
818+ session_start ();
819+ break ;
786820 }
787821 }
788822
0 commit comments