实习第五天报告(8.30)

目录

SQL注入知识点

概述

产生原因

原理与本质

注入思路

常用函数及含义

绕过WAF的方法

注入方式

防御方式

靶场实战

第一关

第二关

​第三关

第四关

第五关

第六关

总结


SQL注入知识点

定义:SQL注入攻击是一种代码注入技术,攻击者通过在Web应用程序的输入字段中插入或“注入”恶意的SQL代码片段,欺骗数据库执行非授权的SQL命令,从而实现对数据库的非法访问和操作,如数据窃取、篡改、删除等,甚至执行系统级命令。

产生原因

SQL注入攻击的产生原因主要归结为以下几点:

程序编写缺陷:开发者在处理应用程序和数据库交互时,使用字符串拼接的方式构造SQL语句,未对用户输入进行充分的检查和处理。

不安全的数据库配置:数据库权限设置不当,允许未授权用户执行敏感操作。

用户输入过滤不足:程序未对用户输入进行足够的过滤和校验,使得恶意代码能够嵌入到SQL语句中。

原理与本质

原理:SQL注入攻击的原理在于利用应用程序未对用户输入进行充分检查的漏洞,通过构造特殊的输入参数,使应用程序在执行SQL语句时,将恶意代码作为SQL语句的一部分执行。

本质:SQL注入攻击的本质是一种通过输入恶意数据来操纵后台数据库执行非预期操作的攻击方式。

注入思路

SQL注入攻击的注入思路主要包括以下几个步骤:

寻找注入点:通过输入测试数据,判断应用程序是否存在SQL注入漏洞。

判断数据库类型:确定目标数据库的类型和版本,以便构造相应的攻击语句。

构造攻击语句:根据数据库类型和版本,构造恶意的SQL语句,尝试执行非法操作。

获取敏感信息:通过执行恶意SQL语句,窃取、篡改或删除数据库中的敏感信息。

常用函数及含义

在SQL注入攻击中,攻击者会利用数据库管理系统(DBMS)提供的各种内置函数来辅助执行恶意操作或获取敏感信息。这些函数的含义和作用因数据库类型的不同而有所差异,以下是一些在MySQL中常见且可能被用于SQL注入攻击的函数及其详细含义:

信息获取类函数

USER():返回当前MySQL服务器登录的用户名。

DATABASE() 或 SCHEMA():返回当前数据库名。

VERSION():返回MySQL服务器的版本信息。

@@datadir@@basedir:分别返回MySQL数据库的数据目录和安装目录路径。

字符串处理类函数

CONCAT(str1, str2, ...):将多个字符串连接成一个字符串。

SUBSTRING(str, pos, len) 或 MID(str, pos, len) 或 SUBSTR(str, pos, len):从字符串str的pos位置开始,截取长度为len的子字符串。

LENGTH(str):返回字符串str的长度。

报错注入类函数

UPDATEXML(XML_doc, XPath_string, new_val):用于修改XML文档中的数据。当XPath_string格式错误时,会触发错误,并返回错误信息,从而可被用于报错注入。

EXTRACTVALUE(XML_doc, XPath_string):从XML文档中返回通过XPath表达式指定的值。同样,当XPath表达式错误时,会触发错误,可被用于报错注入。

时间延迟类函数

SLEEP(duration):使当前线程暂停执行指定的时间duration秒。在基于时间的盲注中,攻击者可以利用此函数通过测量响应时间来判断SQL语句的执行结果。

条件判断类函数:IF(expr1, expr2, expr3):如果expr1为真,则返回expr2的值;否则返回expr3的值。在SQL注入中,可用于构造条件判断语句。

绕过WAF的方法

编码绕过:通过对恶意代码进行编码,如URL编码、Base64编码、Unicode编码等,使得WAF无法直接识别出恶意内容。这种方法的前提是,应用后端在接收编码后的数据前会进行相应的解码处理。

例:

URL:将特殊字符(如空格、引号等)转换为URL编码形式(如%20代表空格)。

Base64:将恶意代码转换为Base64编码的字符串,然后嵌入到URL或请求体中。

Unicode:使用非ASCII字符(如中文字符)进行编码,创建难以被WAF分析的URL或请求体。

分块传输绕过:通过在HTTP请求头中添加Transfer-Encoding: chunked,将请求体分割成多个块进行传输。每个块包含十六进制的长度值和数据,长度值独占一行。这种方法可以绕过基于请求体大小或特定标记检测的WAF。

