Machine / Machines

Eloquia

Eloquia is a sanitized machine note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator

InsanePublished 2025-12-24Sanitized local writeup

Scenario

Eloquia attack path

Eloquia is a sanitized machine note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator

Objective

Machine walkthrough focused on Machines evidence, validation, and reusable operator lessons.

Eloquia sanitized attack graph

Walkthrough flow

01

External scan exposed only IIS HTTP on 80 and WinRM...

02

HTTP redirect and vhost validation confirmed...

03

Eloquia used Qooqle OAuth without meaningful...

04

A reported article with a browser beacon caused the...

05

Logging in through Qooqle then granted Eloquia admin...

Source coverage

High source coverage

Status: complete. This article is generated from 7 sanitized Markdown sources and keeps raw flags, credentials, keys, cookies, and reusable secrets out of the rendered blog.

100% coverage
Evidence verdict

High confidence: the page is reconstructed from a primary walkthrough plus multiple supporting notes or evidence sources. Treat the chain as source-backed, while still checking the listed source files for sensitive values.

  • <TARGET>-Eloquia/walkthrough.md
  • HTB/<TARGET>-Eloquia/notes.md
  • HTB/<TARGET>-Eloquia/attack-map.md
  • HTB/<TARGET>-Eloquia/memory-summary.md
  • HTB/<TARGET>-Eloquia/session-resume.md
  • HTB/<TARGET>-Eloquia/custom-exploit-notes.md
  • HTB/<TARGET>-Eloquia/dead-ends.md

Technical Walkthrough

Eloquia Walkthrough

This file records the final reproducible path only after live validation. Keep speculative notes in research.md and rejected paths in dead-ends.md.

Phase 0: Setup

  • Workspace initialized locally.
  • Public research stored as advisory intelligence.
  • Live validation matched public anchors: IIS 10.0, WinRM 5985, eloquia.htb, qooqle.htb, Django CSRF, OAuth flow, SQL Explorer, SQLite load_extension.

Phase 1: OAuth CSRF Admin Takeover

Created controlled Eloquia and Qooqle accounts. Eloquia's Qooqle OAuth flow used no meaningful state/PKCE protection. A reported article containing a meta-refresh plus image beacon caused the admin bot to request the Pwnbox /bait endpoint. The listener minted a fresh Qooqle authorization code and redirected the admin browser to Eloquia's callback, linking the admin Eloquia session to the attacker Qooqle account.

After the callback, logging into Eloquia through Qooqle returned HTTP 200 for /accounts/admin/.

Phase 2: SQLite RCE

Admin panel exposed SQL Explorer at /dev/sql-explorer/play/. select sqlite_version() confirmed SQLite, and load_extension() was enabled. Anonymous SMB loading failed because Windows blocked guest access, matching the expected dead end.

The intended path was admin Article banner upload: the admin form accepted DLL files and exposed the saved path under static/assets/images/blog/. Loading the uploaded DLL with:

sql
select load_extension('static/assets/images/blog/wp2.dll');

executed code as ELOQUIA\web, confirmed by writing a proof file under the web-served static path.

Phase 3: DPAPI To WinRM

Used RCE to copy Edge Login Data and Local State from the web profile. PowerShell was blocked by policy, so a native DPAPI DLL called CryptUnprotectData as web and wrote the decrypted Chromium AES key to the static path. Offline decryption of Login Data recovered a valid credential for Eloquia\Olivia.KAT, which was validated with WinRM.

User flag was copied from the live target into loot/user.txt.

Phase 4: Failure2Ban SYSTEM

WinRM enumeration showed:

text
HKLM\SYSTEM\CurrentControlSet\Services\Failure2Ban
ImagePath = C:\Program Files\Qooqle IPS Software\Failure2Ban - Prototype\Failure2Ban\bin\Debug\Failure2Ban.exe

icacls confirmed ELOQUIA\Olivia.KAT had write permission on the SYSTEM service executable. A minimal payload copied the Administrator root flag to C:\Temp\root.txt. After staging the payload, a PowerShell overwrite loop won the service restart race. The payload executed as SYSTEM and root was copied into loot/root.txt.

