找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 105|回复: 0

【iotsec-zone】0成本搭建摄像头漏洞挖掘环境

[复制链接]

2万

主题

128

回帖

10万

积分

管理员

积分
105812
发表于 2022-9-23 16:11:14 | 显示全部楼层 |阅读模式 IP:山东省 移动/数据上网公共出口

登录后更精彩...O(∩_∩)O...

您需要 登录 才可以下载或查看,没有账号?立即注册

×
0成本搭建摄像头漏洞挖掘环境


0成本搭建摄像头漏洞挖掘环境

环境说明:
Ubuntu 18.04+QEMU

网络配置:宿主机物理ens18网卡:x.x.x.x/24,虚拟网卡tap0:192.168.0.2/24;

预备知识嵌入式linux开机引导程序U-boot
  • U-Boot 是一个主要用于嵌入式系统的BootLoader程序,可以支持ARMRSIC-VMIPSx86等多种不同的计算机系统结构。目前常见的摄像头硬件使用的cpu大都是ARM架构,采用uboot方式引导,大致流程是:`设备上电 -> uboot代码自动执行 -> 加载uImage内核文件 -> 将执行权限交给内核启动`。由于它是一套在GNU通用公共许可证之下发布的自由软件,因此我们可直接从官方下载源码进行交叉编译后对其进行仿真模拟运行。
设备树(DTB)
  • 设备树(Device Tree binary file),是在系统启动的时候由BootLoader程序将保存在flash或其他地方中的DTB copy到内存中用来描述一棵电路板上CPU、总线、设备组成的树信息,然后内核可以识别这棵树, 并根据它展开出Linux内核中的各种设备。它是由一种ASCII 文本格式的Device Tree描述文件.dts文件,通过DTCDevice Tree Compiler)编译而成,变成适合机器处理的Device Tree Blob
Linux内核常见格式
  • vmlinux:编译出来后未压缩最原始的内核文件。
  • Image:通用Linux内核二进制映像文件。原则上Image就可以直接被烧录到Flash上进行启动执行(类似于u-boot.bin),但搞嵌入式的还是嫌它大了。
  • zImage:自解压的Linux内核映像的压缩版本。是vmlinux经过objcopy gzip压缩后的文件, objcopy实现由vmlinux的elf文件拷贝成纯二进制数据文件,zImage自带了解压缩程序,所以zImage由vmlinux objcopy出来的纯二进制文件以及解压缩程序组成。
  • uImage:U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的TAG。
vexpress虚拟开发版

资源:
CPU:ARM-Versatile Express ARMv7 Processor
SD卡:mmci-pl18x clcd-pl11x ARM(R) AMBA(R) PrimeCell Multimedia Card
网卡:smsc911x phy:libphy
实时时钟:rtc-pl031 (qemu能显示正确时间)
串口:AMBA PL011 UART driver
看门狗:
GPIO:
LCD:pl111 clcd-pl11x
中断:gic

软件准备
  • 源码包下载:
    uboot
    linux
    busybox

  • 创建单独的vexpress目录, 下载uboot, linux和busybox源码并解压,创建镜像文件目录image

    • ubuntu@ubuntu-virtual-machine:~/vexpress$  ls
    • busybox     busybox-1.31.1.tar.bz2     image     linux     linux-3.18.30.tar.gz
    • u-boot      u-boot-2019.07.tar.bz2
  • Ubuntu 软件安装:
    安装交叉编译工具:sudo apt install gcc-arm-linux-gnueabi
    依赖库和软件包安装:sudo apt-get install zlib1g-dev libglib2.0-0 libglib2.0-dev libtool libsdl1.2-dev autoconf flex bison ncurses-dev u-boot-tools


一、安装Qemu使用 apt-get 安装
  • sudo apt-get install qemu
  • sudo apt-get install qemu-system
  • sudo apt-get install qemu-user-static
Qemu网络功能设置

配置TUN/TAP虚拟网络

sudo apt-get install bridge-utils uml-utilities // 虚拟网桥工具,brctl命令会用到;UML(User-mode linux)工具,tunctl命令会用到

