// HackTheBox  ·  writeup

Bumblebee

HackTheBox Easy sqlite3grepawk
DFIR

Scenario

In this Sherlock, you’ll step into the role of a DFIR specialist, tracing the steps of an external contractor who breached Forela’s internal forum. Utilizing provided forum logs and an SQLite3 database dump, you’ll unravel how the perpetrator exploited the Guest WiFi to steal administrative credentials. This easy task tests the your ability to analyze forensic data, follow digital footprints, and unmask the identity of the intruder.

Executive Summary

An external contractor on the Guest WiFi registered a normal forum account on Forela’s phpBB instance and published a post containing JavaScript that rendered a fake login form pointed back at their own machine. An administrator’s credentials were captured through it, and the contractor used them to log in as the administrator from a Mac browser. Within a minute they added their own account to the Administrators group, then requested a database backup from the web-accessible store directory and downloaded it. The forum configuration also held a service-account password in plaintext, readable to anyone with admin rights. The whole chain is visible in the SQLite dump and the web server log, provided the log’s timezone offset is handled correctly.

Artifacts

Timestamp note: access.log timestamps carry a +0100 offset. Database timestamps are UTC epochs. Convert everything to UTC and answer in DD/MM/YYYY HH:mm:ss.

Persistence

Q1 — What was the username of the external contractor?

Start in phpbb_users. The newest account is a lookalike of a staff name, and a forum post by “Alex Poole” describes them as an external contractor. That ties the contractor to the lookalike username, which has the digit-suffixed shape the format hint implies.

sqlite3 phpbb.sqlite3 "select user_id, username, user_ip from phpbb_users order by user_id desc limit 5;"
Click flag to reveal apoole1
Q2 — What IP address did the contractor use to create their account?

The user_ip column on the Q1 account holds the registration address. Confirm it against the web log: the registration POSTs in access.log come from the same source.

grep 'POST' access.log | grep -i register | cut -c1-200

Gotcha: Some access.log lines embed whole HTML pages. A bare grep floods the terminal, so pipe through cut.

Click to reveal answer 10.10.0.78

Credential Access

Q3 — What is the post_id of the malicious post that the contractor made?

From Q1 the contractor’s user_id is 52. Filter phpbb_posts on poster_id and read the post bodies. One post contains a <script> block that builds a login form, which marks it as the malicious one.

sqlite3 phpbb.sqlite3 "select post_id, poster_id, post_subject from phpbb_posts where poster_id=52;"
Click flag to reveal 9
Q4 — What is the full URI that the credential stealer sends its data to?

Pull the post_text of the Q3 post and read the form’s action attribute. It points at a PHP collector on the contractor’s own address from Q2, so captured credentials went straight back to their machine.

sqlite3 phpbb.sqlite3 "select post_text from phpbb_posts where post_id=9;" | grep -o 'action=[^ ]*'
Click to reveal answer http://10.10.0.78/update.php
Q6 — In the forum there are plaintext credentials for the LDAP connection, what is the password?

Once the contractor held admin rights, the board configuration was theirs to read. phpbb_config stores the LDAP bind password in clear text under ldap_password.

sqlite3 phpbb.sqlite3 "select config_name, config_value from phpbb_config where config_name like 'ldap%';"
Click to reveal answer Passw0rd1

Initial Access

Q5 — When did the contractor log into the forum as the administrator? (UTC)

phpbb_log is the board’s own audit trail. Filter on the Q2 address and look for an admin authentication success entry. log_time is an epoch, so convert it to UTC rather than trusting the web log’s +0100 clock. This answer rests on reading that entry type as the administrator login.

sqlite3 phpbb.sqlite3 "select datetime(log_time,'unixepoch'), log_operation, log_ip from phpbb_log where log_ip='10.10.0.78' order by log_time;"
Click flag to reveal 26/04/2023 10:53:12
Q7 — What is the user agent of the Administrator user?

Count user agents in access.log and look for the one that fits the admin session. Exactly one agent in the file is a Macintosh browser, with 456 hits: Chrome 112 on macOS. That is the browser behind the admin session.

