ctf02

关于8月的ctfwp :D

2020ciscn’s wp: https://www.gem-love.com/ctf/2569.html
https://www.gksec.com/amp/CISCN2020_Online_WriteUp.html
2020gactf’s wp:https://mp.weixin.qq.com/s/7POuTp37wzY7bS3R-Fldog
misc: https://mp.weixin.qq.com/s/TXXyzswABUv4cLDOw5SdI
Crypto: https://mp.weixin.qq.com/s/c4bK2R_n_r5q_7rSidEuTg
WEB: https://mp.weixin.qq.com/s/H0-imfruCTIXtMG16a9CIA

钓鱼城杯量子加密misc题:

《量子加密》writeup by @xmcp

本题有跑脚本的环节,下文所述的运行时间在一台i 7 - 10510U (25W) 笔记本电脑上测出。

解题过程分为三个部分: 1 ) 解密ZIP, 2 ) 分析流量, 3 ) 破解口令。

解密ZIP

首先打开压缩包,发现有密码保护,看到注释:

1
2
Password is longer than 16 bytes, and includes at least one number and one uppercase letter.
Feel free to crack it if you can, probably with your high-performance quantum computer :)

说明难以暴力破解。

压缩包里面有“capture.pcapng”和“hint_for_capture.txt”,压缩算法都是Store,这很奇怪,因
为pcapng并非十分紧密的格式,压缩软件没有理由不压缩它。

因此我们考虑ZIP明文攻击,只需要知道pcapng中至少 12 个字节(其中至少 8 个字节连
续)的内容即可破解。

上网搜索pcapng的文件头格式:

红色部分是固定的:Block Type始终为 0 A0D0D0A;Block Total Length是小端存储的Header
长度,显然不会超过64KB,所以高两位都是 00 ;Byte-Order Magic在小端机器上始终为
4 D3C2B1A;Major Version目前只有 0100 ;Minor Version目前只有 0000 。

这样可以知道文件中的 4 + 10 字节内容,满足明文攻击的要求。

其实蓝色部分也是可以猜出来的:Section Length是可选字段,大多数软件(比如WireShark)
在保存pcapng时会写入- 1 (即 8 个字节的FF)。

因此,把蓝色部分也算上的话,我们知道文件中的4+ 18 字节内容,对明文攻击绰绰有余了。

为了严谨起见,我们只使用十分确定的红色部分进行明文攻击。

注意到AZPR不支持明文分段的ZIP明文攻击,我们使用bkcrack.

在压缩包中提取出密文capture.pcapng.enc( 888832 字节)和hint_for_capture.txt.enc( 48
字节),把已知的 10 字节明文保存为capture.pcapng.plain。运行下面的命令进行攻击:

运行 29 分钟后得到秘钥。运行下面的命令解密文件:

分析流量

打开pcap看到上千个HTTP流量,用Fiddler查看发现全都是对192.168.142.138:8080的请
求,User-Agent为sqlmap/1.3.5.105#dev,可以判断是sqlmap自动对服务器进行SQL注入
的过程。

具体观察请求参数和响应,发现sqlmap在尝试盲注flags表的flag字段,请求使用了HEAD
方法(对应sqlmap的–null-connection参数),而且请求顺序是乱的(对应sqlmap的–
threads参数)。

根据前几个GET的响应可以判断出响应头Content-Length为 5 表示“error”,为 2 表示“ok”。

例如上述请求在判断flag的第 32 位字符是否大于 0 x 65 ,返回 5 表明结果是否定的。

将所有HTTP请求导出成文本文件:

然后编写脚本获得flag内容:

根据hint_for_capture.txt的提示,得到的内容经过了base85编码。

将脚本输出base 85 解码得到:

1
2
flag is md5("Sq1it3"+压缩包密码)
Hint: 密码是一个身份证号,且出生年份恰有两个质因子

破解口令

我们需要破解压缩包口令,考虑John the Ripper。首先用zip2john转换一下:

其中hint_for_capture.txt是压缩包中的纯ASCII文件而且比较小,用来加速破解过程。

已经知道压缩包密码是合法的身份证号。由于压缩包注释提到密码包括大写字母,可以推出
身份证尾号为X。通过分解质因数得到可行的出生年份列表:

我们分析一下身份证的格式:

⚫ 前 6 位是区号,上网搜一下可以得到区号列表,全国的合法区号不超过 4000 个。

⚫ 然后 4 位是出生年份,我们从 2020 往下枚举。

⚫ 然后 4 位是出生月日,不超过 366 个。

⚫ 然后 3 位是当天的序号,只需要枚举两位,最后一位可以利用校验码唯一确定。

⚫ 最后 1 位是校验码,固定为X。

这样一来,密码的值域降低到了 1010 量级,可以进行破解了。

首先我们在网上搞一份身份证区号列表,存为id_prefix.txt,然后用C++写一个枚举合法身
份证号的代码(编译选项-Ofast -march=native,不用Python因为太慢了)。

上面这个代码的命令行参数是年份,将把该年的所有尾号为X的合法身份证号输出到stdout。

调用该程序生成字典,然后用john破解。脚本如下:

运行 4 分钟后得到密码:

计算md5(“Sq1it332070119840810108X”)即得到flag。

-------------已经到底啦!-------------