检查是否有/dev/net/tun 设备文件,没有则自行配置安装。

  • ubuntu@ubuntu-virtual-machine:~$sudo tunctl -t tap0 -u ubuntu // 创建虚拟网卡并给用户赋予权限
  • // 配置网桥和虚拟网卡ip
  • ubuntu@ubuntu-virtual-machine:~$sudo ifconfig tap0 192.168.0.2 netmask 255.255.255.0
  • // 查看配置后的信息
  • ubuntu@ubuntu-virtual-machine:~$ip a
  • 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  •     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  •     inet 127.0.0.1/8 scope host lo
  •        valid_lft forever preferred_lft forever
  •     inet6 ::1/128 scope host
  •        valid_lft forever preferred_lft forever
  • 2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
  •     link/ether fe:fc:fe:48:ad:1a brd ff:ff:ff:ff:ff:ff
  •     inet x.x.x.x/24 brd x.x.x.255 scope global noprefixroute ens18
  •        valid_lft forever preferred_lft forever
  •     inet6 fe80::4963:be01:4b2f:abfb/64 scope link noprefixroute
  •        valid_lft forever preferred_lft forever
  • 3: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
  •     link/ether 2e:d3:aa:eb:eb:57 brd ff:ff:ff:ff:ff:ff
  •     inet 192.168.0.2/24 brd 192.168.0.255 scope global tap0
  •        valid_lft forever preferred_lft forever
  •     inet6 fe80::2cd3:aaff:feeb:eb57/64 scope link
  •        valid_lft forever preferred_lft forever
  • //测试网络连通性
  • ubuntu@ubuntu-virtual-machine:~$ping -c 3 192.168.0.2
  • PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
  • 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.049 ms
  • 64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.042 ms
  • 64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.062 ms
  • --- 192.168.0.2 ping statistics ---
二、搭建并运行一个uboot+linux+busybox的ARM仿真环境

思路:

  • 我们先通过自己模拟各种嵌入式系统必须的模块,最终模拟一个能联网运行的ARM环境,明白启动过程、系统初始化与文件系统挂载等等流程。
1、交叉编译uboot
  • ubuntu@ubuntu-virtual-machine:~/vexpress/uboot$export ARCH=arm
  • ubuntu@ubuntu-virtual-machine:~/vexpress/uboot$export CROSS_COMPILE=arm-linux-gnueabi-
  • ubuntu@ubuntu-virtual-machine:~/vexpress/uboot$make vexpress_ca9x4_defconfig // 可以在 configs 目录下选择对应的单板默认配置
  • ubuntu@ubuntu-virtual-machine:~/vexpress/uboot$make -j$(nproc)
  • ubuntu@ubuntu-virtual-machine:~/vexpress/uboot$cp u-boot ../image/
  • # 测试uboot的网络功能
  • ubuntu@ubuntu-virtual-machine:~/vexpress/uboot$qemu-system-arm -M vexpress-a9 -m 512 -nographic -net nic -net tap,ifname=tap0,script=no -kernel u-boot
  • pulseaudio: set_sink_input_volume() failed
  • pulseaudio: Reason: Invalid argument
  • pulseaudio: set_sink_input_mute() failed
  • pulseaudio: Reason: Invalid argument
  • U-Boot 2019.07 (Nov 12 2020 - 16:56:44 +0800)
  • DRAM:  512 MiB
  • WARNING: Caches not enabled
  • Flash: 128 MiB
  • MMC:   MMC: 0
  • *** Warning - bad CRC, using default environment
  • In:    serial
  • Out:   serial
  • Err:   serial
  • Net:   smc911x-0
  • Hit any key to stop autoboot:  0
  • => setenv ipaddr 192.168.0.3
  • => ping 192.168.0.2
  • smc911x: MAC 52:54:00:12:34:56
  • smc911x: detected LAN9118 controller
  • smc911x: phy initialized
  • smc911x: MAC 52:54:00:12:34:56
  • Using smc911x-0 device
  • smc911x: MAC 52:54:00:12:34:56
  • host 192.168.0.2 is alive  #这里alive结果表示虚拟主板中uboot和宿主机器可通讯
  • =>
