首页
论坛
课程
招聘
[原创]从0到1开始使用syzkaller进行Linux内核漏洞挖掘
2021-1-18 22:39 3555

[原创]从0到1开始使用syzkaller进行Linux内核漏洞挖掘

2021-1-18 22:39
3555

尝试从0到1开始使用syzkaller进行Linux内核漏洞挖掘

目录

环境搭建过程(吐血踩坑)

觉得前面踩坑的过程繁琐可以直接去看过程总结
整个环境搭建的过程踩了很多坑。有不少是网上没提到的,于是我详细记录了一下,希望能帮到以后踩坑的同学。

编译syzkaller

这里我使用了一个完全全新的Ubuntu18.04来搭建环境。

 

存储空间分配40G。

 

安装基本的软件

1
2
3
4
5
6
7
8
9
10
11
12
sudo apt-get install debootstrap
sudo apt install qemu-kvm
sudo apt-get install subversion
sudo apt-get install git
sudo apt-get install make
sudo apt-get install qemu
sudo apt install libssl-dev libelf-dev
sudo apt-get install flex bison libc6-dev libc6-dev-i386 linux-libc-dev linux-libc-dev:i386 libgmp3-dev libmpfr-dev libmpc-dev
apt-get install g++
apt-get install build-essential
apt install golang-go
apt install gcc

注意,此时我的gcc版本是 gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)

 

接下来尝试

1
go get -u -d github.com/google/syzkaller/prog

然而这一步慢的离谱。。我查了一下-u -d的选项,似乎跟直接git clone没什么区别。

 

于是我换了个方式,直接使用git clone拉取源码.

1
git clone https://github.com/google/syzkaller /usr/local/golang/src/github.com/google/syzkaller

然后也慢的离谱。

 

于是我直接在宿主机上下载了syzkaller.zip,然后复制到虚拟机中直接unzip解压。

 

然后直接make,发现报错:

 

 

使用 dmesg | egrep -i -B100 'killed process' 查看:

 

发现触发了 OOM-killer ,内存不够。

 

 

按照网上的方法建立了一个swap分区:

 

https://studygolang.com/articles/11781?fr=sidebar

 

重新编译又报错:

1
vm/vmimpl/merger.go:69:12: undefined: bytes.ReplaceAll

似乎是因为golang版本太低。(1.10)

 

于是使用wget下载新版本的golang。进行如下操作:

1
2
3
4
5
6
7
8
wget https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz
tar -xf go1.14.2.linux-amd64.tar.gz
mv go goroot
mkdir gopath
export GOPATH=/root/gopath
export GOROOT=/root/goroot
export PATH=$GOPATH/bin:$PATH
export PATH=$GOROOT/bin:$PATH #把这几行加到.bashrc中

root@ubuntu:~/gopath/src/github.com/google/syzkaller# go version
go version go1.14.2 linux/amd64

 

接下来把syzkaller.zip在:/root/gopath/src/github.com/google/ 下解压。

 

make!

 

又报OOM。

 

于是我查看了一下,似乎是因为同时编译多个文件造成的?

 

于是我尝试先单独编译一下第一个文件:

1
GOOS=linux GOARCH=amd64 go build "-ldflags=-s -w -X github.com/google/syzkaller/prog.GitRevision= -X 'github.com/google/syzkaller/prog.gitRevisionDate='" -o ./bin/syz-manager github.com/google/syzkaller/syz-manager

然后在 ./bin/ 下看到了编译好的 syz-manager

 

于是在进行make。

 

似乎是成功了。.git产生的fatal不用理他。

 

 

./bin/ 下我们看到了如下文件:

 

 

应该是编译好了。大概说一下这几个 syz-* 都是干嘛的:

 

总结一下我此时的环境:

1
2
3
4
5
6
7
Ubuntu18.04,内核5.4.0-42-generic
 
 
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
 
 
go version go1.14.2 linux/amd64

拉取linux主线源码

克隆主线 linux 代码,使用

1
https://mirrors.tuna.tsinghua.edu.cn/git/linux.git

如果太慢可以或者直接去: https://gitee.com/mirrors/linux/repository/archive/master.zip

 

下载解压好后。

 

