首页 > 编程语言 >PHP代码审计——Day 5-postcard

PHP代码审计——Day 5-postcard

时间:2024-04-04 11:22:22浏览次数:27  
标签:shell string postcard filter escapeshellarg PHP data Day 函数

漏洞解析

class Mailer {
  private function sanitize($email) {
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
      return '';
    }

    return escapeshellarg($email);
  }

  public function send($data) {
    if (!isset($data['to'])) {
      $data['to'] = '[email protected]';
    } else {
      $data['to'] = $this->sanitize($data['to']);
    }

    if (!isset($data['from'])) {
      $data['from'] = '[email protected]';
    } else {
      $data['from'] = $this->sanitize($data['from']);
    }

    if (!isset($data['subject'])) {
      $data['subject'] = 'No Subject';
    }

    if (!isset($data['message'])) {
      $data['message'] = '';
    }

    mail($data['to'], $data['subject'], $data['message'],
      '', "-f" . $data['from']);
  }
}

$mailer = new Mailer();
$mailer->send($_POST);

考察点:php内置函数mail引发的命令执行漏洞

bool mail (
	string $to , // 接收人
	string $subject , // 邮件标题
	string $message [, // 邮件正文内容
	string $additional_headers [, // 指定邮件发送时其他的额外头部,如发送者From,抄送CC,隐藏抄送BCC
	string $additional_parameters ]]// 指定传递给发送程序sendmail的额外参数
)

程序中使用filter_var函数来确保只使用有效的邮件地址。关于FILTER_VALIDATE_EMAIL在这篇帖子中有个结论:所有的特殊符号必须放在双引号中

filter_var() 问题在于,在双引号中嵌套转义空格仍然能够通过检测。同时由于底层正则表达式的原因,我们通过重叠单引号和双引号,欺骗 filter_val() 使其认为我们仍然在双引号中,这样我们就可以绕过检测。

php中,mail函数的底层实现调用了escapeshellcmd() :PHP 中用于转义 shell 命令中的特殊字符的函数。它将会转义任何 shell 命令中具有特殊含义的字符,使得这些字符在 shell 中被当作字面量对待,从而避免了命令注入漏洞的发生。

程序中,当对$email进行有效性检查之后,会作下一步处理,return escapeshellarg($email);

escapeshellarg把字符串转码为可以在 shell 命令里使用的参数

  • 功能 :escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,shell 函数包含 exec(),system() 执行运算符(反引号)
  • 定义 :string escapeshellarg ( string $arg )

由于PHP的 mail() 函数在底层调用了 escapeshellcmd() 函数对用户输入的邮箱地址进行处理,即使使用带有特殊字符的payload,绕过 filter_var() 的检测,但还是会被 escapeshellcmd() 处理。然而 escapeshellcmd() 和 escapeshellarg 一起使用,会造成特殊字符逃逸

demo:

<?php
$param = "127.0.0.1' -v -d a=1";
$a = escapeshellarg($param);
// $a: '127.0.0.1'\' '-v -d a=1'

$b = escapeshellcmd($a);
// $b: '127.0.0.1'\\' '-v -d a=1\'
//  这里 \\ 被解释成了 \ 而不再是转义字符

$cmd = "curl ".$b;
// $cmd : curl 127.0.0.1\ -v -d a=1'
// 即向 127.0.0.1\ 发起请求,POST 数据为 a=1'

var_dump($a)."\n";
var_dump($b)."\n";
var_dump($cmd)."\n";
system($cmd);
?>

总结一下,这题实际上是考察绕过 filter_var() 函数的邮件名检测,通过 mail 函数底层实现中调用的 escapeshellcmd() 函数处理字符串,再结合 escapeshellarg() 函数,最终实现参数逃逸,导致远程代码执行。

标签:shell,string,postcard,filter,escapeshellarg,PHP,data,Day,函数
From: https://www.cnblogs.com/smile2333/p/18113990

相关文章

  • PHP代码审计——Day 4-False Beard
    漏洞解析classLogin{publicfunction__construct($user,$pass){$this->loginViaXml($user,$pass);}publicfunctionloginViaXml($user,$pass){if(//防止输入的参数含有<和>符号(!strpos($user,'<')||!strpos($user,'&......
  • PHP代码审计——Day3-Snow Flake
    漏洞解析//实现了一个基本的MVC(Model-View-Controller)结构,通过动态加载控制器类和数据,并调用控制器的方法来实现基本的页面渲染。//自动加载函数,用于动态加载类文件。当使用尚未定义的类时,PHP会自动调用该函数来加载类文件。此处,__autoload函数会尝试加载与类名$className......
  • 稀碎从零算法笔记Day37-LeetCode:所有可能的真二叉树
    今天的每日一题,感觉理解的还不够深,有待加深理解题型:树、分治、递归链接:894.所有可能的真二叉树-力扣(LeetCode)来源:LeetCode题目描述给你一个整数 n ,请你找出所有可能含 n 个节点的 真二叉树 ,并以列表形式返回。答案中每棵树的每个节点都必须符合 Node.val==0 ......
  • 稀碎从零算法笔记Day36-LeetCode:H指数
    有点绕的一个题,题目描述的有点奇怪(可以看下英文?)题型:数组、模拟链接:274.H指数-力扣(LeetCode)来源:LeetCode题目描述给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。根据维基百科上 h指数......
  • 代码随想录算法训练营三刷day44 | 动态规划之 完全背包 518. 零钱兑换 II 377. 组合总
    三刷day44完全背包基础知识问题描述举个栗子518.零钱兑换II1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组377.组合总和Ⅳ1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例来推导dp......
  • 【每日C语言】Day6——变量与操作符
    目录2.4变量4.1变量的创建4.2 变量的分类2.5算术操作符:+、-、*、/、%5.1+和-5.2 *5.3 /5.4%2.6赋值操作符:=和复合赋值6.1 连续赋值6.2复合赋值符2.7单目操作符:++、--、+、-7.1++和--7.1.1 前置++ 7.1.2 后置++7.1.3 前置--7.1.4 后置--7.2+和......
  • 轻松玩转书生·浦语大模型趣味 Demo——day2笔记
    本节课有四个任务:学习部署、玩角色扮演的agent项目,玩数学运算agent、玩写作agent 主要学习过程就是跟着视频,复制学习文档里的资料,完成demo的使用。主要目的是熟悉开发平台。视频:轻松玩转书生·浦语大模型趣味Demo_哔哩哔哩_bilibili资料:Tutorial/helloworld/hello_world.......
  • JAVA语言学习-Day2
    参考教学视频:秦疆Java流程控制Scanner工具包(java5新特性)Scanners=newScanner(System.in);//创建对象,接收接盘数据if(s.hasNext()){  Stringa=s.next();}if(s.hasNextLine()){  Stringa=s.nextLine();}s.close();if选择结构if(boolean){  }elseif(bool......
  • PHP加密之openssl加密
    直接上代码<?php//加密数据functionencryptData($data,$encryption_key,$iv){returnopenssl_encrypt($data,'aes-256-cbc',$encryption_key,0,$iv);}//解密数据functiondecryptData($data,$encryption_key,$iv){returnopenssl_decrypt($data,......
  • phpstudy php8.2.9版本问题
    1、如果php8的扩展控制面板开启无效的话,可以手动开启试试2、php有报错日志:Fatalerror:Directive'track_errors'isnolongeravailableinPHPinUnknownonline0在切换php版本到更高版本时在终端查看php版本时报如下界面错误现在的环境是从php7版本切换到php8版本,所以......