Source-Backed Dossier

The sections below are merged from companion Markdown notes for the same case. They are rendered after sanitization so the article stays precise without publishing raw flags, credentials, or target-specific secrets.

Notes

Scope

  • Platform: HackTheBox
  • Machine: Eloquia
  • Difficulty: Insane
  • OS: Windows
  • Creator: Spectra199
  • Target IP: <TARGET>
  • Pwnbox: <TARGET>
  • Pwnbox user: profex0r
  • Started: 2026-05-07 23:39:43 AEST

Operating Rules

  • Public research is advisory only. Evidence requires live validation.
  • Keep raw flags, reusable <password redacted>, tickets, cookies, private keys, and dumps in loot/ only.
  • Use Pwnbox for live testing and save command output to files.
  • For state-mutating actions, snapshot current state and write rollback notes before execution.
  • For Insane mode, stop at phase boundaries and update attack-map.md, dead-ends.md, custom-exploit-notes.md, and session-resume.md.

Evidence Ledger

TimeCommandOutput FileFindingConfidenceNext Action
2026-05-07 23:39 AESTLocal workspace initializationlocal filesWorkspace initialized for Eloquia; no local pre-research file was present, so fresh external pre-research was started.HighQuery CTF LightRAG and validate live target from Pwnbox.
2026-05-07 23:43 AESTpython3 scripts/query_ctf_lightrag.py ...enum/lightrag-start-summary.jsonCTF LightRAG queried for advisory prior patterns. Returned broad methodology context; no Eloquia-specific ingested memory yet.MediumUse as advisory only; proceed to live validation.
2026-05-07 23:45 AESTssh profex0r@<TARGET>terminal outputSupplied Pwnbox timed out on SSH. Follow-up ping showed 100% packet loss.HighNeed live Pwnbox or direct HTB VPN route before target validation.
2026-05-07 23:47 AESTlocal route/ping/nc checksterminal outputLocal Mac has Wi-Fi and Tailscale routes only; no direct HTB target route. Ping and TCP/80 to target timed out locally.HighResume after Pwnbox respawn/new IP or local HTB VPN route.
2026-05-08 00:51 AESTnmap -Pn -p<redacted> --min-rate 5000nmap/full-tcp.*, enum/pwnbox-baseline.txtNew Pwnbox valid; target reachable; only TCP 80 and 5985 open.HighFingerprint services and validate research anchors.
2026-05-08 00:52 AESTnmap -sC -sV -p<redacted>nmap/service-80-5985.*IIS 10.0 on 80, HTTPAPI/WinRM on 5985, Windows Server CPE.HighAdd hostnames and map web apps.
2026-05-08 01:15 AESTcurl host baselineenum/http-hostname-baseline.txteloquia.htb and qooqle.htb both live; Django-style CSRF cookies/forms present.HighMap OAuth flow.
2026-05-08 01:22 AESTpython3 exploits/oauth_takeover.pyenum/oauth-takeover-run3-public-img.txtOAuth CSRF takeover succeeded; target hit /bait; Qooqle login yielded admin panel access.HighEnumerate SQL Explorer.
2026-05-08 01:30 AESTSQL Explorer probeenum/sql-playground-test.txtSQLite backend confirmed; load_extension() enabled.HighUpload DLL through admin Article banner field.
2026-05-08 01:42 AESTload_extension('static/assets/images/blog/wp2.dll')enum/sql-load-writeproof.txtRCE confirmed as web by writing static proof file.HighExtract Edge artifacts.
2026-05-08 01:51 AESTDPAPI/Edge extractionenum/cmdrunner-profile-search.txt, remote loot/edge-decrypted.txtEdge Login Data and Local State extracted; DPAPI decrypted in web context; Olivia credential recovered.HighValidate WinRM.
2026-05-08 01:52 AESTnxc winrm ... Olivia.KATenum/winrm-olivia-check.txtWinRM as Eloquia\\Olivia.KAT confirmed Pwn3d.HighEnumerate Failure2Ban.
2026-05-08 01:56 AESTFailure2Ban ACL/raceenum/winrm-failure2ban-enum.txt, enum/winrm-f2b-overwrite-race2.txtOlivia has write permission on SYSTEM service binary; overwrite race succeeded.HighPoll copied root flag.
2026-05-08 01:57 AESTRoot flag pollenum/winrm-root-poll.txt, loot/root.txtPayload executed as SYSTEM and copied root flag to readable location.HighFinalize notes and propose sanitized memory ingestion.