运行如下命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.首先:
make CC="/usr/bin/gcc" defconfig
make CC="/usr/bin/gcc" kvmconfig    (这个选项没设置成功?)
 
2.在.config文件中添加
CONFIG_KCOV=y
CONFIG_DEBUG_INFO=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y
 
3.然后:
make CC="/usr/bin/gcc" olddefconfig
make CC="/usr/bin/gcc" -j64

编译完就生成了内核,不过这次不同于我们之前make bzImage。这次应该是驱动也编译了。

Image

1
sudo apt-get install debootstrap

然后建立一个image文件夹,cd进去

1
2
3
4
5
wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh -O create-image.sh
 
chmod +x create-image.sh
 
./create-image.sh

但我这里wget老是失败,于是我直接在这里:https://github.com/google/syzkaller/blob/master/tools/create-image.sh

 

copy了一份下来运行。

 

实际上就是先获取arch信息,然后使用 debootstrap 来构建基本的文件系统。

 

这一步也很慢,不过我寻思文件系统应该可以换成 CTF 题的 rootfs.img,毕竟只要内核对了就行。

 

漫长的等待后:

1
2
root@ubuntu:~/source/linux/image# ls
chroot  create-image.sh  stretch.id_rsa  stretch.id_rsa.pub  stretch.img

可以看到出现了:stretch.id_rsa、stretch.id_rsa.pub、stretch.img 这几个文件。

 

接下来安装qemu环境:

1
sudo apt-get install qemu-system-x86

一般kvm什么的都是自带的。不过如果是vmware可能需要开启一下虚拟化引擎 里的 虚拟化 Intel VT-x/EPT 或 AMD-V/RVI(V)

 

就在虚拟机的设置界面中。

 

boot.sh如下:

1
2
3
4
5
6
7
8
9
10
11
qemu-system-x86_64 \
 -kernel /root/source/linux/arch/x86/boot/bzImage \
 -append "console=ttyS0 root=/dev/sda debug earlyprintk=serial slub_debug=QUZ"\
 -hda ./stretch.img \
 -net user,hostfwd=tcp::10021-:22 -net nic \
 -enable-kvm \
 -nographic \
 -m 256M \
 -smp 2 \
 -pidfile vm.pid \
 2>&1 | tee vm.log

启动起来后显示:

 

root@syzkaller:~#

 

然后poweroff掉。

 

回到 root@ubuntu:~/gopath/src/github.com/google/syzkaller#

 

新建my.cfg文件

 

然后尝试运行 syz-manger发现报错:

1
2021/01/16 20:57:54 bad syz-manager build: build with make, run bin/syz-manager

猜测是 .git ?的问题,因为我在源码中发现了这样一行:

1
2
3
if prog.GitRevision == "" {
        log.Fatalf("bad syz-manager build: build with make, run bin/syz-manager")
    }

于是尝试 git init 一下,重新编译。

 

 

这次启动起来了。但是http panic了。

 

定位问题:

1
2
3
4
5
6
7
8
2021/01/17 01:41:29 http: panic serving 127.0.0.1:56498: runtime error: slice bounds out of range [:8] with length 4
goroutine 53 [running]:
net/http.(*conn).serve.func1(0xc00087e780)
    /root/goroot/src/net/http/server.go:1772 +0x139
panic(0x10f68c0, 0xc0004f74a0)
    /root/goroot/src/runtime/panic.go:975 +0x3e3
main.(*Manager).collectStats(0xc000100820, 0x0, 0x0, 0x0)
    /root/gopath/src/github.com/google/syzkaller/syz-manager/html.go:111 +0x106f

切片越界了。本来只有length=4,但是切到了8。

 

看一下这部分的代码:

 

 

这里似乎是一个获取版本的操作。尝试了一下把这个地方从8改成4就可以跑了。但是显示如下

 

 

首先看这个revision这里,确实是一个长度为4的字符串,所以切片越界了。

 

但是底下都显示的0,没跑起来啊。。。

 

于是我重新在宿主机里挂了一下git的代理:

1
2
3
git config --global http.proxy socks5://192.168.80.1:7890
git config --global https.proxy socks5://192.168.80.1:7890
git config --global http.sslVerify false