grep Macintosh access.log | awk -F'"' '{print $6}' | sort | uniq -c

Tip: The format hint gives the full string shape (Mozilla/5.0 (Macintosh; ...)). Match the log’s value exactly, spaces included.

Click flag to reveal Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36

Privilege Escalation

Q8 — What time did the contractor add themselves to the Administrator group? (UTC)

Stay in phpbb_log after the Q5 login. A LOG_USERS_ADDED entry for the Administrators group names the contractor’s second account, apoole, 39 seconds after the admin login. Convert the epoch to UTC.

sqlite3 phpbb.sqlite3 "select datetime(log_time,'unixepoch'), log_operation, log_data from phpbb_log where log_operation='LOG_USERS_ADDED';"
Click to reveal answer 26/04/2023 10:53:51

Collection

Q9 — What time did the contractor download the database backup? (UTC)

Search access.log for requests to the /store/ directory. A single GET fetches a compressed SQL backup. The line is stamped 12:01:38 +0100, so the UTC time is one hour earlier.

grep '/store/' access.log | cut -c1-200

Gotcha: Submitting the log’s own 12:01:38 is wrong. Subtract the +0100 offset first.

Click flag to reveal 26/04/2023 11:01:38
Q10 — What was the size in bytes of the database backup as stated by access.log?

Same line as Q9. The byte count is the field right after the status code.

grep '/store/' access.log | awk '{print $9, $10}'
Click to reveal answer 34707

Attack Summary

PhaseAction
PersistenceContractor registers a lookalike forum account from the Guest WiFi
Credential AccessPublishes a post with JavaScript that renders a fake login form posting to their own host
Initial AccessLogs in as the administrator from a Mac Chrome session
Privilege EscalationAdds their own second account to the Administrators group 39 seconds later
Credential AccessReads the plaintext LDAP bind password from the board configuration
CollectionDownloads a database backup from the web-accessible /store/ directory

IOCs

TypeValue
IP (contractor, stealer host)10.10.0[.]78
URL (credential collector)hxxp[://]10[.]10[.]0[.]78/update[.]php
Accountapoole1 (user id 52)
Account (added to Administrators)apoole
Forum postpost_id 9
User agentChrome 112 on macOS 10.15.7
Path/store/ (database backup, 34707 bytes)

MITRE ATT&CK

TechniqueIDDescription
Create Account: Local AccountT1136.001Contractor registered a forum account
Input Capture: Web Portal CaptureT1056.003Fake login form in a forum post posting to a collector script
Valid AccountsT1078Administrator login with the captured credentials
Account ManipulationT1098Own account added to the Administrators group
Unsecured Credentials: Credentials In FilesT1552.001LDAP bind password stored in plaintext in phpbb_config
Data from Local SystemT1005Database backup downloaded from /store/

Defender Takeaways

Guest WiFi must not reach internal services. The contractor came in over the guest network and registered on an internal forum. Segmenting guest traffic away from internal web apps removes this path entirely.

Forum posts shouldn’t be able to carry script content. A post with an inline form and JavaScript harvested the administrator’s credentials. Sanitise or restrict post HTML and add a Content Security Policy that blocks form submission to unknown hosts.

Alert on Administrators group changes. The group add came 39 seconds after an admin login from a new address. A rule on LOG_USERS_ADDED into a privileged group, or on an admin login from an unfamiliar IP, would have fired before the backup download.

Keep secrets out of the application config and backups out of the web root. The LDAP bind password sat in clear text for any admin to read, and the database backup was fetchable over HTTP. Use a secrets store and keep backups outside the document root, or require authentication for them.

Normalise timezones at ingestion. The web log used +0100 while the database used UTC epochs. Mixing them silently shifts a timeline by an hour.

Conclusion

A guest-network contractor turned one unsanitised forum post into administrator access and walked away with a database backup. Nothing was exploited technically; the weak points were a trusting post editor, a flat network and a backup sitting in a web-readable folder.