Live Access State

ItemValueStatus
Target reachability<TARGET>Pending
Pwnbox SSH<TARGET>Unreachable from local network
VPN IPUnknownPending
Hostnameseloquia.htb, qooqle.htbAdvisory, pending validation
User flagNoneNot captured
User flagloot/user.txtCaptured
Root flagloot/root.txtCaptured

Attack Map

Current Graph

text
Pwnbox
  |
  | pending validation
  v
<TARGET>
  |
  +-- HTTP/80 [advisory: IIS + Eloquia web app]
  |     |
  |     +-- eloquia.htb [advisory: Django app]
  |     |     |
  |     |     +-- article/report/admin bot [unvalidated]
  |     |     +-- OAuth callback/account linking [unvalidated]
  |     |     +-- admin SQL Explorer [unvalidated]
  |     |
  |     +-- qooqle.htb [advisory: OAuth provider]
  |
  +-- WinRM/5985 [advisory: credential pivot]

Verified Chain

text
Pwnbox
  -> HTTP/80 IIS + Django apps
  -> eloquia.htb / qooqle.htb OAuth flow
  -> OAuth CSRF account linking through reported article/admin bot
  -> Eloquia admin panel
  -> SQL Explorer SQLite load_extension()
  -> Admin Article banner upload of DLL
  -> RCE as ELOQUIA\web
  -> Edge Login Data + Local State DPAPI extraction
  -> WinRM as ELOQUIA\Olivia.KAT
  -> Failure2Ban writable SYSTEM service executable
  -> service restart race overwrite
  -> root flag copied to C:\Temp\root.txt

Hypothesis Ranking

RankPathWhy It MattersStatus
1OAuth CSRF/account linking to adminMultiple sources converge on this as the initial breakthrough.Advisory
2SQLite load_extension() DLL RCE from admin panelExpected route from admin web access to Windows shell as web user.Advisory
3Edge DPAPI saved credential extractionExpected bridge from web shell to WinRM user.Advisory
4Failure2Ban service binary/race hijackExpected SYSTEM route.Advisory

All four ranked hypotheses were live-validated and used.

Transition Proof Requirements

TransitionProof Required Before Advancing
Pre-research to exploit4+ validation anchors match live target.
Web user to admin web accessAuthenticated UI shows admin-only functionality from attacker-controlled login.
Admin web access to RCECommand output or callback from live target, with uploaded DLL path and SQL query logged.
RCE to WinRM userCredential source identified and WinRM auth succeeds live.
WinRM user to SYSTEMService ACL/restart behavior captured before modification; SYSTEM execution confirmed.

Memory Summary

Status: Approved and ingested into private CTF LightRAG.

Metadata

  • Platform: HackTheBox
  • Content type: Machine
  • Name: Eloquia
  • OS: Windows
  • Difficulty: Insane
  • Workspace: <local workspace><TARGET>-Eloquia

Verified Chain

  1. External scan exposed only IIS HTTP on 80 and WinRM on 5985.
  2. HTTP redirect and vhost validation confirmed eloquia.htb and qooqle.htb.
  3. Eloquia used Qooqle OAuth without meaningful state/PKCE protection.
  4. A reported article with a browser beacon caused the admin bot to visit a Pwnbox listener, receive a fresh Qooqle authorization code, and hit Eloquia's OAuth callback in the admin session.
  5. Logging in through Qooqle then granted Eloquia admin panel access.
  6. SQL Explorer exposed SQLite query execution and allowed load_extension().
  7. Anonymous SMB DLL loading failed because Windows blocked guest access.
  8. Admin Article banner upload accepted a DLL and exposed the relative path under static/assets/images/blog/.
  9. Loading the uploaded DLL gave RCE as web.
  10. Edge Login Data and Local State under the web profile were extracted; a native DPAPI DLL decrypted the Chromium master key in the live web context.
  11. Offline Edge password decryption recovered a WinRM-valid user credential.
  12. The WinRM user had write permission on the SYSTEM Failure2Ban.exe service binary.
  13. An overwrite loop won the service restart race and replaced the service binary with a minimal copy-flag payload.

