https://hack.levels.fyi/ctf_01
<html data-theme="dark">
<link rel="stylesheet" href="<https://cdn.jsdelivr.net/npm/@picocss/pico/css/pico.min.css>">
<link rel="icon" href="<https://img.icons8.com/?id=VzU7PPLtpY2i>">
<meta name="viewport" content="width=device-width">
<title>Levels.fyi Hackathon</title>
<style>
:root, h2 { --pico-font-weight:lighter }
</style>
<app-root style="display:block; padding:1rem">
<hgroup>
<h2>Levels.fyi Hackathon</h2>
<p>Round 02 - CTF</p>
</hgroup>
<!-- ctf_f2dd3fa0bec04d8191376645d2b50dd7 -->
</app-root>
Solution: The flag is directly visible in the HTML source code of the page.
$ curl -s <https://hack.levels.fyi/ctf_01> | grep ctf_
<!-- ctf_f2dd3fa0bec04d8191376645d2b50dd7 -->
Takeaway: Never store secrets directly in HTML source code. They are easily visible to users. As a best practice, avoid writing secrets directly in any code. Instead, use environment variables or secure vault storage and access secrets through appropriate interfaces.
https://hack.levels.fyi/ctf_02
<html data-theme="dark">
<link rel="stylesheet" href="<https://cdn.jsdelivr.net/npm/@picocss/pico/css/pico.min.css>">
<link rel="icon" href="<https://img.icons8.com/?id=VzU7PPLtpY2i>">
<meta name="viewport" content="width=device-width">
<title>Levels.fyi Hackathon</title>
<style>
:root, h2 { --pico-font-weight:lighter }
</style>
<app-root style="display:block; padding:1rem">
<hgroup>
<h2>Levels.fyi Hackathon</h2>
<p>Round 02 - CTF</p>
</hgroup>
<input type="number" placeholder="Enter "CTF"" onkeyup="submit(this, event)">
</app-root>
<script>
function submit(input, event) {
if (event.key !== "Enter") return
fetch("<https://hack.log10.workers.dev>", {
method: "POST",
body: JSON.stringify({ query: input.value }),
})
.then(response => response.text())
.then(alert)
}
</script>
Solution: The input box prompts to enter "CTF", but the input type is set to "number", preventing text entry. There are two ways to solve this:
type="number" to type="text", then submit "CTF".$ curl -sd '{"query":"CTF"}' <https://hack.log10.workers.dev>
ctf_b8aff142efd64275a4fa6b5058ea7fc4
Takeaway: Frontend validations should be used for providing better user experience and error messages, not for securing inputs. Never trust input coming from the client-side; always validate on the server-side.
Reference: https://en.wikipedia.org/wiki/CURL
https://hack.levels.fyi/ctf_03
<html data-theme="dark">
<link rel="stylesheet" href="<https://cdn.jsdelivr.net/npm/@picocss/pico/css/pico.min.css>">
<link rel="icon" href="<https://img.icons8.com/?id=VzU7PPLtpY2i>">
<meta name="viewport" content="width=device-width">
<title>Levels.fyi Hackathon</title>
<style>
:root, h2 { --pico-font-weight:lighter }
</style>
<app-root style="display:block; padding:1rem">
<hgroup>
<h2>Levels.fyi Hackathon</h2>
<p>Round 02 - CTF</p>
</hgroup>
<form style="max-width:500px">
<input name="username" placeholder="Enter Username" required>
<input name="password" placeholder="Enter Password" required>
<button type="submit">Login</button>
</form>
</app-root>
<script>
document.querySelector("form").addEventListener("submit", function(event) {
event.preventDefault()
fetch("<https://hack.log10.workers.dev>", {
method: "POST",
body: JSON.stringify({
username: event.target.username.value,
password: event.target.password.value,
}),
})
.then(response => response.text())
.then(alert)
})
</script>