用户
搜索
  • TA的每日心情
    擦汗
    2020-2-18 12:00
  • 签到天数: 347 天

    连续签到: 1 天

    [LV.8]以坛为家I

    版主

    我是表弟

    Rank: 7Rank: 7Rank: 7

    47

    主题

    334

    帖子

    955

    魔法币
    收听
    0
    粉丝
    17
    注册时间
    2015-11-20

    秦突出贡献春秋游侠核心白帽i春秋签约作者楚燕魏齐赵积极活跃奖春秋文阁春秋达人幽默灌水王

    0nise 版主 我是表弟 秦 突出贡献 春秋游侠 核心白帽 i春秋签约作者 楚 燕 魏 楼主
    发表于 2016-6-28 21:35:26 1621233
    本帖最后由 0nise 于 2018-4-9 09:27 编辑

    作者:0nise

    转载请注明出处!

    0x01科普  
    通过特殊的手法将普通的SQL语句,修改成恶意的SQL语句,最终达到入侵者的目的.(个人理解)
    0x02演练
    1.准备工具:SQL SERVER ,Visual Studio
       2.数据库脚本和.net代码(c#)
       3.SqlServer Profiler
       SQL
    脚本代码:
    [SQL] 纯文本查看 复制代码
    USE MASTER 
    GO
    --检索SQLTMP数据库是否存在
    IF EXISTS(SELECT * FROM SYSDATABASES WHERE name = 'SQLTMP')
    --删除SQLTMP数据库
    DROP DATABASE SQLTMP
    GO
    --创建数据库
    CREATE DATABASE SQLTMP
    GO
    --使用SQLTMP数据库
    USE SQLTMP
    GO
    -------------创建一张表用来验证SQL注入漏洞----------------
    --检索表是否存在
    IF EXISTS(SELECT * FROM SYSOBJECTS WHERE name = 'admin')
    --删除表
    DROP TABLE admin
    GO
    --创建表
    CREATE TABLE admin
    (
    id INT PRIMARY KEY IDENTITY(1,1),--设置主键
    name VARCHAR(20) NOT NULL,--用户名
    pass VARCHAR(20) NOT NULL--密码
    )
    -------------插入一条测试数据---------------------------
    INSERT INTO admin VALUES('admin','admin')
    
    --查询插入数据
    SELECT * FROM admin


    下面是一段验证用户名密码的C#代码:
    [C#] 纯文本查看 复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Data;
    using System.Data.SqlClient;
    
    namespace SQLTmp
    {
    class Program
    {
    //数据库连接字符串
    public static String strCon = "Data Source=.;Initial Catalog=SQLTMP;Integrated Security=True";
    //创建数据库连接对象
    static SqlConnection SqlCon = new SqlConnection(strCon);
    static void Main(string[] args)
    {
    Console.WriteLine("请输入用户名:");
    String name = Console.ReadLine();
    Console.WriteLine("请输入密码:");
    String pass = Console.ReadLine();
    try
    {
    Program p = new Program();
    //打开数据库连接
    p.Open();
    string sql = "SELECT COUNT(*) FROM admin WHERE name = '"+name+"'AND pass = '"+pass+"'";
    SqlCommand sqlcom = new SqlCommand(sql, SqlCon);
    int i = (int)sqlcom.ExecuteScalar();
    if (i > 0)
    {
    Console.WriteLine("登录成功!");
    }
    else
    {
    Console.WriteLine("登录失败!");
    }
    Console.ReadLine();
    }
    catch (Exception)
    {
    throw;
    }
    finally {
    //关闭数据库连接
    pass.Clone();
    }
    }
    //打开数据库连接
    public void Open()
    {
    //关闭状态下打开数据库连接
    if (SqlCon.State == ConnectionState.Closed)
    {
    SqlCon.Open();
    }
    //中断情况下打开数据库连接
    if (SqlCon.State == ConnectionState.Broken)
    {
    //关闭
    SqlCon.Close();
    SqlCon.Open();
    }
    }
    //关闭数据库连接
    public void Close() {
    if (SqlCon.State == ConnectionState.Open || SqlCon.State == ConnectionState.Broken)
    {
    SqlCon.Close();
    }
    }
    }
    }
    我们来测试一下

    输入正确的账号密码:

    [AppleScript] 纯文本查看 复制代码
    admin admin
    QQ截图20160628181113.png

    登录成功
    输入错误的账号密码:
    [AppleScript] 纯文本查看 复制代码
    test test

    QQ截图20160628181239.png

    登录失败
    [AppleScript] 纯文本查看 复制代码
    我们在用户名输入:' or 1=1--
    
    密码:123
    QQ截图20160628181414.png

    会发现也能登录成功!
    数据库中没有这个账号密码,还会登录成功?
    why?
    0x03剖析
    我们来剖析一下SQL语句的运行过程

    利用我的SQL语句跟踪工具(SQL Server Profiler)

    QQ截图20160628181948.png

    单击链接
    QQ截图20160628182102.png
    运行


    我们来看一下输正确的账号密码SQL语句的样子
    QQ截图20160628182254.png

    在我们的SQL Server中执行看看,有符合条件的数据
    QQ截图20160628182430.png


    我们再来看看输入错误的账号密码SQL语句的样子
    QQ截图20160628182627.png

    在我们的SQL Server中执行看看,没有符合条件的数据
    QQ截图20160628182833.png

    我们再来看看最后一次的输入的账号密码的SQL语句的样子
    QQ截图20160628183209.png



    我们来看看图片中的SQL语句我们的上面的SQL语句对比一下


    [SQL] 纯文本查看 复制代码
    SELECT COUNT(*) FROM SQLTMP WHERE name = 'admin' AND pass = 'admin';
    SELECT COUNT(*) FROM SQLTMP WHERE name = '' or 1=1 -- ' AND pass = '123';

    我们会发现我们输入的用户名变成了空,后面多了or 1=1 --'这又是为什么,什么原因导致的???
    到离这里我们就应该看看这一段代码:
    [C#] 纯文本查看 复制代码
    string sql = "SELECT COUNT(*) FROM admin WHERE name = '"+name+"'AND pass = '"+pass+"'";
    我们可以看出SQL是中的name和pass是变量是用户输入的账号和密码
    我们来看一下输入的用户名:' or 1=1 --
    那么用户如输入'的时候就会自动把name = ''闭合
    而 or 1=1 将where 条件永远成立
    --在SQL是注释的意思会将后面的SQL语句注释掉!!!
    那么我们就可以这么认为SQL语句到最后是这个样子的
    [SQL] 纯文本查看 复制代码
    SELECT COUNT(*) FROM SQLTMP WHERE name = '' or 1=1
    0x04防御
      有攻击的方式是会有防御的方式
    据我所知常用的有俩种方式:
      1.通过SQLParameter
    好处:预编译SQL语句防止被转意
    用法:
    [C#] 纯文本查看 复制代码
    string sql = "SELECT COUNT(*) FROM admin WHERE name = [url=home.php?mod=space&uid=116087]@name[/url] AND pass = @pass "; 
    //创建SParameter[]
    SqlParameter[] para = {
    new SqlParameter("@name",name),
    new SqlParameter("@pass",pass)
    };
    SqlCommand sqlcom = new SqlCommand(sql, SqlCon);
    //通过Parameters.addRange方法将para[]放进去
    sqlcom.Parameters.AddRange(para);
    int i = (int)sqlcom.ExecuteScalar();
    @符号代表的参数,我们把拼接的方式换成了参数的形式
    QQ截图20160628204216.png

    2.存储过程

          1.首先在数据库中创建存储过程
    2. 调用存储过程
    [C#] 纯文本查看 复制代码
    SqlParameter[] para = {
    new SqlParameter("@name",name),
    new SqlParameter("@pass",pass)
    };
    SqlCommand sqlcom = new SqlCommand();
    sqlcom.Connection = SqlCon;
    sqlcom.CommandText = "Login";
    //指定执行类型为存储过程
    sqlcom.CommandType = CommandType.StoredProcedure;
    sqlcom.Parameters.AddRange(para);
    int i = (int)sqlcom.ExecuteScalar();

    QQ截图20160628205549.png

      避免SQL注入

    评分

    参与人数 2魔法币 +300 收起 理由
    坏蛋 + 200 这种文章,值!
    中国Cold + 100

    查看全部评分

    本帖被以下淘专辑推荐:

    发表于 2016-6-28 21:43:13
    调了字体大小和颜色,没想到代码第一行也有,请大家忽视第一行字体代码         

    演示代码和SQL脚本在这!


    演示代码.rar (33 KB, 下载次数: 6)
    使用道具 举报 回复

    回帖是中华传统美德,嗯,一定要发扬光大
    使用道具 举报 回复
    发表于 2018-11-20 10:26:33

    支持一下~
    使用道具 举报 回复
    支持一下~
    使用道具 举报 回复
    发表于 2016-6-28 21:39:05
    沙发我的
    我是坏蛋的小号
    使用道具 举报 回复
    发表于 2016-6-28 21:45:26
    看不懂,能赐教吗
    就算你是憨豆你也有悲伤的时候。
    Even if you are the bean you also have sad when.
    使用道具 举报 回复
    坏蛋 管理员 欢迎大家来春秋群找我玩
    4#
    发表于 2016-6-28 21:50:38
    火钳刘明
    欢迎加入i春秋QQ群大家庭,每人只能任选加入一个群哦!
    投稿请加QQ:780876774。

    i春秋—楚:713729706
    i春秋—魏:687133802
    网安交流群:820783253
    使用道具 举报 回复
    发表于 2016-6-28 21:51:09
    SmiNe 发表于 2016-6-28 13:45
    看不懂,能赐教吗

    木问题      
    使用道具 举报 回复
    发表于 2016-6-29 07:17:38
    看看。。。。。。
    使用道具 举报 回复
    为什么程序员分不清万圣节和圣诞节?
    因为31 OCT == 25 DEC
    听说弄个女生的头像大家会喜欢我
    使用道具 举报 回复
    发表于 2016-6-30 06:19:22
    管理员的自以为是,往往就是我们下手的地方
    这杯酒我敬的是年少无知
    使用道具 举报 回复
    感谢分享
    使用道具 举报 回复
    66666666666,真是个个帖子都能给人刺激。
    使用道具 举报 回复
    发表于 2016-8-15 01:06:14
    嘿嘿 谢谢你的分享哦
    使用道具 举报 回复
    发表于 2016-10-5 16:35:55
    学习了
    使用道具 举报 回复
    发表于 2016-10-16 03:34:22
    看看   
    路虽远,行则必达。事虽难,做则必成。
    使用道具 举报 回复
    12下一页
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册