2023-强网杯web-thinkshop

这题应该在出题的时候就有提供docker环境,也就是说比赛的时候就有考ctfer搭建docker环境的能力,我看了网上大佬的wp,也侧面验证了,所以从搭建环境开始
docker load < thinkshop.tar
docker导入环境

docker run -tid --name thinkshop -p 36000:80 -e FLAG=flag{test_flag} thinkshop
部署该docker环境

sudo docker start thinkshop
运行该环境

sudo docker exec -it thinkshop /bin/bash
进入该环境的终端

sudo docker stop thinkshop
停止该环境

访问http://127.0.01:36000/

图片显示的是我有进行更改的
image
在网站根目录进行观察,查看index.php
image
这与我们直接访问网站也就是http://127.0.01:36000/,自动跳转的路径是一样的,那么我们就找到了一点线索
image
我们到public查看index.php
根据图片我们能看出真正有用的代码在application目录
image
分析

/var/www/html
├── index.php               ← Web 入口(跳转用)
├── public/
│   ├── index.php           ← 真正的入口文件(ThinkPHP启动)
│
├── application/
│   ├── index/              ← 默认模块(index 模块)
│       ├── controller/     ← 控制器目录
│       ├── model/          ← 模型目录
│       ├── view/           ← 视图目录
│
├── thinkphp/              ← 框架核心

/index.php/index/index/index
└──模块 └控制器└方法

等价于调用

URL段 解析含义
index 模块名(/application/index/)
index 控制器名(/controller/Index.php
index 方法名(Index 控制器中的 index() 函数)

👉 最终执行:
application/index/controller/Index.php 里的 index() 方法

image

root@cb45d412bcad:/var/www/html/application/index/controller# ls ../model/ 
Goods.php  Select.php  Update.php
root@cb45d412bcad:/var/www/html/application/index/controller# cat ../model/Goods.php
    public function getGoodsList()
    {

        $select = new Select();
        return $select->select('goods');
    }

    public function getGoodsById($id)
    {
        $select = new Select();
        $data = $select->select('goods', 'id', $id);
        if (!empty($data[0]['data']) && substr($data[0]['data'], 0, 3) !== "YTo")
            {
                $this->error("数据错误" , 'index/admin/goods_edit');
            }
        return $data;
    }

根据代码我们可以看出存在数据库查询,我们到数据库查看
root/root
我们可以看到其存在shop的数据库,以及admin和goods的表
image

md5的123456
应该存在后台等登录的地方
/var/www/html/application/index/controller/Admin.php
根据前面分析的方法
我们调用Admin中的index方法校验身份
http://127.0.0.1:36000/public/index.php/index/admin/index
image

判断正确,跳转到
http://127.0.0.1:36000/public/index.php/index/admin/login.html
我们尝试用在数据库中的admin表中的数据
进行登录
image

很疑惑,为什么不对,去看看代码
image

这里存在获取参数校验,并写入session的操作

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')
      ->cache(true, $Expire)
      ->find($username);//⬅️在这

    if ($adminData && $adminData['password'] === $encryptedPassword) {
      // 登录成功,设置session
      session('admin', $adminData['username']);


      $this->success($username.'登录成功', 'index/admin/goods_edit');
    } else {
      $this->error('用户名或密码错误');
    }

一下是GPT的分析结果,关键在find()的使用上面
->find($username) —— 执行“查一条”操作(传参表示按主键查找)
● find() 在 ThinkPHP 中是一个用来获取单条记录的方法。它可以:
○ 不带参数时:以查询构造器当前条件为准,取第一条匹配记录(等同 limit 1)。
○ 带一个标量参数(如 find($id)):框架会把这个参数当作 主键值 来构建查询(等价于 WHERE <主_key> = $id),然后返回该条记录。
○ 也可以传数组作为条件(但这里传的是一个标量 $username)。
● 因此 find($username) 的语义是:以主键 = $username 去查 admin 表。这暗示要么:
○ admin 表的主键就是 username 字段(常见),
○ 要么主键是其他列(如 id),那此调用会变成 WHERE id = ''(这在语义上就不同了,可能返回空)。
也就是说用户名应该是id
image

果然,username用的是数据库中的id的值
登录成功
,到这里就卡住了,应该是利用admin能够触发到的页面而不同用户触发不到的页面
到达该目录下

root@cb45d412bcad:/var/www/html/application/index/view/admin#

goods_edit.html的内容

<textarea class="form-control" id="data" name="data" rows="3" required>
  {php}use app\index\model\Goods;$view=new Goods();
  echo $view->arrayToMarkdown(unserialize(base64_decode($goods['data'])));
                                ⬆️反序列化的地方
  {/php}
</textarea>

这里在本地进行测试
image

很明显这就是序列化后的数据
随便创建一个类,然后进行在数据库进行修改,
在这里我将数据库的id=2的data修改,
image

修改
image

看效果
image

能够反序列化,但是这是我们自己在自己的虚拟机上的测试,
在比赛的时候,还得考虑传参,以及哪来的链子
还是回到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('商品信息更新失败');
        }
    }
    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 ";
        foreach ($data as $key => $value) {
            $sql .= "`$key` = unhex('" . bin2hex($value) . "'), ";
        }

        $sql = rtrim($sql, ', ') . " WHERE `id` = " . intval($id);
        return mysqli_query($this->connect(), $sql);
    }
}

基本就清楚了,抓包后,可以在data部分添加数据进行,但是接下来的就是thinkphp的链子部分,这里我还没学,得去学一下了

POST http://777.777.777.777:36000/public/index.php/index/admin/do_edit.html HTTP/1.1
Host: 777.777.777.777:36000
Content-Length: 145
Cache-Control: max-age=0
Accept-Language: zh-CN,zh;q=0.9
Origin: http://777.777.777.777:36000
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://777.777.777.777:36000/public/index.php/index/admin/goods_edit/id/2.html
Accept-Encoding: gzip, deflate, br
Cookie: PHPSESSID=c01ttalgd0co8lemafcplh3a24
Connection: keep-alive

id=2&name=cxz&price=3000.00&on_sale_time=2025-10-11T09%3A29&image=https%3A%2F%2Fi.postimg.cc%2FFzvNFBG8%2FR-6-HI3-YKR-UF-JG0-G-N.jpg&data=hello+w

大佬wp

大佬wp

posted @ 2025-10-12 14:53  z3xc  阅读(44)  评论(0)    收藏  举报