最近由于一次校内比赛开始学习 CTF 的相关知识,很多常见的题型使用一些工具能更方便的解题,这里把之前遇到的一些工具与其使用以及一些经验整理一下~不过说起来暂时在 PWN 和 REVERSE 方面欠缺很多啊。不过可惜最近事情比较多 CTF 相关内容要暂且放一下了。

说起来很多工具都是 kali 自带的,比较建议装个 kali 虚拟机。

Misc

啥都有

压缩包处理

爆破 John the Ripper

很经典的密码爆破工具,在多个平台都有其版本,可以直接在官网下载。

这边额外说下macOS下的安装,因为直接使用 homebrew 安装的时候会出现环境变量设置不够深的问题。

使用方法上,对于 zip/rar 压缩包,使用

1
2
zip2john file.zip > file.hash
rar2john file.rar > file.hash

将他们转换为 hash 文件。然后使用 john file.hash 命令进行爆破。

如果题目有提示密码位数和类型,可以使用 mask 进行指定,以提高效率,例如 4 位纯数字:

1
john --mask='?d?d?d?d' flag.hash

ZIP 伪加密

大概原理就是修改文件头的加密段造成解压软体(诶为什么要叫软体,好机车哦)识别为加密,但是并没有密码,所以一直无法解压的效果。

1.现代解压软件拥有“修复”功能的,可以直接使用修复功能修复。

2.对于 zip 使用工具 ZipCenOp

用法很简单:java -jar ZipCenOp.jar <option> <file>

(r : 恢复 zip,e : 制作伪加密)

3.手动修改 hex [1]

以这个压缩包的 hex 为例:
504B0304 14000008 0800F7B2 5E537699 13D61600 00001400
00000800 10007465 73742E74 78745558 0C007855 7D617155
7D61F501 14004BCB 494CAF2E C9C82C8E F72C8E4F 8C77334C
4CAF0500 504B0102 14031400 00080800 F7B25E53 769913D6
16000000 14000000 08000C00 00000000 00002000 A4810000
00007465 73742E74 78745558 08007855 7D617155 7D61504B
05060000 00000100 01004200 00004C00 00000000

第一个区域是压缩源文件数据区:
504B0304(头文件标记) 1400(解压所需版本) 0008(全局方式位标记)

第二个区域是压缩源文件目录区:
504B0102(文件头标记)1403(压缩版本) 1400(解压所需版本) 0008(全局方式位标记)

全局方式位标记的四个数字中只有第二个数字对其有影响。
第二个数字为奇数时 –>加密
第二个数字为偶数时 –>未加密

所以通常遇到两个全局方式位标记对不上情况的时候,可以考虑是伪加密,并将其修改回偶数。

许多资料都声称,只将压缩源文件目录区的全局方式位标记修改后就能实现伪加密的效果,并以前后不对应为原则来判断[1],但是实际上当只修改后者时,有一些压缩软件是能够正常解压的。并且如果两者都修改或只修改前者,也可以实现伪加密的效果。

ZIP 已知明文攻击

可参考 https://blog.csdn.net/q851579181q/article/details/109767425

文件分析

在文件中藏文件

文件分析 / 提取 binwalk

https://github.com/ReFirmLabs/binwalk

很经典的工具,分析文件格式必备。

安装:

1
2
3
git clone https://github.com/devttys0/binwalk
cd binwalk
python setup.py install

1
2
3
4
binwalk file 分析文件
binwalk -e file 分析并解压文件
binwalk -D=jpeg pcat.bin 分解文件
binwalk -eM pcat.bin 递归分解 需要配合其他指令

一些binwalk分析后,无法直接解出的,可以使用 dd 命令解出。 ( liniux 与 macOS 都自带,windows可以去网上搜索资料。)

1
dd if=<源文件名> of=<提取出来的文件名> skip=<跳过字节数> bs=1

数据提取 / 恢复 foremost

https://github.com/korczis/foremost

某些功能和 binwalk 类似,但是针对类型更广泛,主打“还原”,一些 binwalk 无法分离的文件比如 pcap 中的数据流、数字取证中的文件,他也可以提取。

安装方法:

Kali Linux 自带!

apt 安装

1
sudo apt-get install foremost

git 安装
1
2
3
4
git clone https://github.com/korczis/foremost.git
cd foremost
make
make install

1
brew install foremost

直接下载:https://github.com/jin-stuff/foremost/raw/master/binary/foremost.exe

也可自行编译,具体见 repo 说明。

图片分析/隐写

在图片中藏图片/数据。

图片图像隐写 stegsolve

https://github.com/Giotino/stegsolve

很经典的工具,可以解决单纯的图片通道隐写,LSB隐写,数据提取,图片结合等多种问题。

图片文件隐写 zsteg

https://github.com/zed-0xff/zsteg

仅支持 PNGBMP

很多binwalk无法提取的文件可以使用 zsteg 提取。并且会自动测试 LSB 等加密隐写。

命令也很简单,就是 zsteg 文件 即可。

安装需要有 ruby 环境。 然后 gem install zsteg 即可。

图片/音乐隐写 steghide

很老的一个隐写工具了。

steghide 可以在图片和音乐中隐写文件,并且可以设置密码,所以可以看到很多题目需要用到爆破。 所以对于 GNU / Linux ,你可以直接安装他的增强带破解功能版本 stegseek 。 对于其他系统,你可以使用:https://github.com/Va5c0/Steghide-Brute-Force-Tool

apt 安装

1
sudo apt-get install steghide

homebrew 上没有。 建议使用 MacPorts 安装。 我编译了好几次反正是没成功。

macports 我的超人 :(

1
sudo port install steghide

直接下载:https://sourceforge.net/projects/steghide/files/steghide/0.5.1/

下载 win32 那个 zip。

图片综合 ImageMagick

能做的事情太多了。

使用ImageMagick的创建,编辑,撰写,或转换位图图像。它可以读取和写入各种格式(超过200种)的图像,包括PNG,JPEG,GIF,HEIC,TIFF,DPX,EXR,WebP,Postscript,PDF和SVG。使用ImageMagick可以调整图像大小,翻转,镜像,旋转,变形,剪切和变换图像,调整图像颜色,应用各种特殊效果或绘制文本,线条,多边形,椭圆和贝塞尔曲线。[2]

最近我用到的是拆分 gif 图像 和拼合功能。

1
convert glance.gif flag.png

(将 gif 转为图像序列)

安装方法:

1
sudo apt-get install imagemagick
1
brew install imagemagick

可能需要brew install ghostscript

流量分析

Wireshark 没啥好说

比较常用的:

1.统计-协议分级,查看主要协议(可右键作为筛选器)

2.右键,追踪流。

3.ctrl/command+f 分组字节流+字符串下 检索关键词

4.使用前面提到的 foremost / binwalk 进行分离文件。

暂时能力有限,就用到这些,以后再补充。

Crypto

各种加密~

进制转换/编码解码

我感觉这些工作在控制台做的话会少一些割裂感,其实还挺方便的直接 f12 就有环境。所以这部分觉得很可以用 js 来做一些工作。

base64 字符串互转

1
2
3
4
// 字符串转 base64 
btoa('maxhere') // binary to ascii
// base64 转字符串
atob('bWF4aGVyZQ==') // ascii to binary

你可能会和我一样困惑为什么 btoa 不是 base64 to ascii 反而是输出 base64

前些年在中文互联网搜索时,我没有得到一个比较好的答案,现在已经有了一些,不过还是以一些机翻为主。其实原因很简单,上面的注释已经说明了,如果你还是不理解,可以看下面这部分[3]

任意进制互转

1
2
parseInt("0x22",16); // 将 16进制 转为 10进制
(34).toString(16) // 将 10进制 转为 16进制

ASCII 码文本互转

1
2
"A".charCodeAt();
String.fromCharCode('65');

Hex/String 互转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Hex2String(hex){
let _string = ""
for(let i= 0; i<=hex.length-2; i+=2){
_string += String.fromCharCode(parseInt(`0x${hex.slice(i,i+2)}`,16))
}
return _string;
}
function String2Hex(string){
let _hex = ""
for(let i of string){
_hex += (i.charCodeAt()).toString(16)
}
return _hex;
}

Urlcode 编码

1
2
encodeURIComponent('张麦麦的博客');
decodeURIComponent('%E5%BC%A0%E9%BA%A6%E9%BA%A6%E7%9A%84%E5%8D%9A%E5%AE%A2');

自动解密 Ciphey

https://github.com/Ciphey/Ciphey

使用自然语言处理和人工智能以及一些全自动解密/解码/破解工具。[4]

支持很多种解密方式,好处是可以自动化操作,适用于多重嵌套、懒得分析的单一文本。 具有语义的原文解密效果更好。

安装方法 github 的 中文翻译 已经很详细了。

不支持 Python3.9+ 请使用 Python 3.8-

最平凡的使用方法

1
ciphey -t "encrypted_message"

很多解密情况不适用……

该项目即将弃用,有基于 Rust 的替代项目 Ares

RSA 加密

RSA 加密的详细内容,我把他拆分到了 另一篇文章 里,因为写着写着有点偏离这一篇的主题了。

了解了 RSA 的基本原理,其实可以想到题目的出题方向,即给你某些参数,但是这些参数大概率不能直接获取到私钥 $d$ 。所以你需要通过各种工具和算法把一些值求出来,这部分很容易涉及到一些数论的知识,因此需要有较好的数理基础,很明显——我没有。

RSA 加解密文件 openssl

使用 key 解密

1
openssl rsautl -decrypt -in key.txt -inkey rsa.key -out flag.txt

使用私钥解密

1
openssl rsautl -decrypt -in flag.enc -inkey private.pem

从公钥查看 n e

1
openssl rsa -pubin -text -modulus -in pubkey.pem

RSA综合工具 RSAtool

使用 RSAtool 生成私钥

1
python rsatool.py -o private.pem -e 65537 -p <p> -q <q>

RSA 简单解密

给定 $p \ \ q \ \ e \ \ c$ 的情况下,可以直接求解。

1
2
3
4
5
6
7
8
9
10
import gmpy2
import libnum

def decodeRSA(p,q,e,c):
d= gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,p*q)
print(hex(m)[2:])
return libnum.n2s(int(m)).decode()
flag = decodeRSA(p,q,e,c)
print(flag)

