Error message

You are browsing documentation for drupal 7.x, which is not supported anymore. Read the updated version of this page for drupal 11.x (the latest version).

function BootstrapDrupalCacheArrayTestCase::testGadgetChainDrupal7RCE1

Simulate unsafe deserialization of payload prepared by the phpggc project.

See also

https://github.com/ambionics/phpggc/pull/28

File

modules/simpletest/tests/bootstrap.test, line 926

Class

BootstrapDrupalCacheArrayTestCase
Tests DrupalCacheArray functionality.

Code

public function testGadgetChainDrupal7RCE1() {
 // phpggc -s Drupal7/RCE1 phpinfo 2
 $payload = 'O:11:"SchemaCache":4:{s:6:"%00*%00cid"%3Bs:14:"form_DrupalRCE"%3Bs:6:"%00*%00bin"%3Bs:10:"cache_form"%3Bs:16:"%00*%00keysToPersist"%3Ba:3:{s:8:"#form_id"%3Bb:1%3Bs:8:"#process"%3Bb:1%3Bs:9:"#attached"%3Bb:1%3B}s:10:"%00*%00storage"%3Ba:3:{s:8:"#form_id"%3Bs:9:"DrupalRCE"%3Bs:8:"#process"%3Ba:1:{i:0%3Bs:23:"drupal_process_attached"%3B}s:9:"#attached"%3Ba:1:{s:7:"phpinfo"%3Ba:1:{i:0%3Ba:1:{i:0%3Bs:1:"2"%3B}}}}}';
 $object = unserialize (urldecode ($payload));
 // The object then needs to be destructed.
 unset($object);
 // If the exploit was successful, there should now be a row in cache_form.
 $payload2 = db_query_range ('SELECT data FROM {cache_form} WHERE cid LIKE :cid', 0, 1, array(
 ':cid' => 'form_DrupalRCE',
 ))->fetchField ();
 $this->assertFalse (is_string ($payload2) && strpos ($payload2, 'phpinfo') !== FALSE, 'Second stage payload was not written to cache_form.');
 // The final exploit is executed via the ajax system, but is not a
 // sufficiently valid ajax form submission to use drupalPost for testing.
 $headers = array(
 'Content-Type: application/x-www-form-urlencoded',
 );
 $curl_options = array(
 CURLOPT_URL => url ('system/ajax', array(
 'absolute' => TRUE,
 )),
 CURLOPT_POST => TRUE,
 CURLOPT_POSTFIELDS => 'form_build_id=DrupalRCE',
 CURLOPT_HTTPHEADER => $headers,
 );
 // The second stage payload causes several PHP warnings / notices if it is
 // there in cache_form.
 $content = $this->curlExec ($curl_options);
 $this->assertFalse (strpos ($content, 'Rasmus Lerdorf') !== FALSE, 'Remote Code Execution was not successful.');
 // Now opt-out of the cache_form protection.
 variable_set ('drupal_cache_array_persist_cache_form', TRUE);
 $object = unserialize (urldecode ($payload));
 // The object then needs to be destructed.
 unset($object);
 // If the exploit was successful, there should now be a row in cache_form.
 $payload2 = db_query_range ('SELECT data FROM {cache_form} WHERE cid LIKE :cid', 0, 1, array(
 ':cid' => 'form_DrupalRCE',
 ))->fetchField ();
 $this->assertTrue (is_string ($payload2) && strpos ($payload2, 'phpinfo') !== FALSE, 'DrupalCacheArray persisted data to cache_form.');
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.