畸形包绕过(Pipeline绕过):通过发送格式异常的HTTP请求包(如Connection: keep-alive,但实际上并不保持连接),试图绕过WAF的检测机制。这种方法利用了HTTP协议的一些特性,但可能导致请求被正常服务器拒绝。例如:修改Connection字段为keep-alive,但实际上发送的是不完整的请求包,然后再在请求包中插入无效字符或格式错误的头部字段。

协议覆盖:通过修改HTTP请求头中的Content-Type字段,尝试绕过WAF对特定内容类型的检测规则。例如,将Content-Type改为multipart/form-data并设置自定义的边界符,然后在边界符内嵌入恶意代码。

高并发绕过:通过发起高并发的请求,利用负载均衡机制将请求分发到不同的服务器节点,试图绕过部署在某些节点上的WAF,这种方法需要攻击者具备足够的资源来发起大规模的攻击。

脏数据绕过:通过在请求中插入大量无意义的数据(如大量重复的字符),试图耗尽WAF的处理资源或绕过其检测逻辑。这种方法特别适用于那些只检测请求开头部分内容的WAF。

请求方式差异规则松懈性绕过:某些WAF对不同请求方式(如GET、POST、PUT等)的处理规则可能不一致。攻击者可以尝试变换请求方式来绕过WAF的特定规则。

注入方式

SQL注入攻击的方式多种多样,主要包括以下几种:

基于错误的注入:通过故意构造错误的SQL语句,使数据库返回错误信息,从而获取数据库的内部信息。

基于布尔的盲注:通过构造SQL语句并观察应用程序的响应(如页面是否返回正常),来推断数据库的内部信息。

基于时间的盲注:利用SQL语句中的时间延迟函数(如Sleep()),通过测量应用程序的响应时间,来推断数据库的内部信息。

联合查询注入:通过构造联合查询(如Union select()),将恶意SQL语句与合法查询结合,以获取额外的数据库信息。

堆叠查询注入:在单个SQL查询语句中,通过分号分隔多个SQL语句,尝试执行多个非预期的数据库操作。

防御方式

为了有效防御SQL注入攻击,可以采取以下措施:

使用参数化查询或预编译语句:确保应用程序在处理用户输入时,将输入作为参数传递给SQL语句,而不是直接拼接到SQL语句中。

输入验证和过滤:对用户输入进行严格的验证和过滤,确保输入数据符合预期的格式和规范。

最小权限原则:为数据库用户分配最小的必要权限,避免使用具有广泛权限的数据库账户。

使用ORM框架:利用ORM框架自动处理SQL注入等安全问题。

及时更新和打补丁:定期更新数据库和应用程序的安全补丁,以修复已知的安全漏洞。

部署WAF:使用Web应用防火墙等安全设备,对进出Web应用程序的数据进行监控和过滤,及时发现并阻止SQL注入攻击。

靶场实战

第一关

查看网页内容,尝试输入?id=1,发现存在注入点

修改数字值,发现数字值不同,返回页面也不同,说明输入内容确实带到了数据库中进行了查询

判断注入是字符型还是数字型,发现返回页面未改变,说明是字符型注入,且存在拼接语句

判断数据库中当前表格存在几列,发现输入3不报错,输入4报错,说明存在3列

使用联合查询,尝试寻找回显位置,发现2、3位置会回显

?id=1这部分尝试从表中选取id等于-1的记录。由于大多数情况下,id字段是主键或唯一索引,并且通常不会包含负数(除非特别设计),因此这部分查询很可能不会返回任何行,而select  1,2,3试图从数据库中检索硬编码的值1,2,3,而不是从原始查询中检索的数

使用mysql数据库的函数database(),version(),填充在2、3位置,以获取当前数据名和版本,通过结果知道当前数据看是security,版本是5.7.26

知道数据库版本后,因为Mysql 5 以上有内置库 information_schema ,存储着mysql的所有数据库和表结构信息,因此我们就可以利用该版本的一些函数来获取表名;information_schema.tables表示数据库下的tables表,“.”表示下一级。where后面是条件,group_concat()是将查询到结果连接起来。如果不用group_concat查询到的只有user。该语句的意思是查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容。

?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

我们通过sql语句查询知道当前数据库有四个表,根据表名知道可能用户的账户和密码是在users表中,接下来我们就需要得到该表下的字段名以及内容。该语句的意思是查询information_schema数据库下的columns表中table_users字段内容是users的所有column_name的内容。

注:table_name字段不是只存在于tables表,也存在于columns表中。表示所有字段对应的表名经过查询后得到两个关键字段username和password

?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

继续使用联合查询得到username和password字段中的内容,id起到隔开username和password的作用,便于查看

?id=-1' union select 1,2,group_concat(username ,id , password) from users--+

使用sqlmap验证结果正确性,数据库正确

