What causes null byte values ​​to be rejected in a filter request?

When trying to simplify a PHP web application against null byte poisoning , I noticed that I had time actually sending null bytes in my request.

Using cURL, I was finally able to find a way to send null bytes to my requests, but noticed something very strange: no query parameters whose values ​​include null bytes ever reach my PHP application.

As a proof of concept, I created a file called test.php on my server:

 <?php echo json_encode($_GET), PHP_EOL; 

Here is the result of some requests for this script:

  > curl 'http: //localhost/test.php? foo = bar & baz = nu% 00ll'
 {"foo": "bar"}

 > curl 'http: //localhost/test.php? foo = bar & b% 00az = null'
 {"foo": "bar", "b": "null"}

The keys appear to be truncated in the zero byte, and if the value contains the zero byte, the parameter is completely removed from the request array.

Using print_r() gives similar results:

 <?php print_r($_GET); 
  > curl 'http: //localhost/test.php? foo = bar & baz = nu% 00ll'
 Array
 (
     [foo] => bar
 )

 > curl 'http: //localhost/test.php? foo = bar & b% 00az = null'
 Array
 (
     [foo] => bar
     [b] => null
 )

The same thing happens if I change my script and cURL requests to use $_POST .

Not that I complained, but I need to know why this is happening, so that I can make sure that each web server is configured correctly.

What causes this behavior?

  > php -v

 PHP 5.3.3 (cli) (built: Jul 3 2012 16:40:30) 
 Copyright (c) 1997-2010 The PHP Group
 Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
     with Suhosin v0.9.29, Copyright (c) 2007, by SektionEins GmbH
+7
source share
4 answers

Turn off Suhosin first. This will already take care of this.

While you turned it on, you cannot easily enter NUL bytes.

0
source

I point you to line 1010 from /main/SAPI.c in the PHP source code.

 SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC) { if (sapi_module.getenv) { char *value, *tmp = sapi_module.getenv(name, name_len TSRMLS_CC); if (tmp) { value = estrdup(tmp); } else { return NULL; } if (sapi_module.input_filter) { sapi_module.input_filter(PARSE_ENV, name, &value, strlen(value), NULL TSRMLS_CC); } return value; } return NULL; } 

estrdup () has #defined for _estrdup (), which is located on line 396 / Zend / zend_alloc.c and uses both standard library functions strlen () and memcpy () to execute its bets. Basically estrdup () will only copy to zero byte.

+3
source

In many languages, a null byte represents the end of a line. I would send the data as a hex code and re-interpret it on the server side. I do not think GET supports binary.

0
source

var_dump($your_url);
If it contains UGLY / NULL characters, try TRIM() .

0
source

All Articles