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里面的内容(同一目录)

2.打开BP,进行流量抓包

3.查看当前目录下有没有我们需要的文件

正常来说,我们可以通过print_r(scandir('.'));可以用来查看当前目录所有文件名,但是正则过滤了'.',所以我们需要构造出这个'.';

方法一:current(localeconv() )

current()返回数组中的单元,默认取第一个值,别名pos()。如果都被过滤还可以使用reset()

方法二:chr(46)

chr(46)就是字符"."

怎么构造46呢,因为函数要无参数

chr(current(localtime(time()))):

数组第一个值每秒+1,所以最多60秒就一定能得到46,用current(pos)就能获得"."

这里的Array[0]每过一秒值加一,一分钟内至少得到一个46

这里得到这个"."了

这里我们就得到了当前目录下的所有文件及目录了!

这里还有另外一种思路:上面通过构造点的方式其实就是相对路径,我们还可以通过绝对路径的方式来展示当前路径下的文件

getcwd() --- 取得当前工作目录

这不是跟之前构造"."一样的效果嘛

4.读取文件内容

我们可以通过show_source(),readfile、highlight_file、readgzfile()等读文件函数都可以

注意:只可以读取文件,目录是不行的!

在此之前我们需要获取文件名,而获取文件名的方法有以下几种:

1.current(),返回数组第一个元素

2.end(),数组指针指向最后一个元素,也就是返回数组最后一个元素

3.next(),将数组的指针向后移动一位。就是第二个元素

介绍一个函数:array_reverse() 以相反的元素顺序返回数组

zlag.php(flag.php)本来在最后一位,反过来就成为第一位,可以直接用current(pos)读取

show_source(current(array_reverse(scandir(getcwd()))));

如果是倒数第二个我们可以用:

show_source(next(array_reverse(scandir(getcwd()))));

如果文件不是在前两个或者后两个位置,那有没有什么方法可以读取到呢?换个说法,有什么方法可以获取任意位置文件的文件名呢?

我们可以使用array_rand(array_flip()),array_flip()是交换数组的键和值,array_rand --- 从数组中随机取出一个或多个随机键

通过这种方式我们可以随机获取到当前路径下的文件名或目录名

这不就是flag嘛。多随机几次就有了

5.获取上一级目录的文件

再介绍几个函数:

1.dirname() :返回路径中的目录部分

当然了,这里是可以叠加的

这样就算文件在哪里都能获取到了

2.构造".."

print_r(next(scandir(getcwd())));:我们scandir(getcwd())出现的数组第二个就是"..",所以可以用next()获取

获取上一级目录的内容:

直接这样:readfile(array_rand(array_flip(scandir(dirname(getcwd()))))) 是不行的

因为默认是在当前工作目录寻找并读取这个文件,而这个文件在上一层目录,所以要先改变当前工作目录

show_source(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd())))))));

相关推荐
用户962377954483 天前
VulnHub DC-3 靶机渗透测试笔记
安全
叶落阁主4 天前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
用户962377954486 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机6 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机6 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954486 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star6 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954486 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
cipher8 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
一次旅行11 天前
网络安全总结
安全·web安全