Skip to content

Instantly share code, notes, and snippets.

@roddux
Created March 27, 2019 22:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roddux/866c95fbb7317cc87f69d271f0d36c54 to your computer and use it in GitHub Desktop.
Save roddux/866c95fbb7317cc87f69d271f0d36c54 to your computer and use it in GitHub Desktop.
In-process JS builtin fuzzing idea
// Inspiration: @5aelo, @_tsuro, @ifsecure, @bkth_
// $ ./spidermonkey/js ./fuck^H^Hzz.js
// A quick thought experiment. A simple in-process template fuzzer using eval.
// Next idea is to generate the template, too. This one was hardcoded to try and find JIT bugs. Perhaps it will, I only ran it for a few hours.
// Can code even be JIT'd if it's being run via eval, though? Idk. Baby steps.
var rc = (x)=>x[Math.floor(Math.random() * x.length)];
var _object = [
"Object()", "{}", "{1:1,2:2,3:3,4:4,5:5}", "{a:1,b:2,c:3,d:4,e:5}",
"Array()", "[]", "Array(10)", "[1,2,3,4,5]", "[1.1,2.2,3.3,4.4,5.5]"
];
var _objarg = ["arg1","arg2"];
var _malobject = [ "{}" ];
var _prop = [ // Stolen from domato
"1", "'1'", "{}", "[]", "undefined", "null", "32768", "65535", "65536", "1073741824",
"536870912", "268435456","4294967295", "2147483648", "2147483647", "-2147483648", "-1073741824", "-32769"
];
var _propline = [
"<arg>[1] = <prop>;",
"<arg>['a'] = <prop>;",
"<arg>.a = <prop>;",
"let _=<arg>[0];"
];
var _builtin = [
"Array.prototype.join.apply( <arg>, [ <element> ] )",
"Array.prototype.toLocaleString.apply( <arg> )",
"Array.prototype.reverse.apply( <arg> )",
"Array.prototype.push.apply( <arg>, [ <element> ] )",
"Array.prototype.pop.apply( <arg> )",
"Array.prototype.shift.apply( <arg> )",
"Array.prototype.unshift.apply( <arg>, [ <element> ] )",
"Array.prototype.splice.apply( <arg>, [ <number> ] )",
"Array.prototype.splice.apply( <arg>, [ <number>, <number> ] )",
"Array.prototype.toSource.apply( <arg> )",
"Array.prototype.slice.apply( <arg> )",
"Array.prototype.slice.apply( <arg>, [ <number>, <number> ] )",
"Array.of( <element> )",
"Array.isArray( <element> )",
"Object.prototype.toSource.apply( <arg> )",
"Object.prototype.toString.apply( <arg> )",
"Object.prototype.isPrototypeOf.apply( <arg>, [ <arg> ] )",
"Object.prototype.propertyIsEnumerable.apply( <arg>, [ <propertyName> ] )",
"Object.assign( <arg>, <arg> )",
"Object.setPrototypeOf( <arg>, <arg> )",
"Object.keys( <arg> )",
"Object.values( <arg> )",
"Object.entries( <arg> )",
"Object.is( <arg>, <arg> )",
"Object.defineProperties( <arg>, <propertyDefinition> )",
"Object.create( <arg> )",
"Object.create( <arg>, <propertyDefinition> )",
"Object.getOwnPropertyNames( <arg> )",
"Object.getOwnPropertySymbols( <arg> )",
"Object.preventExtensions( <arg> )",
"Object.freeze( <arg> )",
"Object.isFrozen( <arg> )",
"Object.seal( <arg> )",
];
var tmpl = `
var a1 = <object>, a2 = <object>;
var p1 = <malobject>, p2 = <malobject>;
var flip = false;
var handle2 = {
get: function(target, prop, receiver) {
if ( flip ) {
a1.a = <prop>; a1[0] = <prop>;
} else {
return Reflect.get(...arguments);
}
}
};
var p1 = new Proxy(a1, handle2);
function opt(arg1, arg2) {
function inline(arg1) {
<builtin>
}
for(let _=0;_<1e2;_++,inline(arg1));
<propline>
if ( flip ) <builtin>;
}
for(var i=0;i<1e4;i++){ opt(a1, a2); }
flip = true;
a1.a = <prop>;
opt(a1,{});
a1.a = <prop>;
opt(p1,{});
`;
// let gc = () => for(j=0;j<10;q = new WebAssembly.Memory({initial: 16384}));
var tags = {
"<object>": _object,
"<prop>": _prop,
"<arg>": _objarg,
"<element>": [NaN,"'abc'",Infinity,0,-1],
"<number>": [1,2,3,4,5,6,7,8,9,0],
"<malobject>": _malobject,
"<propline>": _propline,
"<builtin>": _builtin,
"<propertyDefinition>": ["{}"],
"<propertyName>": ["'length'"],
};
function process(template) {
function toReplace() {
let instances = 0;
Object.keys(tags).forEach(
function (tag) {
// cheers, rebecca
instances += (template.match(RegExp(tag,"g")) || []).length;
}
);
return instances;
}
let ic = toReplace();
while (ic > 0) {
Object.keys(tags).forEach(
function(tag) {
while ( template.indexOf(tag) != -1 ) {
template = template.replace(tag, rc(tags[tag]));
}
}
);
ic = toReplace();
}
return template;
}
console.log("[*] Entering fuzzing loop");
var tnum = 0;
while(true) {
console.log("[*] Preparing template", tnum);
let exec = process(tmpl);
console.log("[*] Displaying template");
console.log(exec);
console.log("[*] Executing template");
try {
eval(exec);
} catch(e) {
console.log("[!] Caught exception");
console.log(e);
}
console.log("[*] Completed fuzzing run");
tnum += 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment