Latin1 was the early default character set for encoding documents delivered via HTTP for MIME types beginning with /text . Today, only around only 1.1% of websites on the internet use the encoding, along with some older applications. However, it is still the most popular single-byte character encoding scheme in use today. A funny thing about Latin1 encoding is that it maps every byte from 0 to 255 to a valid character. This means that literally any sequence of bytes can be interpreted as a valid string. The main drawback is that it only supports characters from Western European languages. The same is not true for UTF8. Unlike Latin1, UTF8 supports a vastly broader range of characters from different languages and scripts. But as a consequence, not every byte sequence is valid. This fact is due to UTF8's added complexity, using multi-byte sequences for characters beyond the general ASCII range. This is also why you can't just throw any sequence of bytes at it and ex...
While scrolling twitter recently I saw Intigriti linked to some JavaScript bookmarklet for discovering API endpoints. When doing reconnaissance, sometimes tools like ffuf aren't fine-grained enough for enumerating API endpoints. On the contrary however, interacting with an app in the browser is much more personal and can often reveal API endpoints other tools might miss. We can use the browser developer console and JavaScript to our advantage here:
(function () {
const scripts = document.getElementsByTagName("script");
const regex = /(?<=(\"|\'|\`))\/[a-zA-Z0-9_?&=\/\-\#\.]*(?=(\"|\'|\`))/g;
const results = new Set();
for (let i = 0; i < scripts.length; i++) {
const src = scripts[i].src;
if (src !== "") {
fetch(src)
.then((response) => response.text())
.then((text) => {
const matches = text.matchAll(regex);
for (const match of matches) {
results.add(match[0]);
}
})
.catch((error) => {
console.log("An error occurred: ", error);
});
}
}
const pageContent = document.documentElement.outerHTML;
const pageMatches = pageContent.matchAll(regex);
for (const match of pageMatches) {
results.add(match[0]);
}
function writeResults() {
results.forEach((result) => {
document.write(result + "
");
});
}
setTimeout(writeResults, 3000);
})();
Comments
Post a Comment