然后绑定到远程的git仓库。pull下来,处理冲突。

1
git pull origin master

然后重新make。启动。

 

然而还是这样子。(泪)

 

突然发现qemu启动的时候似乎在这里有一些问题,Kernel File Systems mount不上去:

1
2
3
4
5
6
7
8
9
10
11
12
[FAILED] Failed to mount /sys/kernel/config.
See 'systemctl status sys-kernel-config.mount' for details.
[DEPEND] Dependency failed for Local File Systems.
[DEPEND] Dependency failed for Mark the need to relabel after reboot.
[  OK  ] Reached target Timers.
[    2.878286] EXT4-fs (sda): re-mounted. Opts: (null). Quota mode: none.
[  OK  ] Closed Syslog Socket.
[  OK  ] Started Emergency Shell.
[  OK  ] Reached target Emergency Mode.
[  OK  ] Reached target Login Prompts.
[  OK  ] Started Load Kernel Modules.
[FAILED] Failed to start Remount Root and Kernel File Systems.

于是查找解决方案:

 

https://github.com/google/syzkaller/issues/760

 

按照上面的,删掉那些注释。

 

重新编译内核生成bzImage

 

成功!!!

 

过程总结(重点)

1.网上很多说是必须 gcc 8 的版本,实际并不需要,直接apt安装gcc即可。但是golang版本最好是最新的。当然你可以先apt install golang-go,然后手动升级到最新版本就行。

 

2.go get -u -d效果跟直接git clone一样的。如果git clone太慢可以挂一下代理。

 

3.如果你是直接下载的.zip,记得先git init一下,然后绑定到远程仓库。

 

4.注意编译内核的时候要添加那些选项,并且要把下面那些选项对应的注释删掉!!(比如:# CONFIG_KCOV is not set)要不然会被rewrite掉。。

Syzkaller Overview

官方给出了一个如下的overview图片。

 

图片描述

  • syz-manager 是起了一个监控者的作用。他启动多个VM instance(也就是黄色框),同时通过远程过程调用,在VM中启动 syz-fuzzer
  • syz-fuzzer 在VM内部运行。syz-fuzzer负责引导整个fuzz的过程(input generation, mutation, minimization, etc.)。并且通过RPC将那些引起了新的覆盖(coverage)的输入回送到 syz-managersyz-fuzzer 也负责启动短暂的 syz-executor 进程。
  • 每个 syz-executor 进程都负责执行单个输入(一系列的syscall)。syz-executor 接受从syz-fuzzer 生成的input,然后执行,最后回送结果。这部分的设计要尽可能的简化。不干扰fuzz过程。用C ++编写,编译为静态二进制文件并使用共享内存进行通信。

Syscall descriptions

Syzkaller 采用一套自己的系统调用的描述or声明(syzlang),来操纵fuzz的系统调用序列。

 

官方给出的语法如下:https://github.com/google/syzkaller/blob/master/docs/syscall_descriptions_syntax.md

 

这里有已经声明好的:https://github.com/google/syzkaller/blob/master/sys/linux/sys.txt

1
2
3
4
5
6
7
8
syscallname "(" [arg ["," arg]*] ")" [type] ["(" attribute* ")"]
arg = argname type
argname = identifier
type = typename [ "[" type-options "]" ]
typename = "const" | "intN" | "intptr" | "flags" | "array" | "ptr" |
       "string" | "strconst" | "filename" | "len" |
       "bytesize" | "bytesizeN" | "bitsize" | "vma" | "proc"
type-options = [type-opt ["," type-opt]]

具体的过程是:

 

使用syz-extract得到常量和值一一对应的.const文件(例如/sys/linux/tty.txt被转换为sys/linux/tty_amd64.const),然后使用syz-sysgen编译AST(Abstract Syntax Tree,抽象语法树)和常量值,并返回包含生成的prog对象的Prog(根据系统调用模板和第一步中生成的const文件使用syz-sysgen生成syzkaller用的go代码)。syz-sysgen具体又分为下面4步。
    1.assignSyscallNumbers:分配系统调用号,检测不受支持的系统调用并丢弃
    2.patchConsts:将AST中的常量patch成对应的值
    3.check:对AST进行语义检查
    4.genSyscalls:从AST生成prog对象

 

以上是先知上的 houjingyi 大师傅分析总结的。对应的源码分析的文章链接如下,我这个初学者就不献丑了。。

 

内核漏洞挖掘技术系列(4)——syzkaller(2)

尝试使用Syzkaller捕捉一个简单的内核堆溢出

这部分主要参考 :

  1. bsauce

  2. https://github.com/hardenedlinux/Debian-GNU-Linux-Profiles/tree/master/docs/harbian_qa/fuzz_testing

  3. 使用Syzkaller&QEMU捕捉内核堆溢出Demo

整体过程大概如下:

编译有漏洞的驱动到内核中

test.c中有一个堆溢出的demo。我们将他编译然后insmod上去。

1
2
3
4
5
6
7
8
static ssize_t proc_write (struct file *proc_file, const char __user *proc_user, size_t n, loff_t *loff)
{
    char *c = kmalloc(512, GFP_KERNEL);
 
    copy_from_user(c, proc_user, 4096);        //堆溢出
    printk(DEBUG_FLAG":into write!\n");
    return 0;
}

当我们想要尝试编译内核模块的时候,涉及到一个linux header的问题。(比如说我在5.4.0-62-generic的系统下编译5.11.0-rc3的驱动)

 

我的解决方案是:

1
2
3
4
5
/lib/modules/ 下mkdir一个5.11.0-rc3/
然后cd 5.11.0-rc3/
mkdir kernel
ln -s /root/source/linux ./source
ln -s /root/source/linux ./build

然后make。这里发现了一个问题。

 

源码中有这样几行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static struct file_operations a = {
                                .open = proc_open,
                                .read = proc_read,
                                .write = proc_write,
};
 
 
static int __init mod_init(void)
{
    ......
    const struct file_operations *proc_fops = &a;
    ......
 
    test_entry = proc_create(MY_DEV_NAME, S_IRUGO|S_IWUGO, NULL, proc_fops);
    ......
}

但是编译的时候会报:

1
2
3
4
5
6
/root/fuzz/test.c:27:66: error: passing argument 4 of ‘proc_create’ from incompatible pointer type [-Werror=incompatible-pointer-types]
     test_entry = proc_create(MY_DEV_NAME, S_IRUGO|S_IWUGO, NULL, proc_fops);
                                                                  ^~~~~~~~~
In file included from /root/fuzz/test.c:3:0:
./include/linux/proc_fs.h:109:24: note: expected ‘const struct proc_ops *’ but argument is of type ‘const struct file_operations *
 struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct proc_ops *proc_ops);

这个版本下:proc_create的最后一个参数要求是 const struct proc_ops * 而不是旧的 const struct file_operations *。

 

解决方案参照:https://stackoverflow.com/questions/64931555/how-to-fix-error-passing-argument-4-of-proc-create-from-incompatible-pointer

 

最终我对test.c改动如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
......
static struct proc_ops a = {                        //修改
                                .proc_open = proc_open,   
                                .proc_read = proc_read,
                                .proc_write = proc_write,
};
 
static int __init mod_init(void)
{
    struct proc_dir_entry *test_entry;
    //const struct file_operations *proc_fops = &a;    //不要这里
    const struct proc_ops *proc_fops = &a;            //修改
    printk(DEBUG_FLAG":proc init start!\n");
 
    test_entry = proc_create(MY_DEV_NAME, S_IRUGO|S_IWUGO, NULL, proc_fops);
    if(!test_entry)
       printk(DEBUG_FLAG":there is somethings wrong!\n");
 
    printk(DEBUG_FLAG":proc init over!\n");
    return 0;
}
......
module_init(mod_init);
MODULE_LICENSE("GPL");        //添加LICENSE

Makefile如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CONFIG_MODULE_SIG=n
 
obj-m += test.o
 
EXTRA_CFLAGS += -fno-stack-protector -no-pie
all:
    make -C /lib/modules/5.11.0-rc3/build M=$(PWD) modules
clean:
    rm -rf *.ko
    rm -rf *.mod
    rm -rf *.mod.*
    rm -rf *.o
    rm .tmp_versions/test.mod
    rm .test.ko.cmd
    rm .test.mod.o.cmd
    rm .test.o.cmd
    rm Module.symvers
    rm modules.order

此时可以正常通过编译,生成 test.ko。说明可以正常编译了。

 

这种不用自己找linux header,然后手动创建的方式屡试不爽orz,很适合调试的时候错版本加载一些内核驱动,之前我调试内核cve的时候也用的这种方式

 

接下来我们把test.c cp到/linux/drivers/char/下,然后vim /linux/drivers/char/Kconfig,添加如下:

1
2
3
4
5
config TEST_MODULE
        tristate "Heap Overflow Test"       
        default y                                           
        help
          This file is to test a buffer overflow.

然后make -j64编译。中途看了一眼,刚好发现了:

 

 

然后启动:

1
2
root@syzkaller:/proc# ls | grep test
test

已经有了。

添加对应的syzkaller规则

1.

 

syzkaller/sys/linux/ 下新建

 

对应的 proc_operation.txt 如下:

1
2
3
4
5
6
7
8
9
include <linux/fs.h>
 
open$proc(file ptr[in, string["/proc/test"]], flags flags[proc_open_flags], mode flags[proc_open_mode]) fd
read$proc(fd fd, buf buffer[out], count len[buf])
write$proc(fd fd, buf buffer[in], count len[buf])
close$proc(fd fd)
 
proc_open_flags = O_RDONLY, O_WRONLY, O_RDWR, O_APPEND, FASYNC, O_CLOEXEC, O_CREAT, O_DIRECT, O_DIRECTORY, O_EXCL, O_LARGEFILE, O_NOATIME, O_NOCTTY, O_NOFOLLOW, O_NONBLOCK, O_PATH, O_SYNC, O_TRUNC, __O_TMPFILE
proc_open_mode = S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH

这里我 引用bsauce师傅 的对于调用规则的讲解:

 

调用规则:$号前的syscallname是系统调用名,$号后的type是指特定类型的系统调用。如上文的 open$proc 指的就是open这个类调用中proc这个具体的调用,这个名字是由规则编写者确定的,具体行为靠的是后面的参数去确定。 参数的格式如下: ArgumentName ArgumentType[Limit] ArgumentName是指参数名,ArgumentType指的是参数类型,例如上述例子有string、flags等类型。[ ]号中的内容就是具体的类型的值,不指定的时候由syzkaller自动生成,若要指定须在后文指定,以上文为例:

 

​ mode flags[proc_open_mode]

 

​ proc_open_mode = ...

 

​ 因为我们给的例子是通过/proc/test这个内核接口的写操作来触发堆溢出,因此我们需要控制的参数是open函数中的file参数为“/proc/test”即可,其他操作参考sys.txt即可。

 

2.

 

编译 syz-extract 和 syz-sysgen

1
2
make bin/syz-extract
make bin/syz-sysgen

接下来我们使用 syz-extract 生成 .const 文件:

1
bin/syz-extract -os linux -sourcedir "/root/source/linux" -arch amd64 proc_operation.txt

生成了 proc_operation.txt.const 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Code generated by syz-sysgen. DO NOT EDIT.
arches = amd64
FASYNC = amd64:8192
O_APPEND = amd64:1024
O_CLOEXEC = amd64:524288
O_CREAT = amd64:64
O_DIRECT = amd64:16384
O_DIRECTORY = amd64:65536
O_EXCL = amd64:128
O_LARGEFILE = amd64:32768
O_NOATIME = amd64:262144
O_NOCTTY = amd64:256
O_NOFOLLOW = amd64:131072
O_NONBLOCK = amd64:2048
O_PATH = amd64:2097152
O_RDONLY = amd64:0
O_RDWR = amd64:2
O_SYNC = amd64:1052672
O_TRUNC = amd64:512
O_WRONLY = amd64:1
S_IRGRP = amd64:32
S_IROTH = amd64:4
S_IRUSR = amd64:256
S_IWGRP = amd64:16
S_IWOTH = amd64:2
S_IWUSR = amd64:128
S_IXGRP = amd64:8
S_IXOTH = amd64:1
S_IXUSR = amd64:64
__NR_close = amd64:3
__NR_open = amd64:2
__NR_read = amd64:0
__NR_write = amd64:1
__O_TMPFILE = amd64:4194304

