Custom Web Server (1)
题目描述
Someone said: 'One advantage of having a homemade server is that it becomes much harder to hack.' Do you agree? Give reasons.
Note: The files in src/public
are unrelated for the challenge.
Chilli Level:
Someone said: 'One advantage of having a homemade server is that it becomes much harder to hack.' Do you agree? Give reasons.
Note: The files in src/public
are unrelated for the challenge.
Chilli Level:
I made a ERCode generator! Featuring red-blue encoding, looks more colorful than QRCode, right?
Flag is in the ERCodes.
"A QA engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 99999999999 beers. Orders a lizard. Orders -1 beers. Orders a ueicbksjdhd."
I am working on yet another CTF platform. I haven't implement all the features yet, but I am confident that it is at least secure.
Thanks to Poe I coded a webpage to PDF in seconds! I am genius right?
Chilli Level:
该网站是一个可以发布帖子的网站,同时可以上传图片,所以在源码中关注一下图片上传的地方有没有漏洞
观察源码我们可以发现,这里对每张上传的图片都用 convert
函数进行了处理
router.post(
"/post",
AuthRequired,
fileUpload({
limits: {
fileSize: 2 * 1024 * 1024,
},
}),
ValidationMiddleware("post", "/forum"),
async function (req, res) {
const { title, message, parentId, ...convertParams } = req.body;
if (parentId) {
const parentPost = await db.getPost(parentId);
if (!parentPost) {
req.flashError("That post doesn't seem to exist.");
return res.redirect("/forum");
}
}
let attachedImage = null;
if (req.files && req.files.image) {
const fileName = randomBytes(16).toString("hex");
const filePath = path.join(__dirname, "..", "uploads", fileName);
try {
const processedImage = await convert({
...convertParams,
srcData: req.files.image.data,
format: "AVIF",
});
await fs.writeFile(filePath, processedImage);
attachedImage = `/uploads/${fileName}`;
} catch (error) {
req.flashError(
"There was an issue processing your image, please try again."
);
console.error("Error occured while processing image:", error);
return res.redirect("/forum");
}
}
const { lastID: postId } = await db.createPost(
req.session.userId,
parentId,
title,
message,
attachedImage
);
if (parentId) {
return res.redirect(`/forum/post/${parentId}#post-${postId}`);
} else {
return res.redirect(`/forum/post/${postId}`);
}
}
);
拿到一个 .bin
文件,使用 binwalk
解压此固件
使用 nc 连接给的机子,发现需要登录一个 shell 才能进入,所以我们需要在固件中寻找用户名和密码
使用 grep
命令查找 login
关键字
Our SOC has identified numerous phishing emails coming in claiming to have a document about an upcoming round of layoffs in the company. The emails all contain a link to diagnostic.htb/layoffs.doc. The DNS for that domain has since stopped resolving, but the server is still hosting the malicious document (your docker). Take a look and figure out what's going on.
点击页面中的所有按钮,发现整个网站只有登录和注册两个功能,所以我们在源码中关注这两个功能。
在源码中全局搜索 flag
后,在 ProfileController
中发现了读取 flag
的代码。
public function index() {
$token = (string) $_COOKIE["token"] ?? null;
$flag = file_get_contents(filename: APPPATH . "/../flag.txt");
if (isset($token)) {
$key = (string) getenv("JWT_SECRET");
$jwt_decode = JWT::decode($token, new Key($key, "HS256"));
$username = $jwt_decode->username;
if ($username == "administrator") {
return view("ProfilePage", [
"username" => $username,
"content" => $flag,
]);
} else {
$content = "Haven't seen you for a while";
return view("ProfilePage", [
"username" => $username,
"content" => $content,
]);
}
}
}
点击页面的按钮后发现提示 This game is currently available only from dev.apacheblaze.local.
在源码中搜索这个域名,找到对应处理函数
@app.route('/', methods=['GET'])
def index():
game = request.args.get('game')
if not game:
return jsonify({
'error': 'Empty game name is not supported!.'
}), 400
elif game not in app.config['GAMES']:
return jsonify({
'error': 'Invalid game name!'
}), 400
elif game == 'click_topia':
print(request.headers)
if request.headers.get('X-Forwarded-Host') == 'dev.apacheblaze.local':
return jsonify({
'message': f'{app.config["FLAG"]}'
}), 200
else:
return jsonify({
'message': 'This game is currently available only from dev.apacheblaze.local.'
}), 200
else:
return jsonify({
'message': 'This game is currently unavailable due to internal maintenance.'
}), 200
观察 game.js
源码
if (data.status === "game_over") {
alert(`Game Over! Your score: ${data.score}`);
reset_game();
} else if (data.status === "win") {
window.location.href = `${data.url}`;
} else {
snake = data.snake;
food = { x: data.food[0], y: data.food[1] };
score = data.score;
draw();
}