无参数RCE
一道bytectf的题和一道GXYCTF的题,主要内容为bytectf的wp。两题均为无参数的命令执行,正则匹配如下
/[a-z]+\((?R)?\)/
/[a-z,_]+\((?R)?\)/
第一个较为严格,只允许纯字母函数的无参数调用。
第二个允许了下划线,和逗号,难度直线下降,允许了有参数的函数调用,即a(b(),c())
,允许匹配到,c()
这样子的函数名
(?R)表示引用当前正则表达式,?匹配一次或零次
今天在做什么第五届上海大学生网络安全大赛的一道题,好像是安恒月赛的一道题,感觉题目问题也挺大,有机会自己搭环境搞一搞,对着wp复现了一遍
<?php
highlight_file(__FILE__);
$x = $_GET['x'];
$pos = strpos($x,"php");
if($pos){
exit("denied");
}
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,"$x");
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$result = curl_exec($ch);
echo $result;
首先得想办法对strpos进行绕过,按常理来说我们如果把php放在最前面就可以绕过个strpos函数,但是curl不支持PHP伪协议(可用curl –version查看支持的协议),于是出现了这个二次编码绕过
用%2570代替p即可绕过对于strpos的检验,详见https://bugs.php.net/bug.php?id=76671&edit=1
事实上个人感觉是数据发送到服务器端进行第一次解码,而curl发起第二次请求时进行了第二次的解码,也就意味着这并不是strpos的问题,而是一个来自二次编码绕过的问题
记录一个获得了马师傅肯定的题目
<?php
highlight_file(__FILE__);
$b = 'implode';
call_user_func($_GET['f'], $_POST);
session_start();
if (isset($_GET['name']))
{
$_SESSION['name'] = $_GET['name'];
}
var_dump($_SESSION);
$a = array(reset($_SESSION), 'welcome_to_the_lctf2018');
call_user_func($b, $a);
?>