You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here is the beta access to a interactive learning tool of my course
Source code
// index.jsconstexpress=require('express');constdeparam=require('jquery-deparam');const{template}=require('./util.js');constpug=require('pug');constchild_process=require('child_process');constapp=express()constport=3000app.set('view engine','pug')//Configure server-staus options hereoptions={args:["-eo","cpu,args"],options:{"timeout":500}}//I don't trust these modulesObject.seal&&[Object,Array,String,Number].map(function(builtin){Object.seal(builtin.prototype);})//I believe in Defense in Depth and I don't trust the code I write, so here is my wafapp.use((req,res,next)=>{inp=decodeURIComponent(req.originalUrl)constdenylist=["%","(","global","process","mainModule","require","child_process","exec","\"","'","!","`",":","-","_"];for(i=0;i<denylist.length;i++){if(inp.includes(denylist[i])){returnres.send('request is blocked');}}next();});app.get('/',(req,res)=>{varbasic={title: "Pug 101",head: "Welcome to Pug 101",name: "Guest"}varinput=deparam(req.originalUrl.slice(2));if(input.name)basic.name=input.name.Safetify()if(input.head)basic.head=input.head.Safetify()varcontent=input.content? input.content.Safetify() : ''varpugtmpl=template.replace('OUT',content)constcompiledFunction=pug.compile(pugtmpl)res.send(compiledFunction(basic));});app.get('/serverstatus',(req,res)=>{constresult=child_process.spawnSync('ps',options.args,options.options);out=result.stdout.toString();res.send(out)})app.listen(port,()=>{console.log('started')})
// util.js//Copied from https://github.com/Spacebrew/spacebrew/blob/1d8fb258c04cfe65728ce32e0b198032f384d9c3/admin/js/utils.js//static regex and function to replace all non-alphanumeric characters//in a string with their unicode decimal surrounded by hyphens//and a regex/function pair to do the reverseString.SafetifyRegExp=newRegExp("([^a-zA-Z0-9 \r\n])","gi");String.UnsafetifyRegExp=newRegExp("-(.*?)-","gi");String.SafetifyFunc=function(match,capture,index,full){//my pug hates these charactersreturn"b nyan "+capture.charCodeAt(0);};String.UnsafetifyFunc=function(match,capture,index,full){returnString.fromCharCode(capture);};//create a String prototype function so we can do this directly on each string as//"my cool string".Safetify()String.prototype.Safetify=function(){returnthis.replace(String.SafetifyRegExp,String.SafetifyFunc);};String.prototype.Unsafetify=function(){returnthis.replace(String.UnsafetifyRegExp,String.UnsafetifyFunc);};//global functions so we can call ['hello','there'].map(Safetify)Safetify=function(s){returns.Safetify();};Unsafetify=function(s){returns.Unsafetify();};vartemplate=`doctype htmlhtml head title #{title} link(rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css") body h1 #{head}, #{name} p You can learn about Pug interactively on my brand new site! p Note: The pug features are limited, for more pug features you have to subscribe to my course which will be released soon. form(action='/', method='GET') p | name: input( name='name', value='Guest') br | content: textarea( name='content') b hello world input(type='submit', value='Submit') br p Rendered Output: OUT`module.exports={template: template}
Writeup
I checked package.json and found jquery-deparam, so I think it's a challenge about prototype pollution.
But, the prototype has been sealed via Objec.seal:
Description
Here is the beta access to a interactive learning tool of my course
Source code
Writeup
I checked
package.json
and foundjquery-deparam
, so I think it's a challenge about prototype pollution.But, the prototype has been sealed via
Objec.seal
:So, our target is not
Object.prototype
, isString.SafetifyRegExp
. We can polluteString.SafetifyRegExp
to bypassSafetifyFunc
.Like this:
We can use any characters now, and then we can leverage
pug.compile
to do SSTI.global
is blocked but we can usethis
instead,process
also blocked so we need to find another way, I found that we can useoptions.args
:What if we couldn't find all the characters in
options.args
? We can pollute another property as well:Just modify
optinos
if you need a RCE:Then vist
/serverstatus
to see the resultThe text was updated successfully, but these errors were encountered: