相比于编写程序我觉得去寻找程序里的逻辑漏洞或者通过检测别人的软件去猜测别人的思路会使人提升的更加快。这一篇文章其实说来并没有什么技术含量,仅作为工具的一个使用方法和一些知识点的记忆,同理也不会对某些技术点讲的太细。
先来普及下SQL注入的基础知识:
所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击.
具体的介绍看这里:百度百科
图片若不清晰可以点击图片看大图。
目标:
SQL注入目标
一般来说只有这么一个登陆界面没有给任何其他界面的系统是很难被找出有什么问题的,你检测的东西少了自然很多东西都是无法进行的。在这个状态下可以尝试万能用户名/密码。然后对这个系统进行目录扫描,看是否有列目录这种低级错误。当这些东西都没办法生效时我们有最给力的办法——社工。
首先看系统名称就可以得知是内部使用,且内部人员都应该有帐号。俗话说——千里之堤毁于蚁穴,我们到网络中心走一趟就好了。记下老师的名字回来我们一个个的尝试。在使用拼音全拼、缩写等等办法后我们进入了这个系统。
社工后进入系统
到了这一步最重要的防御屏障我们已经绕过了,剩下的只剩下找注入点的活了~在一番寻找之后在 /operation/operationdanshow.do?id=2520 这里找到了注入点。
尝试在地址栏输入http://target.com/operation/operationdanshow.do?id=2520‘ 一定记住数字后的西文单引号!
SQL注入点
从图中我们就可以看到如果正常操作的情况下使用的数据库的表名。从报错提示可以知道程序是如何出错的。
这里摘抄一段,看SQL注入是如何产生的:
1、接收一个由用户提交的变量,假设变量为$variety:
$variety = $_POST['variety'];
2、接收的变量带入构造一个数据库查询语句:
$query = "SELECT * FROM wines WHERE variety='$variety'";
3、把构造好的语句提交给MySQL服务器查询,MySQL返回查询结果。
当由用户输入lagrein’ or 1=1#时,产生的结果将会完全不同。
代码已经猜测出来了,从注入点去做坏事就可以利用工具了~将注入点地址丢入工具并Load Cookie
将注入点丢入工具进行测试
测试完成,跑出结果是必须的。现在来对注入后的结果分析是否有对我们有利的数据。
注入工具测试结果
从结果来看,整个程序竟然使用了数据库的root用户,System User也是root用户,如果一旦被侵入后果不堪设想。
至于数据表也是可以获得的~
数据库数据
注入到这里检测也算是结束了,剩下的就是通知系统负责方修补漏洞了。
防止SQL注入的几种方式:
检查用户输入的类型,当用户输入的为数字时可以使用如下方式:
使用is_int()函数(或is_integer()或is_long()函数)
使用gettype()函数
使用intval()函数
使用settype()函数
检查用户输入字符串的长度使用strlen()函数。
检查日期或时间是否是有效的,可以使用strtotime()函数
对于一个已经存在的程序来说,可以写一个通用函数来过滤:
function safe($string)
{
return "'" . mysql_real_escape_string($string) . "'";
}
调用方式:
$variety = safe($_POST['variety']);
$query = "SELECT * FROM wines WHERE variety=" . $variety;
对于一个刚开始写的程序,应当设计的更安全一些,PHP5中,增加了MySQL支持,提供了mysqli扩展:
PHP手册地址:http://php.net/mysqli
-
<?php
-
// retrieve the user's input
-
$animalName = $_POST['animalName'];
-
// connect to the database
-
$connect = mysqli_connect('localhost', 'username', 'password', 'database');
-
if (!$connect)
-
exit('connection failed: ' . mysqli_connect_error());
-
// create a query statement resource
-
$stmt = mysqli_prepare($connect, "SELECT intelligence FROM animals WHERE name = ?");
-
if ($stmt) {
-
// bind the substitution to the statement
-
mysqli_stmt_bind_param($stmt, "s", $animalName);
-
// execute the statement
-
mysqli_stmt_execute($stmt);
-
// retrieve the result...
-
mysqli_stmt_bind_result($stmt, $intelligence);
-
// ...and display it
-
if (mysqli_stmt_fetch($stmt)) {
-
print "A $animalName has $intelligence intelligence.\n";
-
} else {
-
print 'Sorry, no records found.';
-
}
-
// clean up statement resource
-
mysqli_stmt_close($stmt);
-
}
-
mysqli_close($connect);
-
?>
mysqli扩展提供了所有的查询功能。
mysqli扩展也提供了面向对象的版本:
-
<?php
-
$animalName = $_POST['animalName'];
-
$mysqli = new mysqli('localhost', 'username', 'password', 'database');
-
if (!$mysqli)
-
exit('connection failed: ' . mysqli_connect_error());
-
$stmt = $mysqli->prepare("SELECT intelligence FROM animals WHERE name = ?");
-
if ($stmt) {
-
$stmt->bind_param("s", $animalName);
-
$stmt->execute();
-
$stmt->bind_result($intelligence);
-
if ($stmt->fetch()) {
-
print "A $animalName has $intelligence intelligence.\n";
-
} else {
-
print 'Sorry, no records found.';
-
}
-
$stmt->close();
-
}
-
$mysqli->close();
-
?>