表正确

字段正确

数据正确,完成

第二关

和第一关一样,先对注入类型进行判断,由于无论是单引号还是双引号都会报错,可以判断为数字型注入

接着和第一关一样的步骤,判断数据库中当前表格存在几列,发现和第一关一样存在三列

使用联合查询寻找回显位置,发现和第一关一样是2、3位置回显

剩下步骤同第一关,查询数据库、数据库版本,然后使用information_schema表查询表名、字段和

数据

使用sqlmap验证正确性,完成

第三关

先对注入类型进行判断,先尝试单引号双引号,均报错,根据报错信息,可推测查询语句中存在括号

尝试使用括号闭合,不再报错

判断数据库中当前表格存在几列,发现存在三列

使用联合查询判断回显位置为2、3

查询数据库、数据库版本,然后使用information_schema表查询表名、字段和数据,并使用sqlmap验证,完成

第四关

根据页面报错信息可判断为双引号字符型加括号

判断列数为3

判断回显位置为2、3

查询数据库、数据库版本,然后使用information_schema表查询表名、字段和数据,并使用sqlmap验证,完成

第五关

判断注入类型为双引号字符型,且由于页面没有回显内容,不适合采用联合查询,因为数据不显示,只有对错页面显示,我们可以选择布尔盲注。

判断数据库中当前表格存在几列,发现存在三列

接下来通过length()函数判断数据库长度,原理同联合查询的order by语句,这里我们用and逻辑符拼接,当and后的语句,即数据库名长度为n时,页面才会正常回显,经过多次尝试,确定数据库名长度为8

?id=1'and length((select database()))=n--+

然后我们可以使用数据库中的一个函数substr()来取出数据库名的每一位来进行盲注,用来猜数据库名。第一个参数为传入字符串,第二个参数作用是取几位,第三个参数为步长,该语句的作用即是:检查当前数据库名称的第一个字符是否是'*'。如果是,这个条件就会返回true,否则返回False,这也是布尔盲注花费大量时间的原因,因为需要挨个挨个猜测数据库名、表名、字段等等,所以布尔盲注大多数使用工具,例如sqlmap进行注入,但无奈老师要求不使用sqlmap,在这里由于其他题的经验,我猜数据库名是security,表名是users,字段有username,password等,而若要检测数据内容就不得不借用工具了^_^

?id=1' and substr(database(),1,1)=‘*’  #用于推测数据库名

使用sqlmap验证我的猜想,果然是对的^_^

第六关

判断注入类型为单引号字符型,且由于页面没有回显内容,不适合采用联合查询,因为数据不显示,只有对错页面显示,我们可以选择布尔盲注。

接下来步骤同第五关,有了上次的经验,这次我们直接借助工具sqlmap^_^

后续题目有兴趣做在更新^_^

总结

SQLi手工注入步骤一般如下:

判断注入点:首先确定应用程序中可能存在SQL注入漏洞的输入点,如URL参数、表单字段等;通过输入特殊字符(如单引号、双引号、括号等,使用闭合绕过的方式来确定注入类型是字符型(分为双引号型和单引号型)还是数字型)或特定的SQL语句片段(如and 1=1、and 1=2,布尔盲注),观察应用程序的响应或报错信息来判断是否存在注入点,并确定闭合方式

猜解字段数量:使用ORDER BY语句:通过逐渐增加ORDER BY子句中的数字,观察应用程序何时报错,以确定数据库表中字段的数量。

确定回显点:使用UNION SELECT语句:在确认字段数量后,通过构造UNION SELECT语句将恶意查询结果与原查询结果合并输出,以找到回显点(即应用程序中显示数据库查询结果的位置)。注:应确保UNION SELECT语句中的字段数量与原始查询一致,以避免SQL语法错误。

信息收集:利用回显点,通过执行内置数据库函数(如version()、database()、user()等)获取数据库版本、当前数据库名、当前用户名等敏感信息;然后利用information_schema数据库中的tables和columns表,查询数据库中所有表名和列名。这通常需要使用GROUP_CONCAT()函数将多个结果合并为一个字符串输出。

数据提取:根据已获取的表名和列名,构造特定的SQL查询语句以提取所需的数据;如有条件,还可以将提取的数据导出到文件或通过网络传输到攻击者控制的服务器。

附(Ai说的):绕过安全机制:应对WAF和IPS:尝试使用编码绕过(如URL编码、Base64编码)、分块传输、畸形包、协议覆盖等方法绕过WAF(Web应用防火墙)和IPS(入侵防御系统)的检测;根据应用程序的具体安全措施(如输入验证、参数化查询等),采取相应的绕过策略

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值