IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 『PHP内核』PHP 7 escapeshellarg底层探究 -> 正文阅读

[PHP知识库]『PHP内核』PHP 7 escapeshellarg底层探究

escapeshellarg描述

escapeshellarg把字符串转义为安全的shell参数

escapeshellarg(string $arg): string
  • Linux:对传入的字符串用一对单引号包围,将内容的'先用反斜杠转义,再添加一对单引号包围,即单引号会被转义为'\''
  • Windows:对传入的字符串用一对双引号包围,将内容的"%!以空格替换

歧义

PHP Manual中文版翻译为:给字符串增加一个单引号

在这里插入图片描述

静态调试

PHP_FUNCTION(escapeshellarg)

函数大概和之前分析过的它的兄弟escapeshellcmd类似

『PHP内核』PHP 7 escapeshellcmd底层探究 CSDN@Ho1aAs

在这里插入图片描述

第510行判断传入参数的有效性不同于escapeshellcmd:后者是以传入字符串的长度验证的,而这里是直接以字符串本身来判断,因此传入任何变量都能够进入这个if,即使是NULL;另外:escapeshellcmd在这里还有个else返回空字符串的操作

在这里插入图片描述

第二步检验是否传入了空字符,没有则进入功能实现函数,最后通过RETVAL返回转义后的字符串

PHPAPI zend_string *php_escape_shell_arg(char *str)

进入到PHPAPI类的函数实现

在这里插入图片描述

estimate是预估转义后的最大字符串长度,最大长度是Linux下传入单引号的情况:一个单引号被转义成'\'',然后整个字符串用一堆单引号包裹,再加上最后的结束符,因此是4l+3;然后就是判断传入字符串是否超过了最大单行命令的长度,条件见注释

	uint64_t estimate = (4 * (uint64_t)l) + 3;

	/* max command line length - two single quotes - \0 byte length */
	if (l > cmd_max_len - 2 - 1) {
		php_error_docref(NULL, E_ERROR, "Argument exceeds the allowed length of %zu bytes", cmd_max_len);
		return ZSTR_EMPTY_ALLOC();
	}

给返回值cmd分配内存,大小为4l+2

	cmd = zend_string_safe_alloc(4, l, 2, 0); /* worst case */

添加前面的引号

然后就是第一步给返回值的第一个字符赋值为引号:Windows是双引号、Linux是单引号

#ifdef PHP_WIN32
	ZSTR_VAL(cmd)[y++] = '"';
#else
	ZSTR_VAL(cmd)[y++] = '\'';
#endif

跳过多字节字符

处理方式同escapeshellcmd

在这里插入图片描述

PHP历史漏洞:GBK宽字节注入

同理这一部分也是在PHP 5.2.6 之后加入以修复漏洞

转义

遍历字符转义,分平台

  • Windows将"%!直接以空格替换
  • Linux将'首先以反斜杠转义再套上一对单引号,实际操作是自左向右的,借用了default

default是无需转义,直接向cmd赋值

		switch (str[x]) {
#ifdef PHP_WIN32
		case '"':
		case '%':
		case '!':
			ZSTR_VAL(cmd)[y++] = ' ';
			break;
#else
		case '\'':
			ZSTR_VAL(cmd)[y++] = '\'';
			ZSTR_VAL(cmd)[y++] = '\\';
			ZSTR_VAL(cmd)[y++] = '\'';
#endif
			/* fall-through */
		default:
			ZSTR_VAL(cmd)[y++] = str[x];
		}
	}

添加后面的引号

接下来是添加后面的引号,这里对于Windows在这之前多处理了一步:如果字符串末尾是个反斜杠需要再用反斜杠转义,为了防止逃出双引号执行命令

#ifdef PHP_WIN32
	if (y > 0 && '\\' == ZSTR_VAL(cmd)[y - 1]) {
		int k = 0, n = y - 1;
		for (; n >= 0 && '\\' == ZSTR_VAL(cmd)[n]; n--, k++);
		if (k % 2) {
			ZSTR_VAL(cmd)[y++] = '\\';
		}
	}

	ZSTR_VAL(cmd)[y++] = '"';
#else
	ZSTR_VAL(cmd)[y++] = '\'';
#endif
	ZSTR_VAL(cmd)[y] = '\0';

然后就是添加结束符

检查结果有效性返回

判断转义结果的长度是否有效、判断分配空间是否溢出

	if (y > cmd_max_len + 1) {
		php_error_docref(NULL, E_ERROR, "Escaped argument exceeds the allowed length of %zu bytes", cmd_max_len);
		zend_string_release(cmd);
		return ZSTR_EMPTY_ALLOC();
	}

	if ((estimate - y) > 4096) {
		/* realloc if the estimate was way overill
		 * Arbitrary cutoff point of 4096 */
		cmd = zend_string_truncate(cmd, y, 0);
	}
	ZSTR_LEN(cmd) = y;
	return cmd;
}

登记cmd的长度,返回转义结果

动态调试

测试代码:

// test.php
<?php
  	echo escapeshellarg('"\\');

断点:

在这里插入图片描述

先把前面的双引号添加了

在这里插入图片描述

然后遍历字符串:第一个字符是双引号,需要转义,直接被空格替换,存入cmd,然后break跳出当前switch,读入下一个字符

在这里插入图片描述

第二个字符是反斜杠,无需转义,存入cmd

在这里插入图片描述

转义结束,之后检测末尾是否是反斜杠,是就再将其转义一次

在这里插入图片描述

添加后面的引号,加上结束符截断

在这里插入图片描述

检查结果有效,完成操作,返回

在这里插入图片描述

欢迎在评论区留言,欢迎关注我的CSDN @Ho1aAs

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-10-23 12:16:55  更:2021-10-23 12:17:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 13:54:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计