2、交叉编译linux内核
  • ubuntu@ubuntu-virtual-machine:~/vexpress/linux$export ARCH=arm
  • export CROSS_COMPILE=arm-linux-gnueabi-
  • make vexpress_defconfig
  • make -j$(nproc)
  • make modules -j$(nproc)
  • make uImage LOADADDR=0x60000000
  • make dtbs
  • cp -f arch/arm/boot/uImage  ../image/
  • cp -f arch/arm/boot/zImage  ../image/
  • cp -f arch/arm/boot/dts/vexpress-v2p-ca9.dtb  ../image/device.dtb
3、交叉编译busybox并制作根文件系统

创建脚本并执行:

  • ubuntu@ubuntu-virtual-machine:~/vexpress/busybox$  cat mkbusybox.sh
  • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- defconfig
  • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install
  • # 将编译好的busybox和一些动态链接库复制到一个ext3文件系统中,制作rootfs
  • dd if=/dev/zero of=sdcard.ext3 bs=1M count=32
  • mkfs.ext3 sdcard.ext3
  • sudo rm -fr rootfs;
  • mkdir rootfs
  • sudo mount -t ext3 -o loop sdcard.ext3  rootfs/
  • cd rootfs;
  • sudo mkdir lib proc sys dev etc etc/init.d
  • sudo cp -r ../_install/* .
  • sudo cp -P /usr/arm-linux-gnueabi/lib/*  lib/
  • sudo cp ../examples/bootfloppy/etc/inittab  etc/
  • sudo touch etc/init.d/rcS ;
  • sudo chmod 0777 etc/init.d/rcS;
  • sudo echo "#!/bin/sh" >> etc/init.d/rcS
  • sudo echo "mount -t proc none /proc" >> etc/init.d/rcS
  • sudo echo "mount -t sysfs none /sys" >> etc/init.d/rcS
  • sudo echo "mount -t tmpfs none /dev" >> etc/init.d/rcS
  • sudo echo "/sbin/mdev -s" >> etc/init.d/rcS
  • sudo chmod 0755 etc/init.d/rcS;
  • cd ..;
  • sudo umount rootfs/
  • cp sdcard.ext3 ../image/
4、搭建tftp服务器(供uboot下载内核启动)
  • ubuntu@ubuntu-virtual-machine:~/vexpress/$sudo apt-get install tftp-hpa tftpd-hpa
  • ubuntu@ubuntu-virtual-machine:~/vexpress/$cat /etc/default/tftpd-hpa #修改配置文件
  • # /etc/default/tftpd-hpa
  • TFTP_USERNAME="tftp"
  • TFTP_DIRECTORY="/home/ubuntu/vexpress/image"
  • TFTP_ADDRESS=":69"
  • TFTP_OPTIONS="--secure"
  • ubuntu@ubuntu-virtual-machine:~/vexpress/$sudo service tftpd-hpa restart
5、运行uboot+linux+busybox文件系统的ARM环境

使用虚拟网卡tap0、引导程序u-boot、内核镜像uImage和根文件系统sdcard.ext3这些自建的零件启动一个带网络的ARM仿真环境

  • ubuntu@ubuntu-virtual-machine:~/vexpress/image/$qemu-system-arm -M vexpress-a9 -m 512 -nographic -net nic -net tap,ifname=tap0,script=no -kernel u-boot -sd sdcard.ext3
  • #......
  • =>setenv ipaddr 192.168.0.3 #这里只是设置uboot的临时ip
  • =>setenv serverip 192.168.0.2 #设置tftp服务器地址
  • =>tftp 0x60000000 uImage #从tftp服务器上下载内核镜像,加载到0x60000000地址处
  • =>tftp 0x70000000 device.dtb #从tftp服务器上下载设备树,加载到0x70000000地址处
  • =>setenv bootargs "console=ttyAMA0 root=/dev/mmcblk0 init=/linuxrc rw rootwait" #设置启动参数,指定系统初始化程序以及根文件在哪块分区位置等
  • =>bootm 0x60000000 - 0x70000000 #从0x60000000启动内核(注意-号两边有空格)
  • #...自动加载启动内核并挂载根文件系统和执行rcS初始化脚本...
  • / # ls
  • bin               lost+found        sys
  • dev               lib               proc              usr
  • etc               linuxrc           sbin
  • / # ifconfig eth0 192.168.0.4 #这里设置的是虚拟环境的ip,可与宿主机的tap0网卡192.168.0.2通讯

使用zImage内核文件不依赖uboot直接启动:

  • ubuntu@ubuntu-virtual-machine:~/vexpress/image/$qemu-system-arm -M vexpress-a9 -m 512 -sd sdcard.ext3 -nographic -net nic -net tap,ifname=tap0,script=no -kernel zImage -dtb device.dtb  -append "console=ttyAMA0 rootwait rw root=/dev/mmcblk0 init=/linuxrc"

退出仿真环境:

先按Ctrl+A,然后按x键即可退出qemu仿真环境

三、分析摄像头升级固件并根据固件模拟摄像头环境

思路:通过分析摄像头固件,得到其中的文件,解压出其中的文件后分析启动过程,将如何初始化、修改了哪些文件等等操作都记录下来,然后把提取出来的文件放到自己制作的一个文件系统中,用我们自己的ARM仿真环境去挂载这个根据固件制作出来的文件系统,对此摄像头环境进行仿真模拟。

1、使用binwalk分析提取固件

进入提取后的_romfs-x.squashfs.img分区中,能看见这就是一个嵌入式linux的根目录。

2、分析并制作文件系统

根据初始化脚本rcS中挂载情况,推出各个分区挂载在到跟文件系统中的目录,我们直接在romfs-x中创建对应目录,然后把相应分区镜像中的文件复制到romfs这个根分区的文件夹中。我们制作一个根文件系统把这些文件都放进去即可,最后在rcS脚本中写入/bin/sh,方便初始化完成后直接进入我们的shell。

通过查看linux内核的错误定义头文件include/uapi/asm-generic/errno-base.h中得知以上错误代码error 8的含义,是由于linuxrc初始化程序报的可执行文件格式错误。

简单使用了file命令和readelf简单分析了摄像头文件系统中的busybox二进制程序和其他的一些二进制程序,可以发现它们确实是可执行文件格式,但使用了一种摩托罗拉的架构,和本机的X86-64架构、仿真环境的ARM架构完全不一样。我们从中拿出一个小的配置wifi功能的二进制程序iwconfig来尝试逆向分析:

现在陷入僵局,无法逆向分析了,就开始思考:a.是否由于厂商可以修改了elf的标志,让常规的普通内核和逆向软件无法识别加载这种特殊格式的可执行程序,只有自家厂商的魔改内核可加载这种程序;b.此版本摄像头硬件就是使用的是摩托罗拉mCore架构芯片,并没有采用大众的ARM架构芯片。

开始验证假设a:恢复elf的arch标志位为ARM架构,将0x0012h处的27 00改为28 00即可,看看能不能在我们的arm仿真环境中正常运行:

M-CORE是一种摩托罗拉设计的基于RISC指令集的低功耗芯片架构 … …,看到推出年代是1997年,几乎和我一般大了,这也很老了,居然从来没听说过。还好这里还给出了这款芯片的开发人员参考手册,可以继续学习一下,方便后续逆向。

通过阅读这个手册,知道这些关键信息:mCore是采用32位的RISC指令集架构,指令长度固定为16位,得到各指令功能介绍,得到二进制操作码和指令对应关系。

现在回来开始逆向分析二进制程序就思路清晰了,知道如何把二进制代码转换为指令来分析功能了:

得到0x00020f0这个地址的值为0x7208,转换16位二进制格式的指令就是0b01110010 00001000

果然还是工具强大,各种辅助线,各种注释,节省了很多精力,遗憾不能反编译为伪代码,我们把更多精力放在阅读汇编代码上,这样就可以愉快的进行漏洞挖掘了。

通过按照标准的mcore芯片文档来逆向分析,确定这些摄像头固件里的二进制程序确实没有经过混淆修改,得知此摄像头硬件应该确实是摩托罗拉的芯片,猜想b成立。

接下来就面临一个非常尴尬的情况,目前能静态的逆向分析这些程序了,但是没有动态调试环境。尝试用qemu来模拟出一个mcore架构的运行环境,刚开始查阅qemu官方文档,其中介绍到有支持RISC-V的模块,天真的想到mcore基于RISC指令集,RISC-V是它的第5版,应该向下兼容吧,然后就开始下载qemu源码,手动编译配置添加这个模块,接下来还需要编译RISC-V的内核,然后有巨多的坑。后来才发现ARM也是属于RISC指令集的,因此mCore、ARM、RISC-V都是基于RISC的同一高度的不同架构,根本不是第5版,本地的ARM仿真环境不能运行mcore的程序,肯定编译出来的RISC-V也是互不兼容啊,很遗憾我没找到能模拟mcore程序的运行环境。如果有大佬能解决这个问题,希望可以指点一下。

实战B:A厂摄像头型号b

由于目前不能模拟出mcore架构环境,在A厂的型号a产品上的完美模拟暂时碰壁了,因此我们将目标转向型号b,从网上下载A厂摄像头型号b的升级固件

1、提取分析固件、制作文件系统

由于是同一厂商的不同型号,固件提取和文件系统制作过程都差不多,这里就省略了,直接记录仿真运行中遇到的坑。

2、仿真运行
  • ubuntu@ubuntu-virtual-machine:~/vexpress/image/$qemu-system-arm -M vexpress-a9 -m 512 -nographic -net nic -net tap,ifname=tap0,script=no -kernel zImage -append "console=ttyAMA0 rootwait rw root=/dev/mmcblk0 init=/linuxrc" -sd carm_sd.ext3

报错:无法创建、解压文件的问题我们可以进入shell后手动操作,提示初始化时文件系统中模块的version magic和当前内核不匹配,因此我们需要编译能加载vermagic为3.18.30 preempt mod_unload ARMv7 p2v8的内核

十分幸运修改完成交叉编译好指定版本的ARM架构内核后,基本能成功运行,接下来检查配置网络,测试与宿主机的网络畅通:

我们要找到是是谁提供的web服务,看看能不能通过手动启动。思路:在web目录中查看相关文件,看看调用了什么接口,然后全局搜索接口在什么地方出现。

在宿主机上切到web分区目录,开启一个python服务器,模拟一个web服务来提供index页面,通过访问抓包获取登录接口

然后我们把carm_sd.ext3挂载到宿主机的rootfs目录,在此目录中全局搜索字符串,看看在哪里出现了,通过宿主机器搜索文件相对更快:

  • ubuntu@ubuntu-virtual-machine:~/vexpress/image$ sudo mount carm_sd.ext3 rootfs/ubuntu@ubuntu-virtual-machine:~/vexpress/image$ grep -r '/RPC2_Login' ./rootfs/匹配到二进制文件 ./rootfs/usr/bin/sonia./rootfs/mnt/web/jsBase/common/rpcBase.js:^Cubuntu@ubuntu-virtual-machine:~/vexpress/image$ file rootfs/usr/bin/soniarootfs/usr/bin/sonia: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.1.1, BuildID[sha1]=06711d7d2dcc3e9bc81e5e416b935420866181be, stripped

把usr/bin/sonia取出来分析一下,找到/RPC2_Login接口对应的代码,确定sonia就是提供web服务的后端功能程序,接下来就可以静态分析上手挖掘了。

不知道为什么出现这些打开文件失败的错误,难道是初始化的时候有些资源没初始化成功?因此回过头,再研究一下启动过程中的初始化操作,一步步手动再执行一遍:

发现他们一家子都在这里了,没有依赖此目录外的其他模块呀。莫非需要慢慢研究重新一条条修改内核配置?能不能分析一下固件中的kernel.img提取其中的配置,或者直接拿它来运行呢?说干就干!

binwalk kernel.img看到,结构是:uImage头+uImage头+zImage内核头+lzo和xz数据+uImage头:

我们知道uImage是zImage添加64字节信息后供uboot识别启动的,仔细研究了一下zImage和uImage格式,看看多的是什么东西:

使用自己的uboot加载裁剪好的uImage内核,发现还是不能运行。不清楚为什么,就开始用自己编译的同版本内核A同从固件中提取出来的内核B和自己编译的高版本内核C进行熵对比,可以看到头部结构基本相似,只有在固件中提取出来的内核B尾部混乱程度最高,猜测对某些关键部分进行了加密:

看见这个flash芯片是这样焊的,以我手中小拇指大的烙铁和粗糙的技术,如果强行飞线可能会造成无法挽回的损失,保险起见,我在淘宝上买了专业的夹具和对应编程器。

在等待快递的这段时间,尝试修改uboot源码来看看能不能跟入内核,看看魔改后的内核运行到什么程度,是否有特殊自解压操作等。

开启uboot的DEBUG模式,修改include/log.h 添加#define DEBUG 1

可以看见kernel_entry是一个函数指针,来自images->ep;跟入include/image.h看看bootm_headers_t的数据结构,得知images->ep就是内核的入口:

到此各种文件格式基本分析得差不多了,了解了这些结构中一些特殊字段的含义,现在开始编译debug版本的u-boot.debug,用来加载摄像头固件中提取出来diy的kernel.img.uImage.diy内核:

  • ubuntu@ubuntu-virtual-machine:~/vexpress/image$  qemu-system-arm -M vexpress-a9 -m 512 -nographic -net nic -net tap,ifname=tap0,script=no -kernel u-boot.debug -sd carm_sd.ext3

现在没法运行魔改的内核,就没法加载定制的各种ko模块,各种服务也就跑不起来,就不是完美模拟摄像头环境,只有等到专业设备到手了试试直接从芯片中读取数据,搞明白究竟咱操作的再来试试。

实战C:B厂摄像头版本a1、提取分析固件、制作文件系统

使用binwalk -Me ipc_b.bin提取固件得到如下目录:

根据初始化脚本,创建挂载目录,将对应分区的文件复制到相应文件夹下,然后就可以制作文件系统了;我们还可以修改rcS脚本添加一个shell,将配置网卡、创建目录、解压文件等操作都注释掉,等我们进入shell后手动来执行。最后得到包含摄像头文件的文件系统monitor_sd.ext3

3、仿真运行
  • qemu-system-arm -M vexpress-a9 -m 512 -sd monitor_sd.ext3 -nographic -net nic -net tap,ifname=tap0,script=no -kernel zImage -dtb device.dtb -append "console=ttyAMA0 rootwait rw root=/dev/mmcblk0 init=/linuxrc"

报错:一些内核模块加载版本不兼容,只需要编译对应能加载这些模块的内核即可;一些目录不存在,我们进入shell后手动添加即可。

从宿主机上看虚拟摄像头环境是否正常启动这些服务,尝试登录:

接下来就可以进行静态分析,上手挖掘啦,然后还可以在仿真环境里动态测试,就不用再花小钱钱买真实的摄像头设备了,成功0成本白嫖一套环境。

其他:

遇到过固件程序能被binwalk识别,但是不能提取的情况,这是因为固件被加密了,需要拿到硬件设备,从设备中读取芯片数据,从中找到加密方式才行。

参考文章:

【qemu-vexpress】https://www.qemu.org/docs/master/system/arm/vexpress.html

【基于QEMU搭建完整的虚拟ARM开发环境】https://blog.csdn.net/konga/article/details/79595119

【M.CORE】https://en.wikipedia.org/wiki/M%C2%B7CORE

【M-CORE, microRISC Engine, Programmers Reference Manual】https://web.archive.org/web/20160304090032/

http://www.saladeteletipos.com/pub/SistemasEmbebidos2006/PlacaMotorola/mcore_rm_1.pdf


转自:iotsec-zone






回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|IOTsec-Zone|在线工具|CTF WiKi|CTF平台汇总|CTF show|ctfhub|棱角安全|rutracker|攻防世界|php手册|peiqi文库|CyberChef|猫捉鱼铃|手机版|小黑屋|cn-sec|分享屋 ( 鲁ICP备2021028754号 )

GMT+8, 2024-5-7 10:50

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表