鱼C论坛

 找回密码
 立即注册
查看: 3062|回复: 1

SQL注入漏洞修复学习

[复制链接]
发表于 2011-5-2 01:53:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  照百度说法,SQL注入是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。其实就是就是提交精心构造的数据库语句,使其反馈一些有用的数据。说白了就是去欺骗数据库,假如只有web服务器的话,是没法进行SQL注入的。

  网上常用的注入手法有两种,一种是猜测,让数据库暴出用户名、密码等信息;另一种直接绕过认证,取得权限。相对应,要想修复此类漏洞,就必须禁止特殊数据的提交或将特殊提交的数据修改。

  下面是不同脚本语言下的防注入过滤代码,其实思想是一致的。

  1、    PHP防注入过滤代码
  /*************************
  说明:        判断传递的变量中是否含有非法字符 如$_POST、$_GET
  功能:        防注入
  使用方法:    将下列代码保存为ak,php,调用方式 在数据提交页加上include("ak.php");
  **************************/
  <?php
  function dowith_sql($str)
  //实现将特征码两边加.
  {
  $refuse_str="exec|and|or|select|update|from|where|order|by|*|delete|'|insert|into|values|create|table|
  database|set|char|asc|cast|declare|<script|script|iframe|3bomb|c.js|;";
  //定义防注入的字符
  $arr=explode("|",$refuse_str);
  //将$refuse_str中的值单独取出
  for($i=0;$i<count($arr);$i++)
  {
  $replace="[".$arr[$i]."]";
  $str=str_replace($arr[$i],$replace,$str);
  //在变量$str中搜索字符串$arr[$i],并将其替换为字符串[$replace]
  }
  return $str;
  }
  foreach ($_GET as $key=>$value)
  //遍历获GET方法获得的参数$_GET的值传给$key,并赋值给$value
  {
  $_GET[$key]=dowith_sql($value);
  //将$value中的特征码处理传个$_GET[$key]
  }
  foreach ($_POST as $key=>$value)
  {
  $_POST[$key]=dowith_sql($value);
  }
  ?>
  上面的防注入的方法只是防了GET与POST方法提交的数据,但是,WEB服务器读取数据的顺序是,先取GET中的数据,没有再去POST中的数据,没有还会再去COOKIES中的数据,上面的代码还没有防cookies注入。防cookies注入就比较简单了,cookies的id值一般只为阿拉伯数字,但是cookies注入必须得在id中构造代码,只要在获得参数UID后,对其进行过滤就可以了,代码如下:
  <?php
  if($_COOKIE['id']!=null) {
  //判断cookies不为空
  foreach ($_COOKIE['id'] as $key=>$id){
  //读取cookies中的值
  if (if_numeric($id)<0){
  echo "<script language=\\"javascript\\">alert(\\"请不要输入非法字符!\\");</script>" history.go(-1);</script>";
  }
  }
  ?>
  将上述代码保存为hk.php。
  所以在平时应用时,在网页上加上include("ak.php");与include("hk.php");

  2、    ASP防注入过滤代码
  <%
  '--------说明------------------
  '使用方法:  在需要防注的页面头部用 <!--#Include File="sql2.Asp"-->包含就可以了
  '友情提示:把代码复制到CONN.asp(数据库连接文件) 那么,只要包含了CONN的所有文件都防注了
  '-------- ------------------------
  Dim xf_Post,xf_Get,xf_In,xf_Inf,xf_Xh,xf_db,xf_dbstr
  '自定义需要过滤的字串,用 "|" 分隔
  xf_In = "'|;|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare"
  xf_Inf = split(xf_In,"|")
  If Request.Form<>"" Then
  For Each xf_Post In Request.Form
  For xf_Xh=0 To Ubound(xf_Inf)
  If Instr(LCase(Request.Form(xf_Post)),xf_Inf(xf_Xh))<>0 Then
  Response.Write "<Script Language=JavaScript>alert('请不要在参数中包含非法字符尝试注入');</Script>"
  Response.Write "非法操作!系统做了如下记录↓<br>"
  Response.Write "操作IP:"&Request.ServerVariables("REMOTE_ADDR")&"<br>"
  Response.Write "操作时间:"&Now&"<br>"
  Response.Write "操作页面:"&Request.ServerVariables("URL")&"<br>"
  Response.Write "提交方式:POST<br>"
  Response.Write "提交参数:"&xf_Post&"<br>"
  Response.Write "提交数据:"&Request.Form(xf_Post)
  Response.End
  End If
  Next
  Next
  End If
  If Request.QueryString<>"" Then
  For Each xf_Get In Request.QueryString
  For xf_Xh=0 To Ubound(xf_Inf)
  If Instr(LCase(Request.QueryString(xf_Get)),xf_Inf(xf_Xh))<>0 Then
  Response.Write "<Script Language=JavaScript>alert('请不要在参数中包含非法字符尝试注入');</Script>"
  Response.Write "非法操作!系统已经给你做了如下记录↓<br>"
  Response.Write "操作IP:"&Request.ServerVariables("REMOTE_ADDR")&"<br>"
  Response.Write "操作时间:"&Now&"<br>"
  Response.Write "操作页面:"&Request.ServerVariables("URL")&"<br>"
  Response.Write "提交方式:GET<br>"
  Response.Write "提交参数:"&xf_Get&"<br>"
  Response.Write "提交数据:"&Request.QueryString(xf_Get)
  Response.End
  End If
  Next
  Next
  End If
  %>
  同样,再将cookies防一下,代码加在数据提交页。
  if(Request.Cookies["uid"]!=null)
  {
  uid=Request.Cookies["uid"].value;
  isnumeric cooidesID = new isnumeric();
  //这是一个类
  if (cooidesID.reIsnumeric(ruid))
  //如果是数字就运行下面的
  {
  string str="select * from userTable where id="+uid;
  ...
  }
  }

  3、    JSP防注入过滤代码
  <script language="javascript">
  <!--
  var url = location.search;
  // 函数location.search作用是取?之后的参数值,取得 QueryString 部分
  var re=/^?(.*)(select%20|insert%20|delete%20from%20|count(|drop%20table|update%20truncate%20|asc(|mid(|char(|xp_cmdshell|exec%20master|net%20localgroup%20administrators|"|:|net%20user||%20or%20)(.*)$/gi;
  //定义特殊字符串
  var e = re.test(url);
  //test()字符串中是否有匹配正则表达式的子字符串。返回true或false。
  if(e) {
  alert("地址中含有非法字符~");
  location.href="error.asp";
  }
  //-->
  <script>

  当然,我们也可以定义过滤函数,直接应用到用户名、密码等提交的数据参数上,函数如下:
  function checkuseravoid(str){
  var inj_str="‘|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
  var sarray=new Array();
  sarray=inj_str.split('|');
  for (var i=0 ;i <inj_stra.length ;i++ ) {
  if (str.indexOf(inj_stra)>=0)
  return true;
  }
  return false;
  }

  4、    C#防注入过滤代码
  //这个例子里暂定为=号和号,可继续添加
  bool CheckParams(params object[] args)
  {
  string[] Lawlesses={"=",""};
  if(Lawlesses==null||Lawlesses.Length<=0)return true;

  //构造正则表达式,例:Lawlesses是=号和号,则正则表达式为 .*[=}].*
  //另外,由于我是想做通用而且容易修改的函数,所以多了一步由字符数组到正则表达式,实际使用中,直接写正则表达式亦可;

  string str_Regex=".*[";
  for(int i=0;i< Lawlesses.Length-1;i++)
  str_Regex+=Lawlesses+"|";
  str_Regex+=Lawlesses[Lawlesses.Length-1]+"].*";
  //
  foreach(object arg in args)
  {
  if(arg is string)
  //如果是字符串,直接检查
  {
  if(Regex.Matches(arg.ToString(),str_Regex).Count>0)
  return false;
  }
  else if(arg is ICollection)
  //如果是一个集合,则检查集合内元素是否字符串,是字符串,就进行检查
  {
  foreach(object obj in (ICollection)arg)
  {
  if(obj is string)
  {
  if(Regex.Matches(obj.ToString(),str_Regex).Count>0)
  return false;
  }
  }
  }
  }
  return true;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2015-11-28 12:36:54 | 显示全部楼层
:shock::smile:smile:smile:smile:smile:smile:smile:smile:smile:smile
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-15 16:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表