Reusable Lessons

  • For OAuth CSRF/admin-bot chains, make the callback server mint authorization codes on demand; short-lived codes make pre-generation unreliable.
  • Treat listener hits carefully: ignore unrelated paths to avoid mistaking public crawler traffic for admin-bot success.
  • Use image beacons alongside meta-refresh when article HTML injection needs reliable browser delivery.
  • If SQLite UNC load_extension() reaches SMB but Windows blocks guest access, pivot to local upload paths instead of cracking captured NetNTLM immediately.
  • Admin forms may have weaker file validation than public user-facing forms.
  • When PowerShell is blocked by policy, native DLLs can still call DPAPI APIs directly in the target user's context.
  • For Windows service restart races, run an overwrite loop and poll for payload effects rather than trying to stop/start the service without rights.

Do Not Ingest

  • Raw flags
  • Recovered <password redacted>
  • Admin cookies
  • DPAPI key material
  • Browser credential database contents

Session Resume

Current Status

  • Phase: Complete
  • User flag: captured in loot/user.txt
  • Root flag: captured in loot/root.txt
  • Current access: WinRM credential for Eloquia\Olivia.KAT recovered from Edge DPAPI and validated live
  • Last confirmed action: Failure2Ban executable overwrite race succeeded and SYSTEM payload copied root flag

Known Advisory Intelligence

  • Expected hostnames: eloquia.htb, qooqle.htb
  • Expected ports: 80/tcp, 5985/tcp
  • Expected chain: OAuth CSRF/account takeover -> SQLite DLL RCE -> Edge DPAPI credential extraction -> WinRM -> Failure2Ban service hijack/race -> SYSTEM

Post-Solve Tasks

  1. Keep raw flags and recovered credentials in loot/ only.
  2. Prepare sanitized memory summary for user approval before LightRAG ingestion.
  3. Do not ingest raw cookies, flags, <password redacted>, DPAPI key material, or credential dump output.

Notes

State Mutations

TimeTargetAttribute/FileOld StateNew StateRollback
2026-05-08 01:22 AESTEloquia ArticleNew reported articleDid not existOAuth callback article created for admin-bot flowDelete created article from admin panel if cleanup is required
2026-05-08 01:38 AESTAdmin Article uploadNew DLL-backed articleDid not existDLL files uploaded under static/assets/images/blog/ for RCEDelete created admin article/uploaded file if cleanup is required
2026-05-08 01:56 AESTFailure2Ban.exeService executableOriginal 13 KB service binaryReplaced with minimal copy-flag payload during race windowRestore original binary from backup/source if required

Custom Tooling

ToolPurposeInputsOutputStatus
oauth_takeover.pyAutomate Qooqle OAuth CSRF/admin-bot raceTest Eloquia/Qooqle account, listener IP/portAdmin web session cookies in loot/Worked
sqlite_cmd_runner.pyOne-shot command execution through SQL Explorer DLL upload/loadCommand string, admin cookiesCommand output written to static path and copied to loot/Worked
sqlite_edgekey.cNative DPAPI decryption of Edge Chromium master keyweb user's Local StateBase64 AES key written to static pathWorked
failure2ban_copyflag.cMinimal SYSTEM payloadService restart executionRoot flag copied to C:\Temp\root.txtWorked

Windows Payload Requirements

  • SQLite extension DLL must match target architecture.
  • Prefer a minimal proof payload first, then a controlled file-copy or shell payload after validation.
  • Record compile command, hash, upload path, and trigger query.
  • For service replacement, snapshot original binary hash, ACL, path, and service state before writing.

Dead Ends

Record abandoned paths with proof and reason so later agents do not repeat them.

TimePathEvidenceReason RejectedRevisit Condition