Docker Container


Inspecting the current Docker container after conducting basic enumeration

svc


/ # ll /home
total 12K    
     4 drwxr-xr-x    1 root     root        4.0K Dec 27 17:01 ..
     4 drwxr-x---    4 1001     1001        4.0K Nov 11  2022 svc
     4 drwxr-xr-x    1 root     root        4.0K Nov 10  2022 .
/ # ll /home/svc
total 28K    
     4 -rw-r-----    1 root     1001          33 Dec 27 17:01 user.txt
     4 drwxr-x---    4 1001     1001        4.0K Nov 11  2022 .
     4 drwxr-xr-x    1 root     root        4.0K Nov 10  2022 ..
     0 lrwxrwxrwx    1 root     root           9 Nov 10  2022 .bash_history -> /dev/null
     4 drwxrwxr-x    5 1001     1001        4.0K Jun 12  2022 .local
     4 drwx------    3 1001     1001        4.0K Jun 12  2022 .cache
     4 -rw-r--r--    1 1001     1001        3.7K Jun  7  2022 .bashrc
     4 -rw-r--r--    1 1001     1001         807 Jun  7  2022 .profile

The /home directory contains a single user; svc The svc account was initially enumerated in the API server; api.mentorquotes.htb

Given that the svc account does not exist in the /etc/passwd file of the current Docker container, it is very likely that the svc account is a valid system user in the host system and the home directory of the svc account in the host system could be mapped to the current Docker container

/ # touch /home/svc/blah
touch: /home/svc/blah: Read-only file system

Additionally, the /home/svc directory is read-only file system. This further suggests the possibility of the volume mapping

db.py


/app # cat app/db.py
import os
 
from sqlalchemy import (Column, DateTime, Integer, String, Table, create_engine, MetaData)
from sqlalchemy.sql import func
from databases import Database
 
# Database url if none is passed the default one is used
database_url = os.getenv("database_url", "postgresql://postgres:postgres@172.22.0.1/mentorquotes_db")
 
# SQLAlchemy for quotes
engine = create_engine(DATABASE_URL)
metadata = MetaData()
quotes = Table(
    "quotes",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("title", String(50)),
    Column("description", String(50)),
    Column("created_date", DateTime, default=func.now(), nullable=False)
)
 
# SQLAlchemy for users
engine = create_engine(DATABASE_URL)
metadata = MetaData()
users = Table(
    "users",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("email", String(50)),
    Column("username", String(50)),
    Column("password", String(128) ,nullable=False)
)
 
 
# Databases query builder
database = Database(DATABASE_URL)

checking the db.py file of the api server application, it does reveal the sql connection string with a cleartext credential; postgres:postgres

  • Interestingly, it first does it by attempting to fetch DATABASE_URL from the environment variable
    • or falling back to the hardcoded SQL connection string;
      • os.getenv("database_url", "postgresql://postgres:postgres@172.22.0.1/mentorquotes_db")
  • Given the svc account also does exist in the API server application, I could attempt to enumerate the backend database; postgreesql

no psql


/app # psql
sh: psql: not found
/app # find / -name psql -executable -ls 2>/dev/null

However, the command-line tool for postgresql, psql , is not available within the current Docker container Considering the IP address of the backend database(172.22.0.1) differs from the current Docker container, it would require tunneling to reach the 172.22.0.1 host

Environment Variables


/app # env
HOSTNAME=a05537a193df
WORK_DIR=/app/
PYTHON_PIP_VERSION=19.3.1
SHLVL=3
HOME=/home/svc
OLDPWD=/app/app
GPG_KEY=0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D
python_get_pip_url=https://github.com/pypa/get-pip/raw/ffe826207a010164265d9cc807978e3604d18ca0/get-pip.py
TERM=xterm-256color
path=/home/svc/.local/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ADMIN_USER=james
ADMIN_EMAIL=james@mentorquotes.htb
LANG=C.UTF-8
SECRET=76dsf761g31276hjgsdkahuyt123
PYTHON_VERSION=3.6.9
PWD=/app
PYTHON_GET_PIP_SHA256=b86f36cc4345ae87bfd4f10ef6b2dbfa7a872fbff70608a1e43944d283fd0eee

While there is no DATABASE_URL, it includes an interesting variable; SECRET=76dsf761g31276hjgsdkahuyt123 Based on its name, it seems likely that this variable is intended to store a secret or sensitive information. However, the actual content and purpose of this secret are not discernible from the provided environment variables alone.