HackTheBox Writeup - Machines - BlockBlock
🕒 2025/03/27
- IP:
10.10.11.43 - OS:
Linux - Difficulty:
Hard
1. Nmap
First, let's scan all the ports on the machine with nmap.
sudo nmap -sS -sV -sC -v -p 1-65535 -oN nmap.txt 10.10.11.43# Nmap 7.94SVN scan initiated Tue Mar 25 22:37:05 2025 as: /usr/lib/nmap/nmap -sS -sV -sC -v -p 1-65535 -oN nmap.txt 10.10.11.43 Nmap scan report for 10.10.11.43 Host is up (0.20s latency). Not shown: 65532 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 9.7 (protocol 2.0) | ssh-hostkey: | 256 d6:31:91:f6:8b:95:11:2a:73:7f:ed:ae:a5:c1:45:73 (ECDSA) |_ 256 f2:ad:6e:f1:e3:89:38:98:75:31:49:7a:93:60:07:92 (ED25519) 80/tcp open http Werkzeug/3.0.3 Python/3.12.3 |_http-favicon: Unknown favicon MD5: D07AD703EDD6F8326B5C45F86CA8084E | http-methods: |_ Supported Methods: GET HEAD OPTIONS |_http-server-header: Werkzeug/3.0.3 Python/3.12.3 | fingerprint-strings: | GetRequest: | HTTP/1.1 200 OK | Server: Werkzeug/3.0.3 Python/3.12.3 | Date: Tue, 25 Mar 2025 14:42:03 GMT | Content-Type: text/html; charset=utf-8 | Content-Length: 275864 | Access-Control-Allow-Origin: http://0.0.0.0/ | Access-Control-Allow-Headers: Content-Type,Authorization | Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS | Connection: close | <!DOCTYPE html> | <html> | <head> | <title> | Home - DBLC | </title> | <link rel="stylesheet" href="/assets/nav-bar.css"> | </head> | <body> | <!-- <main> --> | <meta charset=utf-8> | <meta name=viewport content="width=device-width, initial-scale=1"> | <style> | :after, | :before { | box-sizing: border-box; | border: 0 solid #e5e7eb | :after, | :before { | --tw-content: "" | :host, | html { | line-height: 1.5; | HTTPOptions: | HTTP/1.1 500 INTERNAL SERVER ERROR | Server: Werkzeug/3.0.3 Python/3.12.3 | Date: Tue, 25 Mar 2025 14:42:03 GMT | Content-Type: text/html; charset=utf-8 | Content-Length: 265 | Access-Control-Allow-Origin: http://0.0.0.0/ | Access-Control-Allow-Headers: Content-Type,Authorization | Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS | Connection: close | <!doctype html> | <html lang=en> | <title>500 Internal Server Error</title> | <h1>Internal Server Error</h1> |_ <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p> |_http-title: Home - DBLC 8545/tcp open unknown | fingerprint-strings: | GetRequest: | HTTP/1.1 400 BAD REQUEST | Server: Werkzeug/3.0.3 Python/3.12.3 | Date: Tue, 25 Mar 2025 14:42:04 GMT | content-type: text/plain; charset=utf-8 | Content-Length: 43 | vary: origin, access-control-request-method, access-control-request-headers | access-control-allow-origin: * | date: Tue, 25 Mar 2025 14:42:04 GMT | Connection: close | Connection header did not include 'upgrade' | HTTPOptions: | HTTP/1.1 200 OK | Server: Werkzeug/3.0.3 Python/3.12.3 | Date: Tue, 25 Mar 2025 14:42:04 GMT | Content-Type: text/html; charset=utf-8 | Allow: HEAD, POST, OPTIONS, GET | Access-Control-Allow-Origin: * | Content-Length: 0 | Connection: close | Help: | <!DOCTYPE HTML> | <html lang="en"> | <head> | <meta charset="utf-8"> | <title>Error response</title> | </head> | <body> | <h1>Error response</h1> | <p>Error code: 400</p> | <p>Message: Bad request syntax ('HELP').</p> | <p>Error code explanation: 400 - Bad request syntax or unsupported method.</p> | </body> | </html> | RTSPRequest: | <!DOCTYPE HTML> | <html lang="en"> | <head> | <meta charset="utf-8"> | <title>Error response</title> | </head> | <body> | <h1>Error response</h1> | <p>Error code: 400</p> | <p>Message: Bad request version ('RTSP/1.0').</p> | <p>Error code explanation: 400 - Bad request syntax or unsupported method.</p> | </body> |_ </html> 2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service : ... Read data files from: /usr/share/nmap Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Tue Mar 25 22:43:36 2025 -- 1 IP address (1 host up) scanned in 391.44 seconds
2. Website
- http://10.10.11.43/

