PHP代码审计(二)——常见漏洞

注入类

命令注入

将用户输入拼接到命令行中执行 导致的任意命令执行问题

<?php
$command = 'ping -c 1 '.$_GET['ip'];
system($command); //system函数特性 执行结果会自动打印
?>

此处输入ip参数无任何过滤限制
get输入ip=127.127.127.127
如果是非法输入:ip=127.127.127.127;whoami,就会执行whoami

遇到不熟悉的php函数就查找对应功能
然后要熟悉Linux、Windows命令行基础语法

在审计的过程中,遇到输入可控的时候,检查是否存在escapeshellarg escapeshellcmd 函数转义 或者是其他的处理方法(如 强制类型转换 替换字符 等),这些方式可以将输入内容中一些特殊字符转义来降低注入风险

常见bash shell 语法

一些常见的可以执行系统命令的函数/语法

代码注入

将用户输入拼接到PHP代码中执行 导致的任意代码执行问题

有些特殊业务使用了eval等代码执行函数,实际业务中要尽量避免使用eval这种动态执行代码方法 必要使用时做好过滤

SQL注入

将用户输入拼接到数据库将要执行的SQL语句中 导致攻击者可以修改原有执行的SQL语句


<?php
include('conn.php');//数据库连接省略
$sql = "SELECT id, name FROM users WHERE id=$_GET['id']";
$result = $mysqli->query($sql);
if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo "id: " . $row["id"]. " - Name: " . $row["name"];
    }
} else {
    echo "没有查询到结果";
}
?>

构造payload:?id=123 UNION SELECT name,password FROM users;

于是会执行:

SELECT id, name FROM users WHERE id=123 UNION SELECT name,password FROM users;

文件包含

将远程/本地文件 包含入当前页面的PHP代码并执行

<?php
$file = $_GET['page']; 
include(“pages/$file”);
?>

//  正常输入:?page=login.php
//  服务器包含并执行pages目录下的login.php

//  攻击者输入 ?page=../image/123.jpg
//  服务器包含并执行pages的上层目录image目录下的123.jpg

该漏洞通常需要参数后半部分可控或者参数完全可控才存在。当代码运行环境php版本小于5.3.4且 php的magic_quotes_gpc为OFF状态时 参数在中间拼接也可利用 (CVE-2006-7243)
这是个PHP本身的问题 不是代码的问题 解决方法: 升级PHP

参数在中间拼接时 如果用户仍可向拼接出的文件进行写入则可以利用,如 include(“pages/$file.tpl”);

假设用户不能上传php文件 但可上传tpl文件

可以上传一个tpl文件 构造路径包含tpl文件 执行php代码

文件包含利用方法:

  • 包含上传文件 (上传头像图片等)
  • 包含 data:// php://filter 或 php://input 伪协议 (php.ini allow_url_include 设置为 on)
  • 包含日志 Apache nginx 等web服务器访问日志 SSH FTP 等登陆错误日志 PHP框架日志
  • 包含 /proc/self/environ (必须是有proc伪文件系统的操作系统 比如LINUX) 当前进程的环境变量(PHP会将HTTP头 请求URI等信息写入当前进程环境变量)
  • 包含 session文件 (通常在临时目录下 (linux /tmp/ ) sess_会话ID文件)
  • PHP间接或直接创建的其他文件 比如数据库文件 缓存文件 应用日志等

文件操作

文件操作相关关键参数用户可控 导致文件/目录 删除/移动/写入(上传)/读取等

全部文件操作函数可参考PHP官方手册 (几乎大部分文件操作函数都可用于ssrf phar反序列化)

1、文件删除、目录删除

unlink(文件路径)//删除文件
rmdir(文件夹路径)//删除目录

攻击者可以尝试删除lock文件,解除重复程序安装保护等安全限制,或者尝试删除网站关键文件,让网站拒绝服务、数据丢失等

2、文件写入、上传

文件写入
file_put_contents(路径,写入字符串);//直接将字符串写入文件(不存在会自动创建)

$fp = fopen(文件路径, "w");//以写入模式打开一个文件 返回文件指针(不存在会自动创建)
fwrite($fp,写入字符串);//写入数据
fclose($fp);//关闭文件

文件上传
move_uploaded_file(临时上传文件路径,目标文件路径);//移动临时上传文件

php收到post上传表单,会将上传文件保存到临时目录,如果内容不为空,就执行php文件处理逻辑,然后移动临时文件到保存位置。请求结束后,如果临时文件没有被移走就会被自动删除。从写入文件到删除文件有个短暂的窗口时间,可以用于文件包含

3、文件解压

