0x01 考点关键词

信息泄露、文件上传漏洞

0x02 分析

重复注册账号推荐人填同一个账号可以刷积分,到100积分解锁文件上传点。

robots.txt 泄露 config.txt 得到源码:

<?php

class master
{
	private $path;
	private $name;

	function __construct()
	{

	}

	function stream_open($path)
	{
		if(!preg_match('/(.*)\/(.*)$/s',$path,$array,0,9))
			return 1;
		$a=$array[1];
		parse_str($array[2],$array);

		if(isset($array['path']))
		{
			$this->path=$array['path'];
		}
		else
			return 1;
		if(isset($array['name']))
		{
			$this->name=$array['name'];
		}
		else
			return 1;

		if($a==='upload')
		{
			return $this->upload($this->path,$this->name);
		}
		elseif($a==='search')
		{
			return $this->search($this->path,$this->name);
		}
		else
			return 1;
	}
	function upload($path,$name)
	{
		if(!preg_match('/^uploads\/[a-z]{10}\/$/is',$path)||empty($_FILES[$name]['tmp_name']))
			return 1;

		$filename=$_FILES[$name]['name'];
		echo $filename;

		$file=file_get_contents($_FILES[$name]['tmp_name']);

		$file=str_replace('<','!',$file);
		$file=str_replace(urldecode('%03'),'!',$file);
		$file=str_replace('"','!',$file);
		$file=str_replace("'",'!',$file);
		$file=str_replace('.','!',$file);
		if(preg_match('/file:|http|pre|etc/is',$file))
		{
			echo 'illegalbbbbbb!';
			return 1;
		}

		file_put_contents($path.$filename,$file);
		file_put_contents($path.'user.jpg',$file);


		echo 'upload success!';
		return 1;
	}
	function search($path,$name)
	{
		if(!is_dir($path))
		{
			echo 'illegal!';
			return 1;
		}
		$files=scandir($path);
		echo '</br>';
		foreach($files as $k=>$v)
		{
			if(str_ireplace($name,'',$v)!==$v)
			{
				echo $v.'</br>';
			}
		}

		return 1;
	}

	function stream_eof()
	{
		return true;
	}
	function stream_read()
	{
		return '';
	}
	function stream_stat()
	{
		return '';
	}

}

stream_wrapper_unregister('php');
stream_wrapper_unregister('phar');
stream_wrapper_unregister('zip');
stream_wrapper_register('master','master');

?>

定义了一个类master,其中有几个方法:

stream_open()
对path的传参和name的传参从字符串到变量,做了一个方法对应。

upload()
对上传的文件内容中存在 < " ’ . 全部替换为 !
然后如果匹配到 /file: http pre etc/is 就会报错
最后输出文件内容和文件路径.

search()
判断了是否存在path路径,对当前目录进行遍历,存在和path路径,对当前目录进行遍历,存在和name相同的文件或者目录替换为空
并列出当前目录。

上传一个一句话木马上去。找到图片地址,并发现存在目录遍历:

可以发现我们的<被替换成了!,这里在源码里我们也看了。对上传文件的内容进行了一些敏感字符的替换。
可以上传.htaccess文件,那么就可以用.htaccess修改配置文件。

使用了在源码中唯一开启的伪协议 master:// 进行修改:

php_value auto_append_file master://search/path=%2fhome%2f&name=flag

把这个 .htaccess 文件上传上去的话,上传一个php文件然后访问这个php文件就可以执行命令。