- When clicking
Register: - When clicking
Login: - When clicking
Chat: - When clicking
Profile:
Let’s register with the username ass & the password ass
Once we’ve registered and logged in, we can use the chat window.
- http://10.10.11.43/chat
- When clicking
Report User:

- When clicking
here:- http://10.10.11.43/api/contract_source
- Note that we found a URL path
/api/.
- Note that we found a URL path
- http://10.10.11.43/api/contract_source
- When clicking
- Cookies

Since we found a URL path /api/, let's perform directory enumeration using gobuster.
gobuster dir -e -w /usr/share/wordlists/dirb/common.txt -u http://10.10.11.43/api -o gobuster-api.txt
http://10.10.11.43/api/info returns data that includes the user's cookie.
3. XSS
First, let's test if someone reacts to a Report User message.
- Test Payload
As seen above, someone (possibly an admin) reacts to it.
With the execution flow confirmed, we can now proceed to craft the actual payload.
The goal of the payload is to fetch /api/info from that user's browser and exfiltrate the response to our server.
Exploitation Flow:
- Create a JavaScript file
404.jsthat fetches/api/infoand exfiltrates the data to our server via an image request. - Start a Python HTTP server to serve
404.js& capture incoming data. - Submit the XSS payload via
Report User, which loads404.jswhen a non-existent image fails to load.
We successfully received a request containing the URL-encoded cookie from the user's browser.
Let's decode it.
As seen above, the user is admin, and we have obtained their cookie, which allows us to impersonate them and log in.
Let's modify the token cookie and refresh the page.

- When clicking
Admin:
As seen above, we successfully logged in as admin.
4. Burp Suite
- When accessing http://10.10.11.43/admin

POST/api/json-rpc

Referencing https://www.quicknode.com/docs/ethereum/eth_getBlockByNumber, we attempt to query the block data via a JSON-RPC request.
The eth_getBlockByNumber method returns information about a specific block on the Ethereum blockchain, identified by its block number. By setting the second parameter to true, the response includes full transaction objects instead of just their hashes.
POST/api/json-rpc
- Request Payload
{ "jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["0x1", true], "id": 1 } - Response
result->transactions->input- save the
inputfield toinput.txt
- Request Payload
Then, we use the following command to convert the hex-encoded input field into a readable string.
At the end of the decoded string, we find two notable strings.
keira|SomedayBitCoinWillCollapse
5. SSH
Let's try logging in via SSH using the credentials keira | SomedayBitCoinWillCollapse.
As seen above, we successfully logged in as keira.
6. Abusing Sudo (keira -> paul)
After further investigation, we discovered something interesting related to sudo permissions.
We have permission to execute /home/paul/.foundry/bin/forge as paul.
forgeis a CLI tool from the Foundry smart contract development suite, which supports executing local scripts. If misconfigured with FFI enabled, it can be abused to run arbitrary system commands.
Next, we initialize a new Foundry project using forge init:
We then enable FFI (Foreign Function Interface), which allows calling external binaries, by modifying foundry.toml:
Next, we copy the required Forge standard library forge-std (https://github.com/foundry-rs/forge-std) from its online repository to /tmp/lib/, so that our script can import and use it during compilation.
We then create a malicious Solidity script that executes a reverse shell:
Place both scripts under /tmp/privesc/.
Now we can execute our payload. First, let's launch a listener on our Kali machine:
Then execute the malicious script using forge script, which runs as user paul:
As seen above, we successfully obtained a reverse shell as paul.
7. Abusing Sudo (paul -> root)
Now that we are paul, further investigation reveals something interesting related to sudo permissions.
We have root privileges to execute /usr/bin/pacman.
pacmanis the default package manager for Arch Linux and its derivatives. It allows users to install, upgrade, and manage software packages, including custom-built ones.
We prepare a custom PKGBUILD file to create a malicious package that will overwrite /etc/passwd and inject a new root-level user h4ck3r with the password P@55w0rd.
A
PKGBUILDfile is a script used to define how a package should be built, including what files to install and where to place them. By modifying aPKGBUILD, an attacker can create a package that overwrites critical system files, such as/etc/passwd, if installed with elevated privileges.
Build the malicious package:
Install the package and overwrite /etc/passwd:
As seen above, /etc/passwd has been modified.
We can now switch to the newly created user h4ck3r with root privileges:



































