PHP防SQL注入类,可以过滤敏感参数
确定XP_CMDSHELL可执行情况
发现WEB虚拟目录
上传ASP,php,jsp木马;
得到管理员权限;
//PHP整站防注入程序,需要在公共文件中require_once本文件
//判断magic_quotes_gpc状态
if (@get_magic_quotes_gpc ()) {
$_GET = sec ( $_GET );
$_POST = sec ( $_POST );
$_COOKIE = sec ( $_COOKIE );
$_FILES = sec ( $_FILES );
}
$_SERVER = sec ( $_SERVER );
function sec(&$array) {
//如果是数组,遍历数组,递归调用
if (is_array ( $array )) {
foreach ( $array as $k => $v ) {
$array [$k] = sec ( $v );
}
} else if (is_string ( $array )) {
//使用addslashes函数来处理
$array = addslashes ( $array );
} else if (is_numeric ( $array )) {
$array = intval ( $array );
}
return $array;
}
1、整型参数的判断
当输入的参数YY为整型时,通常abc.asp中SQL语句原貌大致如下:
select * from 表名 where 字段=YY,所以可以用以下步骤测试SQL注入是否存在。
①HTTP://xxx.xxx.xxx/abc.asp?p=YY’(附加一个单引号),此时abc.ASP中的SQL语句变成了
select * from 表名 where 字段=YY’,abc.asp运行异常;
②HTTP://xxx.xxx.xxx/abc.asp?p=YY and 1=1, abc.asp运行正常,而且与HTTP://xxx.xxx.xxx/abc.asp?p=YY运行结果相同;
③HTTP://xxx.xxx.xxx/abc.asp?p=YY and 1=2, abc.asp运行异常;
如果以上三步全面满足,abc.asp中一定存在SQL注入漏洞。
function num_check($id) {
if (! $id) {
die ( '参数不能为空!' );
} //是否为空的判断
else if (inject_check ( $id )) {
die ( '非法参数' );
} //注入判断
else if (! is_numetic ( $id )) {
die ( '非法参数' );
}
//数字判断
$id = intval ( $id );
//整型化
return $id;
}
//字符过滤函数
function str_check($str) {
if (inject_check ( $str )) {
die ( '非法参数' );
}
//注入判断
$str = htmlspecialchars ( $str );
//转换html
return $str;
}
function search_check($str) {
$str = str_replace ( "_", "_", $str );
//把"_"过滤掉
$str = str_replace ( "%", "%", $str );
//把"%"过滤掉
$str = htmlspecialchars ( $str );
//转换html
return $str;
}
//表单过滤函数
function post_check($str, $min, $max) {
if (isset ( $min ) && strlen ( $str ) < $min) {
die ( '最少$min字节' );
} else if (isset ( $max ) && strlen ( $str ) > $max) {
die ( '最多$max字节' );
}
return stripslashes_array ( $str );
}
输入的参数YY为字符串时,通常abc.php中SQL语句原貌大致如下:
select * from 表名 where 字段='YY',所以可以用以下步骤测试SQL注入是否存在。
①HTTP://xxx.xxx.xxx/abc.php?p=YY’(附加一个单引号),此时abc.ASP中的SQL语句变成了
select * from 表名 where 字段=YY’,abc.asp运行异常;
②HTTP://xxx.xxx.xxx/abc.php?p=YY&;nb ... 39;1'='1', abc.php运行正常,而且与HTTP://xxx.xxx.xxx/abc.asp?p=YY运行结果相同;
③HTTP://xxx.xxx.xxx/abc.php?p=YY&;nb ... 39;1'='2', abc.php运行异常;
如果以上三步全面满足,abc.asp中一定存在SQL注入漏洞。
//防注入函数
function inject_check($sql_str) {
return eregi ( 'select|inert|update|delete|'|/*|*|../|./|UNION|into|load_file|outfile', $sql_str );
// 进行过滤,防注入
}
function stripslashes_array(&$array) {
if (is_array ( $array )) {
foreach ( $array as $k => $v ) {
$array [$k] = stripslashes_array ( $v );
}
} else if (is_string ( $array )) {
$array = stripslashes ( $array );
}
return $array;
}
//php 批量过滤post,get敏感数据
if (get_magic_quotes_gpc()) {
$_GET = stripslashes_array($_GET);
$_POST = stripslashes_array($_POST);
}
function stripslashes_array(&$array) {
while(list($key,$var) = each($array)) {
if ($key != 'argc' && $key != 'argv' && (strtoupper($key) != $key || ''.intval($key) == "$key")) {
if (is_string($var)) {
$array[$key] = stripslashes($var);
}
if (is_array($var)) {
$array[$key] = stripslashes_array($var);
}
}
}
return $array;
}
//过滤
function htmlencode($str){
if(empty($str)) return;
if($str=="") return $str;
$str=trim($str);
$str=str_replace("&","&",$str);
$str=str_replace(">",">",$str);
$str=str_replace("<","<",$str);
$str=str_replace(chr(32)," ",$str);
$str=str_replace(chr(9)," ",$str);
$str=str_replace(chr(9)," ",$str);
$str=str_replace(chr(34),"&",$str);
$str=str_replace(chr(39),"'",$str);
$str=str_replace(chr(13),"<br />",$str);
$str=str_replace("'","''",$str);
$str=str_replace("select","select",$str);
$str=str_replace("SCRIPT","SCRIPT",$str);
$str=str_replace("script","script",$str);
$str=str_replace("join","join",$str);
$str=str_replace("union","union",$str);
$str=str_replace("where","where",$str);
$str=str_replace("insert","insert",$str);
$str=str_replace("delete","delete",$str);
$str=str_replace("update","update",$str);
$str=str_replace("like","like",$str);
$str=str_replace("drop","drop",$str);
$str=str_replace("create","create",$str);
$str=str_replace("modify","modify",$str);
$str=str_replace("rename","rename",$str);
$str=str_replace("alter","alter",$str);
$str=str_replace("cast","cas",$str);
return $str;
}
//解码
function htmldecode($str){
if(empty($str)) return;
if($str=="") return $str;
$str=str_replace("select","select",$str);
$str=str_replace("join","join",$str);
$str=str_replace("union","union",$str);
$str=str_replace("where","where",$str);
$str=str_replace("insert","insert",$str);
$str=str_replace("delete","delete",$str);
$str=str_replace("update","update",$str);
$str=str_replace("like","like",$str);
$str=str_replace("drop","drop",$str);
$str=str_replace("create","create",$str);
$str=str_replace("modify","modify",$str);
$str=str_replace("rename","rename",$str);
$str=str_replace("alter","alter",$str);
$str=str_replace("cas","cast",$str);
$str=str_replace("&","&",$str);
$str=str_replace(">",">",$str);
$str=str_replace("<","<",$str);
$str=str_replace(" ",chr(32),$str);
$str=str_replace(" ",chr(9),$str);
$str=str_replace(" ",chr(9),$str);
$str=str_replace("&",chr(34),$str);
$str=str_replace("'",chr(39),$str);
$str=str_replace("<br />",chr(13),$str);
$str=str_replace("''","'",$str);
return $str;
}
// 函数:string_filter($string, $match_type=1)
// 功能:过滤非法内容
// 参数:
// $string 需要检查的字符串
// $match_type 匹配类型,1为精确匹配, 2为模糊匹配,默认为1
//
// 返回:有非法内容返回True,无非法内容返回False
// 其他:非法关键字列表保存在txt文件里, 分为普通非法关键字和严重非法关键字两个列表
// 作者:heiyeluren
// 时间:2006-1-18
//
//======================================================================
function lib_lawless_string_filter($string, $match_type=1)
{
//字符串空直接返回为非法
$string = trim($string);
if (empty($string))
{
return false;
}
//获取重要关键字列表和普通关键字列表
$common_file = "common_list.txt"; //通用过滤关键字列表
$signify_file = "signify_list.txt"; //重要过滤关键字列表
//如果任何列表文件不存在直接返回false,否则把两个文件列表读取到两个数组里
if (!file_exists($common_file) || !file_exists($signify_file))
{
return false;
}
$common_list = file($common_file);
$signify_list = file($signify_file);
//精确匹配
if ($match_type == 1)
{
$is_lawless = exact_match($string, $common_list);
}
//模糊匹配
if ($match_type == 2)
{
$is_lawless = blur_match($string, $common_list, $signify_list);
}
//判断检索结果数组中是否有数据,如果有,证明是非法的
if (is_array($is_lawless) && !empty($is_lawless))
{
return true;
}
else
{
return false;
}
}
//---------------------
// 精确匹配,为过滤服务
//---------------------
function exact_match($string, $common_list)
{
$string = trim($string);
$string = lib_replace_end_tag($string);
//检索普通过滤关键字列表
foreach($common_list as $block)
{
$block = trim($block);
if (preg_match("/^$string$/i", $block))
{
$blist[] = $block;
}
}
//判断有没有过滤内容在数组里
if (!empty($blist))
{
return array_unique($blist);
}
return false;
}
//----------------------
// 模糊匹配,为过滤服务
//----------------------
function blur_match($string, $common_list, $signify_list)
{
$string = trim($string);
$s_len = strlen($string);
$string = lib_replace_end_tag($string);
//检索普通过滤关键字列表
foreach($common_list as $block)
{
$block = trim($block);
if (preg_match("/^$string$/i", $block))
{
$blist[] = $block;
}
}
//检索严重过滤关键字列表
foreach($signify_list as $block)
{
$block = trim($block);
if ($s_len>=strlen($block) && preg_match("/$block/i", $string))
{
$blist[] = $block;
}
}
//判断有没有过滤内容在数组里
if (!empty($blist))
{
return array_unique($blist);
}
return false;
}
//--------------------------
// 替换HTML尾标签,为过滤服务
//--------------------------
function lib_replace_end_tag($str)
{
if (empty($str)) return false;
$str = htmlspecialchars($str);
$str = str_replace( '/', "", $str);
$str = str_replace("", "", $str);
$str = str_replace(">", "", $str);
$str = str_replace("<", "", $str);
$str = str_replace("<SCRIPT>", "", $str);
$str = str_replace("</SCRIPT>", "", $str);
$str = str_replace("<script>", "", $str);
$str = str_replace("</script>", "", $str);
$str=str_replace("select","select",$str);
$str=str_replace("join","join",$str);
$str=str_replace("union","union",$str);
$str=str_replace("where","where",$str);
$str=str_replace("insert","insert",$str);
$str=str_replace("delete","delete",$str);
$str=str_replace("update","update",$str);
$str=str_replace("like","like",$str);
$str=str_replace("drop","drop",$str);
$str=str_replace("create","create",$str);
$str=str_replace("modify","modify",$str);
$str=str_replace("rename","rename",$str);
$str=str_replace("alter","alter",$str);
$str=str_replace("cas","cast",$str);
$str=str_replace("&","&",$str);
$str=str_replace(">",">",$str);
$str=str_replace("<","<",$str);
$str=str_replace(" ",chr(32),$str);
$str=str_replace(" ",chr(9),$str);
$str=str_replace(" ",chr(9),$str);
$str=str_replace("&",chr(34),$str);
$str=str_replace("'",chr(39),$str);
$str=str_replace("<br />",chr(13),$str);
$str=str_replace("''","'",$str);
$str=str_replace("css","'",$str);
$str=str_replace("CSS","'",$str);
return $str;
//HTML标签,可以作为扩展过滤
/*
$tags = array("/html", "/head", "/body", "/div", "/span", "/DOCTYPE", "/title", "/link", "/meta", "/style", "/p", "/h1,", "/h2,", "/h3,", "/h4,", "/h5,", "/h6", "/strong", "/em", "/abbr", "/acronym", "/address", "/bdo", "/blockquote", "/cite", "/q", "/code", "/ins", "/del", "/dfn", "/kbd", "/pre", "/samp", "/var", "/br", "/a", "/img", "/area", "/map", "/object", "/param", "/ul", "/ol", "/li", "/dl", "/dt", "/dd", "/table", "/tr", "/td", "/th", "/tbody", "/thead", "/tfoot", "/col", "/colgroup", "/caption", "/form", "/input", "/textarea", "/select", "/option", "/optgroup", "/button", "/label", "/fieldset", "/legend", "/script", "/noscript", "/b", "/i", "/tt", "/sub", "/sup", "/big", "/small", "/hr" );
*/
}
引用是直接这样:
$xxx = htmlspecialchars($_POST['xxx']);
或者
$xxx = htmlspecialchars($_GET['xxx']);
最近无聊没事做,开始做一些php的分享,代码都比较简单,但比较实用。
这是四年前写的,几行代码实现四位随机数字的php验证码功能。
代码如下 | 复制代码 |
session_start(); if(rand(0,9)%2==0){ } |
具体方法
一、PHP防止站外提交数据的方法
代码如下 | 复制代码 |
<? $servername=$HTTP_SERVER_VARS['SERVER_NAME']; $sub_from=$HTTP_SERVER_VARS["HTTP_REFERER"]; $sub_len=strlen($servername); $checkfrom=substr($sub_from,7,$sub_len); if($checkfrom!=$servername){ echo("警告!你正在从外部提交数据!!请立即终止!!"); exit; } ?> |
把以上代码放到需要防止外部提交数据的页面中,如果是直接输入网址或者是从外部网部链接到本页,则显示:警告!你正在从外部提交数据!!请立即终止!!;如果系从本站链接或通过表单提交到该页,则无此提示。这样做主要是为了防止一些伪造表单向站内提交数据 。
上面的代码通过curl可直接跳过了,我们可以参考dz论坛登录的一种做法
处理远程表单提交更好的方式是,根据一个惟一的字符串或时间戳生成一个令牌,并将这个令牌放在会话变量和表单中。提交表单之后,检查两个令牌是否匹配。如果不匹配,就知道有人试图从表单的远程副本发送数据。
要创建随机的令牌,可以使用 PHP 内置的 md5()、uniqid() 和 rand() 函数,如下所示
代码如下 | 复制代码 |
<SPAN style="FONT-SIZE: small"><?php session_start(); if ($_POST['submit'] == "go"){ //check token if ($_POST['token'] == $_SESSION['token']){ //strip_tags $name = strip_tags($_POST['name']); $name = substr($name,0,40); //clean out any potential hexadecimal characters $name = cleanHex($name); //continue processing.... }else{ //stop all processing! remote form posting attempt! } } $token = md5(uniqid(rand(), true)); $_SESSION['token']= $token; function cleanHex($input){ $clean = preg_replace("![][xX]([A-Fa-f0-9]{1,3})!", "",$input); return $clean; } ?> <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post"> <p><label for="name">Name</label> <input type="text" name="name" id="name" size="20" maxlength="40"/></p> <input type="hidden" name="token" value="<?php echo $token;?>"/> <p><input type="submit" name="submit" value="go"/></p> </form> </SPAN> |
没事把以前写的asp写出来
ASP防止外部提交数据的方法
代码如下 | 复制代码 |
<% Server_v1=Cstr(Request.ServerVariables("HTTP_REFERER")) Server_v2=Cstr(Request.ServerVariables("SERVER_NAME")) If mid(server_v1,8,len(server_v2))<>server_v2 then Response.write "警告!你正在从外部提交数据!!请立即终止!!" Response.End End if %> |
简单点来说就是你不想让别人知道的信息,比如说数据库的地址,用户名,密码等等,此类信息往往知道的人越少越好。
通常,PHP程序里的配置文件大致如下所示:
代码如下 | 复制代码 |
<?php |
有时候出于某些原因,比如说代码审查,亦或者合作开发等等,第三方需要获取代码版本仓库的读权限,一旦授权,数据库的地址,用户名,密码等敏感信息就暴露了。当然也可以不在代码版本仓库里保存配置文件,取而代之是撰写文档进行说明,但我不喜欢这样的方法,因为如此一来,代码本身是不完整的。
如何解决此类问题呢?最直接的方法是把敏感信息从代码中拿掉,换个地方保存。具体保存到哪里呢?有很多选择,比如说通过nginx的fastcgi_param来设置:
代码如下 | 复制代码 |
fastcgi_param DATABASE_HOST 192.168.0.1; |
经过这样的映射后,我们的代码就不会直接包含敏感信息了:
代码如下 | 复制代码 |
<?php |
此外,还可以通过php-fpm的env指令来设置:
代码如下 | 复制代码 |
env[DATABASE_HOST] = 192.168.0.1 |
需要说明的一点是,这个设置必须放在主配置文件php-fpm.conf里,不能放到include指令设置的子配置文件里,否则会报错:「Array are not allowed in the global section」;另外一点,虽然是通过env设置的,但结果还是在$_SERVER里,而不是$_ENV。
说明: @Laruence 提醒了我,如果配置信息通过nginx的fastcgi_param来设置的话,当nginx和php交互时,会带来大量的数据传输(如此看来通过php-fpm的env来设置相对更有优势),鸟哥建议使用独立的扩展来搞定,比如「hidef」。
通过nginx和php-fpm配置文件来解决问题的话,有一个缺点,仅对Web有效,如果通过命令行来运行,那么无法在$_SERVER里获取相关信息,不过这不算什么难事儿,只要写个公共的脚本正则匹配一下nginx或者php-fpm的配置文件,就可以动态的把这些信息映射到命令行环境,具体怎么搞就留给大家自己操作吧。
代码干净了,剩下的工作就是如何确保nginx或php-fpm配置文件的安全了,不过和代码比起来,nginx或php-fpm配置文件并不需要很多人有权限,所以相对更容易管理
还有一个重要的函数phpinfo()这个大家一定要注意了,如能正常显示phpinfo函数我们可
详情
PHPInfo提供了以下一些信息:
*PHP 版本 (包括build版本在内的精确版本信息)
*系统版本信息(包括build版本在内的精确版本信息)
*扩展目录(PHP所在目录)
*SMTP服务器信息
*Sendmail路径(如果Sendmail安装了的话)
*Posix版本信息
*数据库
*ODBC 设置(包括的路径,数据库名,默认的密码等等)
*MySQL 客户端的版本信息(包括build版本在内的精确版本信息)
*Oracle版本信息和库的路径
*所在位置的实际路径
*Web 服务器
*IIS 版本信息
*Apache 版本信息
*如果在Win32下运行:
*计算机名
*Windows目录的位置
*路径(能用来泄漏已安装的软件信息)
例子:
访问一个类似于下面的URL:
http://www.example.com/PHP/phpinfo.php
虽然说md5的密文是有限的,不过其数量为6.3340286662973277706162286946812e+49 ,如果对这个数字没感觉,你可以想象一下一亿的五次方再乘个几千万就差不多了。。。。。
以前接触过不少程序(当菜鸟黑客的那段时光……),大部分程序加密方式都是“md5”,而且是纯加密,本来这也没有错,以为md5算法毕竟没有被破解,但是随着特征字符串的收集,使用纯md5加密已经越来越危险。
自己写程序一般习惯加上特征字符串再MD5,自以为万无一失,但是今天发现cmd5居然可以破解这种加密方式,当然前提是要知道特征字符串,虽然我的更为复杂,不过出于防范心理,还是对加密函数进行了复杂化。
代码如下 | 复制代码 |
function md123($sstr) { $md_asc=”"; $mds=md5(“qwEqw”.$sstr.”2ddsdf”); $mds=md5(“rtrTtyr”.$mds.”zcv34r”); for($i=1;$i< strlen($mds);$i++){ $md_asc.=168/ord(substr($mds,$i,1)); } return md5($md_asc); } |
这样通过随即字符串和ascii ,使密码安全性得到进一步提高,在通过ord的时候,一个简单的1已经被转换成了一下字符:
1.73195876288662.94736842105261.66336633663373.1111
1111111113.23076923076923.16981132075471.731958762
88661.683.42857142857142.94736842105261.681.681.6470
5882352943.11111111111111.66336633663372.94736842
105263.42857142857141.66336633663373.1698113207547
3.16981132075473.11111111111111.69696969696971.681.7
1428571428573.16981132075471.71428571428573.294117
64705881.681.64705882352941.69696969696971.64705882
352946ccc2eceada95b64bc7f55c07c2a6af6
这样再进行MD5加密,就安全了,如果这样还被破解了,那就用面条上吊吧
相关文章
- PHPEMS(PHP Exam Management System)在线模拟考试系统基于PHP+Mysql开发,主要用于搭建模拟考试平台,支持多种题型和展现方式,是国内首款支持题冒题和自动评分与教师评分相...2016-11-25
- SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作 标准注入语句1.判...2016-11-25
- 防止SQL注入是我们程序开发人员必须要做的事情了,今天我们就来看一篇关于PHP防止SQL注入的例子了,具体的实现防过滤语句可以参考下面来看看吧。 使用prepared以及参...2016-11-25
- 这篇文章主要介绍了cmd下过滤文件名称的两种方法,需要的朋友可以参考下...2020-06-30
- 本文主要介绍AngularJS 依赖注入的知识,这里整理了相关的基础知识,并附示例代码和实现效果图,有兴趣的小伙伴可以参考下...2016-08-24
- SQL注入攻击是黑客攻击网站最常用的手段。如果你的站点没有使用严格的用户输入检验,那么常容易遭到SQL注入攻击。SQL注入攻击通常通过给站点数据库提交不良的数据或...2016-11-25
- 这篇文章主要介绍了PHP正则表达式过滤html标签属性的相关内容,实用性非常,感兴趣的朋友参考下吧...2016-05-06
- 这篇文章主要介绍了Spring boot 无法注入service问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-09
- 这篇文章主要介绍了JavaScript过滤字符串中的中文与空格方法汇总 的相关资料,需要的朋友可以参考下...2016-03-09
- 这篇文章主要介绍了Spring 配置文件字段注入到List、Map,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-19
- 方法一过滤html自定义函数 代码如下 复制代码 function ihtmlspecialchars($string) { if(is_array($string)) { foreach($string as $key =>...2016-11-25
- 本文章以自己的一些经验来告诉你黑客朋友们会怎么利用你数据库的sql漏洞来把你的数据库下载哦,有需要的同这参考一下本文章。 在数据库中建立一张表: 代码...2016-11-25
- 这篇文章主要给大家总结介绍了关于.Net防sql注入的几种方法,文中通过示例代码介绍的非常详细,对大家学习或者使用.Net具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2021-09-22
- C# 撒列实现关键字过滤的实例,需要的朋友可以参考一下...2020-06-25
- 这篇文章主要介绍了ASP.NET防止SQL注入的方法,结合具体实例形式分析了asp.net基于字符串过滤实现防止SQL注入的相关操作技巧,需要的朋友可以参考下...2021-09-22
- 在 SpringBoot中,提供了一种新的属性注入方式,支持各种java基本数据类型及复杂类型的注入,下面这篇文章主要给大家介绍了关于SpringBoot属性注入的多种方式,需要的朋友可以参考下...2021-10-30
spring中向一个单例bean中注入非单例bean的方法详解
Spring是先将Bean对象实例化之后,再设置对象属性,所以会先调用他的无参构造函数实例化,每个对象存在一个map中,当遇到依赖,就去map中调用对应的单例对象,这篇文章主要给大家介绍了关于spring中向一个单例bean中注入非单例bean的相关资料,需要的朋友可以参考下...2021-07-19- 这篇文章主要介绍了C#实现简单过滤非法字符的方法,涉及C#针对字符串遍历与判断的相关技巧,非常简单实用,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了Python过滤序列元素的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-31
- 这篇文章我们设计了一些复杂的概念,因为要对ASP.NET Core的启动及运行原理、配置文件的加载过程进行分析,依赖注入,控制反转等概念的讲解等...2021-09-22