• 从c#角度看万能密码SQL注入漏洞


        以前学习渗透时,虽然也玩过万能密码SQL注入漏洞登陆网站后台,但仅仅会用,并不理解其原理。

    今天学习c#数据库这一块,正好学到了这方面的知识,才明白原来是怎么回事。

    众所周知的万能密码SQL注入漏洞,大家相信很熟悉了。

    不懂得简单了解下,懂的大牛直接飘过即可。

    *****************************************************************************

    当我们用御剑之类的扫描器扫描到某些有这个万能密码SQL注入的漏洞网站后台后,

    打开网页,输入下列内容,无需知道账号密码也可以登录后台。

    http://www.*******.com/admin/admin_login.asp

    账号:djlfjdslajdfj(随意输入) 密码:
    1‘or’1’=‘1

    那么为什么呢?

    其实原理很简单:

    我们先看一条普通的数据库查询语句:

    1.普通的直接在数据库里进行查询语句:

    select * from T_users where username='root' and password='root';

    2.在网站开发中有些人是这样做的,T_users是表名,username是数据库中字段名,

    name和pwd是变量。

    "select  * form T_users where username='  "+ name +"   "+" and password=' "+ pwd +" ' ";

    如果变量name赋值为root,pwd变量赋值为root的话,这根本不会有什么问题,和上面一模一样。

    即等价于"select * from T_users where username= 'root' and password= 'root' "

    3.但是如果变量name赋值:随意输入,而pwd被赋值 1 or 1=1 ,

    那么整个语句就变成了这个样子:

    "select from T_users where username=adsfafsf' and password='1 or 1=1"

    可以看出,此时整个查询语句返回值始终为true.

    模拟测试数据库如下:

    模拟万能密码SQL注入漏洞源码如下:

    using System;
    using System.Data.SqlClient;
    namespace 第一个数据库程序
    {
        class Program
        {
            static void Main(string[] args)
            {
                //解决数据库添加不进去数据,两个mdf问题冲突问题代码,即.
                /***************************************************/
         
                string dataDir = AppDomain.CurrentDomain.BaseDirectory;
                if (dataDir.EndsWith(@"inDebug")
                    || dataDir.EndsWith(@"inRelease"))
                {
                    dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
                    AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
                }
                /************************************************/
    
                Console.WriteLine("请输入用户名:");
                string user = Console.ReadLine();
                Console.WriteLine("请输入密码:");
                string pwd = Console.ReadLine();
          
                //与数据库建立连接
                using (SqlConnection conn = new SqlConnection(@"Data Source=.SQLEXPRESS;AttachDbFilename=|DataDirectory|Database1.mdf;Integrated Security=True;User Instance=True"))
                {
                    conn.Open();//打开连接
    
                    //创建sql语句命令
                    using (SqlCommand cmd = conn.CreateCommand())
                    {
                        //SQL语句查询命令
                        cmd.CommandText = " select * from [T_users] where username='"+ user + "'" + "and password='" + pwd + "'" ;
    
                        int i = Convert.ToInt32(cmd.ExecuteScalar());//返回第一行第一列的值
                        if (i > 0)
                        {
                            Console.WriteLine("登陆成功!");
                        }
                        else 
                        {
                            Console.WriteLine("登陆失败!");
                        }
                    }
                }
    
                Console.ReadKey();
            }
        }
    }

    程序运行截图:

    普通输入,输错密码无法登陆:

    输入正确密码,登陆成功:

    输入万能密码,登陆成功!

    那么该如何解决这问题呢?

    解决源码如下:

    using System;
    using System.Data.SqlClient;
    namespace 第一个数据库程序
    {
        class Program
        {
            static void Main(string[] args)
            {
                //解决数据库添加不进去数据,两个mdf问题冲突问题代码,即.
                /***************************************************/
         
                string dataDir = AppDomain.CurrentDomain.BaseDirectory;
                if (dataDir.EndsWith(@"inDebug")
                    || dataDir.EndsWith(@"inRelease"))
                {
                    dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
                    AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
                }
                /************************************************/
    
                 Console.WriteLine("请输入用户名:");
                string user = Console.ReadLine();
                Console.WriteLine("请输入密码:");
                string pwd = Console.ReadLine();
    
                //与数据库建立连接
                using (SqlConnection conn = new SqlConnection(@"Data Source=.SQLEXPRESS;AttachDbFilename=|DataDirectory|Database1.mdf;Integrated Security=True;User Instance=True"))
                {
                    conn.Open();//打开连接
    
                    //创建SQL命令语句
                    using (SqlCommand cmd = conn.CreateCommand())
                    {
                        //SQL查询语句
                        cmd.CommandText = "select * from T_users where username=@NAME and password=@PW";
    
                        cmd.Parameters.Add(new SqlParameter("NAME", user));//NAME 和PW是参数,名字自己随意取,但必须和上面的一致。
                        cmd.Parameters.Add(new SqlParameter("PW", pwd));
    
                        int i = Convert.ToInt32(cmd.ExecuteScalar());//函数返回第一行第一列的值
                        if (i > 0)
                        {
                            Console.WriteLine("登陆成功!");
                        }
                        else
                        {
                            Console.WriteLine("登陆失败!");
                        }
                    }
                }
    
                Console.ReadKey();
            }
        }
    } 

    普通输入,输错密码无法登陆:

    输入正确密码,登陆成功:

    万能密码登陆失败!

  • 相关阅读:
    Java初学者:for循环介绍
    Java初学者:条件判断及其语句
    Java初学者:基本数据类型的强制类型转换
    eclipse+gradle+nodejs搭建web开发环境
    桑基图(sankey)
    tomcat性能优化
    数据库概览与选择
    在linux上装 postgresql 在 windows或 linux 连不上的问题的解决方法
    mosquitto的TLS功能测试,客户端使用paho.mqtt.golang(附JAVA版客户端实现)
    两步使用arm-linux-androideabi-addr2line定位JNI动态库中C代码错误位置
  • 原文地址:https://www.cnblogs.com/xingyunblog/p/3927488.html
Copyright © 2020-2023  润新知