$zip = new \ZipArchive;
$zip->open('test_new.zip', \ZipArchive::CREATE) //打开一个zip文件
$zip->addFile('test.txt'); //添加压缩文件
$zip->addEmptyDir('newdir');//添加空目录
$zip->addFromString('new.txt', '文本');//从字符串添加文件到压缩包
$zip->extractTo('upload');//将压缩包文件解压到upload目录下
$zip->close();//关闭zip

审计时重点查找 extractTo方法

注:ZipArchive扩展在windows平台 php版本>5.6时默认安装. linux及windows其他版本需要手动编译安装.

判断解压目录是否在web目录下 是否检查压缩包内文件类型 如果不在web目录下也可以使用.. 进行目录穿越控制上传目录 到web目录下 或者在权限足够的情况下写入文件到系统关键目录 (自启动 定时任务 ssh公钥 覆盖shadow 等)

4、文件读取

XSS

让用户浏览器执行攻击者指定的JS脚本代码

1、反射型: 服务器后端处理时把处理不当的用户输入输出到网页 导致用户浏览器执行恶意代码

<?php
echo 'Hello '.$_GET['name'].'!';


正常输入: ?name=cz
服务器返回 Hello cz!
浏览器渲染纯文本 Hello cz!


攻击者输入: ?name=<script type="text/javascript">alert('XSS!');</script>
服务器返回 Hello <script type="text/javascript">alert('XSS!');</script>!
浏览器渲染 Hello !  script被作为html标签解析 执行其中的代码 弹出警告框XSS!

审计时注意 PHP常使用 htmlspecialchars 和 htmlentities函数 转义用户的输入作为防护

2、存储型:将服务器储存的处理不当的用户输入输出到网页 导致用户浏览器执行恶意代码

攻击者输入->服务器储存,攻击者得到一个返回储存值的页面
被害者请求页面->服务器调用储存并输出->XSS

常见于评论、留言、文章等。该漏洞需要同时联合查看储存与输出 有时业务复杂 多写入点 多输出点 不易发现

比如 发布评论 攻击者发布带有恶意代码的评论 被害者访问评论展示页面 触发XSS 后台管理员审核评论时 触发XSS

再比如 用户系统设置昵称时 攻击者将昵称写入数据库 在评论显示时读取数据库值输出用户昵称

3、DOM型
与浏览器前端DOM渲染有关

SSRF

服务端请求伪造,让服务器发起攻击者指定的请求(HTTP/HTTPS/TCP/UDP 等),攻击者通常用来访问/攻击内网服务 获取内网信息 绕过ip限制
SSRF的函数几乎和文件读取操作一样 php中绝大多数文件读取/写入操作函数都支持多种协议(包括HTTP/S FTP 伪协议 等)

漏洞可能存在点:远程图片下载

CSRF

跨站请求伪造

1、表单请求

攻击者使被害者的浏览器在用户不知情的情况下发起目标网站表单请求 这些表单常常带有目标网站的用户cookies 可以以用户在目标网站的身份进行操作 (攻击者不能获取cookies)

检查鉴权后的操作是否添加token/Referrer校验 拒绝空Referrer

2、JSONP请求

除了表单常见的还有jsonp请求 服务器返回一段带有函数调用的json 浏览器把jsonp页面当做js加载执行 调用回调函数将数据传入函数 用于浏览器从服务器动态获取信息 由于js等静态资源调用浏览器默认放行 造成了风险

(get表单也可以使用这种方式发起请求 但是无法获取服务器返回的内容)

可获取用户登陆后才能获取的信息 比如登陆用户个人资料 账户余额 等

检查Referrer 拒绝空Referrer

3、AJAX请求

一种使用js动态加载数据的技术

浏览器会先发送一个HEAD请求 获取HTTP头 检查Access-Control-Allow-Origin等Access-Control安全策略

这会决定是否发起带有目标域浏览器cookies的请求 如果没有头或不符合策略则拒绝请求

审计时检查 HTTP是否错误地添加"Access-Control-Allow-Origin:*" 头

XXE

XML外部实体(注入) 攻击者利用xml的性质可以获取本地/远程文件内容 (不同于其他语言 PHP中xml实体可以使用PHP伪协议)

审计时注意检查下表函数,如有使用,检查是否禁用了外部实体

libxml_disable_entity_loader(true); //禁用外部实体使用到的函数 参数为true时禁用

注意: php环境中libxml 版本>=2.9.0时外部实体默认禁用 (PHP版本 >=8.0时 就开始使用>=2.9.0版本的libxml 且libxml_disable_entity_loader函数被完全废弃 使用该函数会抛出错误)

漏洞可能存在点:支付等回调api

反序列化

LDAP注入

其他漏洞

参考文章

https://www.yuque.com/burpheart/phpaudit/php-chang-jian-lou-dong_page-11

posted @ 2024-03-28 17:24  smile_2233  阅读(6)  评论(0编辑  收藏  举报