RSA 共模攻击

适用情况:明文 m、模数 n 相同,公钥指数 e、密文 c 不同,gcd(e1,e2)==1[5]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import libnum
import gmpy2

def common_modulus(n, c1, c2, e1, e2):
common_d= libnum.gcd(e1, e2)
assert(common_d)
_, s1, s2 = gmpy2.gcdext(e1, e2)#扩展欧几里得算法
#若s1<0,则c1^s1==(c1^-1)^(-s1),其中c1^-1为c1模n的逆元。
if s1 < 0:
s1 = -s1
c1 = gmpy2.invert(c1, n)
if s2 < 0:
s2 = -s2
c2 = gmpy2.invert(c2, n)
m = pow(c1, s1, n)*pow(c2, s2, n)%n
# 一些e1 e2不互素的情景,若gcd(e1,e2)=2,可以尝试开2次方
if(common_d==2):
m = gmpy2.iroot(m,2)[0]
flag = libnum.n2s(int(m)).decode()
return flag

flag = common_modulus(n,c1,c2,e1,e2)
print(flag)

RSA 质因数分解

给定一个 $n$ ,或一个公钥文件则使用 openssl 提取 $n$ 。

若 $n$ 本身不是很大,则可以对其进行质因数分解,一些网站(例如factordb)有已经储存的结果供我们使用。

分解出来 $p$ 和 $q$ 在直接使用扩展欧几里得算法求出私钥 $d$ 或者用 rsatool 生成私钥,即可对加密结果进行求解。

栅栏加密

栅栏加密具体有两种,一种是竖直型,一种是 W 型。 但事实也并非如此。 很多平台栅栏加密,其实就是 W 型的。

我们就参照都知道的说法吧,给出一个竖直型的加解密代码,看了下这种的工具确实比较少:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
railFence ={
encode : (code,key)=>{
let text = ""
for(let i = 0 ; i<=key-1; i++){
for(let j =i ; j<=code.length-1; j+=key){
text += code[j];
}
}
return text
},
decode : function(code,key){
key = parseInt((code.length/key).toFixed(0))
return this.encode(code,key)
}
}

console.log(railFence.encode('R5UALCUVJDCGD63RQISZTBOSO54JVBORP5SAT2OEQCWY6CGEO53Z67L_doyouknowCaesar',4))
console.log(railFence.decode('RLJDQTOVPTQ6O6duws5CD6IB5B52CC57okCaUUC3SO4OSOWG3LynarAVGRZSJRAEYEZ_ooe',4))

常用工具网站

网站 地址 说明
CTF 在线工具 http://www.hiencode.com/ 支持很多加密形式的在线工具,界面干净
the x 工具箱 https://the-x.cn/base64 推荐他的 base64 可以识别出二进制数据
CTF Wiki https://ctf-wiki.org/ CTF 相关的知识百科
在线扫码 https://online-barcode-reader.inliteresearch.com/default.aspx
factordb http://www.factordb.com/index.php 用于 RSA 分解质因数生成私钥
CyberChef https://gchq.github.io/CyberChef 分析/解密
SoJSON https://www.sojson.com/encrypt_des.html 解密 预设偏移量
quipqiup https://quipqiup.com/ 词频分析,自动解密

未完待续

参考文章

  • [1] zip伪加密原理及操作 https://blog.csdn.net/qq_26187985/article/details/83654197
  • [2] ImageMagick 中文网 http://www.imagemagick.com.cn/
  • [3] https://stackoverflow.com/questions/33854103/why-were-javascript-atob-and-btoa-named-like-that
  • [4] Ciphey 中文文档 https://github.com/Ciphey/Ciphey/blob/master/translations/zh/README.md
  • [5] 前端 CTF中的RSA(一) 共模攻击法 https://www.dazhuanlan.com/schoolboy/topics/1025798
  • [6] https://www.qqxiuzi.cn/bianma/zhalanmima.php
  • [7] https://en.wikipedia.org/wiki/Rail_fence_cipher