重新运行

1
root@ubuntu:~/gopath/src/github.com/google/syzkaller# bin/syz-sysgen

然后:

1
2
make clean
make all

重新编译syzkaller。

 

最后我们修改 my.cfg

 

加上:

1
2
3
4
5
6
"enable_syscalls": [
                "open$proc",
                "read$proc",
                "write$proc",
                "close$proc"
],

最后

1
scp -P 10021 -i ./stretch.id_rsa -r /root/gopath/src/github.com/google/syzkaller/bin root@127.0.0.1:/root/bin

boot起来虚拟机将其拷贝到虚拟机的/root/bin 下。

效果

启动:bin/syz-manager -config my.cfg -vv 10
一段时间后出现:

 

但不知为什么我这里是空指针未引用orz。。不过确实是跑出来了 /proc/test 的洞。

 

图片描述
还有这种的:
图片描述

 

一段时间后:
图片描述
产生了一个c报告。可以直接在里面看对应的产生漏洞c代码(syzkaller生成的)

参考

编译delve时报错\"../../pkg/proc/native/proc_linux.go:170:16: undefined: strings.ReplaceAll\"如何处理?

 

解决golang编译项目时出现signal: killed

 

Setup: Ubuntu host, QEMU vm, x86-64 kernel

 

ubuntu系统debootstrap的使用

 

Git clone走ss代理

 

tools/create-image.sh: image does not boot in qemu

 

在Ubuntu 16.04.6 LTS上升级Go到最新版1.12.5实录

 

Syzkaller

 

内核漏洞挖掘技术系列(4)——syzkaller(2)

 

【漏洞挖掘】使用Syzkaller&QEMU捕捉内核堆溢出Demo

 

如何将一个驱动编译进内核


[公告]名企招聘!

最后于 2021-1-19 23:06 被ScUpax0s编辑 ,原因: test.c为我修改好的文件
上传的附件:
收藏
点赞5
打赏
分享
打赏 + 1.00
打赏次数 1 金额 + 1.00
 
赞赏  Editor   +1.00 2021/01/23 精品文章~
最新回复 (9)
雪    币: 6537
活跃值: 活跃值 (4399)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
pureGavin 活跃值 2 2021-1-19 08:42
2
0
感谢分享
雪    币: 9832
活跃值: 活跃值 (6574)
能力值: (RANK:600 )
在线值:
发帖
回帖
粉丝
有毒 活跃值 9 2021-1-19 08:57
3
0
精品,期待下一部
雪    币: 4756
活跃值: 活跃值 (7605)
能力值: (RANK:480 )
在线值:
发帖
回帖
粉丝
ScUpax0s 活跃值 7 2021-1-19 09:08
4
0
谢谢师傅们支持
雪    币: 2710
活跃值: 活跃值 (491)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
Thunder J 活跃值 2 2021-1-19 09:19
5
0
mark
雪    币: 1873
活跃值: 活跃值 (398)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Genes 活跃值 2021-1-19 10:24
6
0
感谢大佬分享~
雪    币: 693
活跃值: 活跃值 (514)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
TUGOhost 活跃值 2021-1-19 22:36
7
0
感谢分享,内存40G直接把我劝退了
雪    币: 4756
活跃值: 活跃值 (7605)
能力值: (RANK:480 )
在线值:
发帖
回帖
粉丝
ScUpax0s 活跃值 7 2021-1-19 23:05
8
0
TUGOhost 感谢分享,内存40G直接把我劝退了
啊,抱歉,用词不当,不是运行内存40G,是存储空间分40G………
雪    币: 15724
活跃值: 活跃值 (11921)
能力值: (RANK:75 )
在线值:
发帖
回帖
粉丝
Editor 活跃值 2021-1-23 10:41
9
0
感谢分享!mark!
雪    币: 48
活跃值: 活跃值 (115)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
saloyun 活跃值 2021-1-26 16:14
10
0
感谢分享!mark!
游客
登录 | 注册 方可回帖
返回