这个问题是程序员容易忽略的,往往只是依靠gpc或addslashes函数对用户直接输入的数据进行处理,这样数据中的'"等都会被\转义,这样就能正确的执行sql语句,有效防止注入攻击了。但存入数据库的数据呢?在执行完sql语句存入数据库的是经过gpc处理前的原始数据,那么当程序再select出的就是受污染的数据了,如果把select出的数据再执行sql语句,那么就触发了sqlinj,如果直接写入缓存文件的话就有可能直接拿shell了:)
通过文本中转:
用户输入===>gpc\addslashes()===>写入文本文件===>include===>再次写入文本文件\执行sql语句
这个和通过数据库中转大致是一样的,对于写文件的操作如果处理不当是有可能被攻击者直接拿shell的,我们来看看php168的一个代码片段:
function login_logs($username,$password) {
global $timestamp,$onlineip;
$logdb[]="$username\t$password\t$timestamp\t$onlineip";
@include("adminlogin_logs.php");
$writefile="<?php \r\n";
$jj=0;
foreach($logdb AS $key=>$value) {
$jj++;
$writefile.="\$logdb[]=\"$value\";\r\n";
if($jj>200) {
break;
}
}
write_file("adminlogin_logs.php",$writefile);
}
function write_file($filename,$data,$method="rb+",$iflock=1){
@touch($filename);
$handle=@fopen($filename,$method);
if($iflock){
@flock($handle,LOCK_EX);
}
@fputs($handle,$data);
if($method=="rb+") @ftruncate($handle,strlen($data));
@fclose($handle);
@chmod($filename,0777);
if( is_writable($filename) ){
return 1;
}else{
return 0;
}
}
php168在登录后台时如果输入的用户名或密码有误就会执行这个login_logs函数把登录者的信息记录在adminlogin_logs.php,如果用户输入的$username的数据是“";eval($_POST[cmd]); //”,前面的"被闭合了,成功的写入了shell。但如果gpc为on的话,"会被转义成\",无法利用了。但注意这里会先包含adminlogin_logs.php,并循环数组把数据再次写入adminlogin_logs.php,要知道,这里的\仅仅是转义字符,所以include后$logdb依旧是受污染的原数据,再次写入文件时"就起作用了,成功写入了shell。