eval()函数中的eval是evaluate的简称,这个函数的作用就是把一段字符串当作PHP语句来执行
php://input
用法: 可以访问请求的原始数据的只读流,将post请求中的数据作为PHP代码执行.
因此可以用php://input 来执行post输入流的命令
例如:?file=php://filter/read=convert.base64-encode/resource=/flag
ping 命令可以测一下与主机网络联通情况。但是如果过滤不严的话,也会导致恶意命令执行。
可以用管道符 来执行我们想执行的命令。
传入 127.0.0.1 | ls
|可以用;代替
可以用 cat tac 获取文件
空格过滤绕过:
${IFS}
$IFS$9
%09
%20
<>
<
我们可以通过改变当前目录路径来 达到 不用/ 直接cat 的效果。
我们使用cd命令进入到flag文件目录。
例如:?ip=127.0.0.1 & cd flag_is_here;ls
题目对管道符 | & || &&,进行了过滤我们可以不用管道符,也能执行命令
传入 ;ls
出来 window&linux 都支持的前四个连接之外
linux 还支持 分号(;) cmd1;cmd2 按顺序执行,先执行cmd1 再执行cmd2
url编码里 %0a代表换行 %0d 代表回车
;被过滤了的话,试着用%0A换行代替一下
用*通配符来过滤
例如:构造:?ip=127.0.0.1%0Acd${IFS}fl*_is_here%0Als
无参数rce
(1) scandir() 函数:
返回指定目录中的文件和目录的数组.
scandir("."):得到该文件下的所有文件和文件夹
(2) print_r() 函数
print_r() 函数用于打印变量,以更容易理解的形式展示。
参数为要打印的变量,如果给出的是 string、integer 或 float 类型变量,将打印变量值本身。如果给出的是 array,将会按照一定格式显示键和元素。object 与数组类似。
(3) localeconv() 函数:
返回一包含本地数字及货币格式信息的数组。而数组第一项就是.
(4) current() 函数:
返回数组中的当前单元, 默认取第一个值。
所以 current(localeconv())两个函数连用,返回的就是 ' . ' 点
注:pos() 是current() 的别名。
(5) array函数
array_reverse() 函数:顾名思义,反转数组。
array_flip() 函数: 反转/交换数组中的键和值,成功则返回交换后的数组,失败返回NULL。
array_rand()函数:从数组中随机取出一个或多个单元,如果只取出一个,返回随机单元的键名。 如果不止一个,返回包含随机键名的数组。第二个参数number默认为1.
键与值反转交换后,数组里 文件名变为了值。array_rand()从数组中随机取出一个单元的键名,不断刷新访问就会不断随机返回,具体题目中多刷新几次就出来flag文件了。
reset()函数:将数组的内部指针指向第一个单元
end()函数:将数组的内部指针指向最后一个单元
next()函数:将数组的内部指针向前移动一位
prev()函数:将数组的内部指针倒回一位
(7) time有关函数
time()函数:返回自 Unix 纪元(January 1 1970 00:00:00 GMT)起的当前时间的秒数。
localtime()函数:返回本地时间。
localtime()函数可以接受参数,并且第一个参数可以直接接受time()
(8) chr()&chdir()&dirname()函数
chr()与ord()互补,返回ascll码对应的字符. 什么时候用呢?
因为当秒数为46时,chr(46)=”.”,可以用来获取点(.) 当localeconv()被过滤时可用。
chr 函数以256为一个周期,所以 chr(46) , chr(302) , chr(558) 都等于 "."
所以使用 chr(time()) ,一个周期必定出现一次 "."
chr(current(localtime(time()))) :
数组第一个值每秒+1,所以最多60秒就一定能得到46,用 current或pos 就能获得 "."
chdir("..")返回上一级目录。scandir()出来的数组里有 . (当前目录) 和 ..(上一级目录)。
print_r(scandir(next(scandir(getcwd))));可查看上级目录文件
dirname():返回上一级目录,路径中的目录部分。
getcwd():返回当前目录。
可用chdir(dirname(getcwd))来更改目录。
(9) file()函数
readfile()函数:读取文件并写入到输出缓冲。 echo(readfile())
readgzfile()函数:readgzfile 也可读文件,常用于绕过过滤
(10)session方法
session_id可以获取PHPSESSID的值,而我们知道PHPSESSID允许字母和数字出现,而flag.php符合条件.因此我们在请求包中cookie:PHPSESSID=flag.php,使用session之前需要通过session_start()告诉PHP使用session,php默认是不主动使用session的。session_id()可以获取到当前的session id。这样可以构造payload:?
exp=readfile(session_id(session_start()));