张麦麦

个人 CTF 常用工具使用 & 初学经验整理

· 16min· CTF·#Web#逆向#JavaScript#Python

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

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

Misc

杂项,啥都有。

压缩包处理

爆破 John the Ripper

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

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

macOS 安装方法 / 问题解决

首先直接上 Homebrew 大法,没有的可以搜下安装方法。john-jumbo 是其增强版

Terminal window
1
brew install john-jumbo

安装后可以使用 john 命令验证。 但是使用 zip2john 命令时,发现并没有找到命令。

google后,发现是因为Homebrew的环境变量只到bin目录下,但是zip2john在比较深的目录下,因此需要手工添加环境变量。

根据原文提示有些问题,因为查看 john 目录下 zip2john 是一替身,且无二级目录。而且也有其他类似命令需要配置到环境变量。因此直接添加上级目录到.zshrc 之类的文件即可。

如果你是 john 而非 john-jumbo 则找到对应目录添加就行。

Terminal window
1
export PATH="/opt/Homebrew/Cellar/john-jumbo/1.9.0/share/john:$PATH"

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

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

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

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

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

ZIP 伪加密

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

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

2.对于 zip 使用工具 ZipCenOp

用法很简单:

Terminal window
1
#(r : 恢复 zip,e : 制作伪加密)
2
java -jar ZipCenOp.jar <option> <file>

3.手动修改 hex [1]

以这个压缩包的 hex 为例:

1
504B0304 14000008 0800F7B2 5E537699 13D61600 00001400
2
00000800 10007465 73742E74 78745558 0C007855 7D617155
3
7D61F501 14004BCB 494CAF2E C9C82C8E F72C8E4F 8C77334C
4
4CAF0500 504B0102 14031400 00080800 F7B25E53 769913D6
5
16000000 14000000 08000C00 00000000 00002000 A4810000
6
00007465 73742E74 78745558 08007855 7D617155 7D61504B
7
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

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

安装:

Terminal window
1
git clone https://github.com/devttys0/binwalk
2
cd binwalk
3
python setup.py install
Terminal window
1
binwalk file 分析文件
2
binwalk -e file 分析并解压文件
3
binwalk -D=jpeg pcat.bin 分解文件
4
binwalk -eM pcat.bin 递归分解 需要配合其他指令

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

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

数据提取 / 恢复 foremost

https://github.com/korczis/foremost

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

安装方法:

GNU/Linux

Kali Linux 自带!

apt 安装

Terminal window
1
sudo apt-get install foremost

git 安装

Terminal window
1
git clone https://github.com/korczis/foremost.git
2
cd foremost
3
make
4
make install
macOS
Terminal window
1
brew install foremost
Windows

直接下载: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

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

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

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

图片/音乐隐写 steghide

很老的一个隐写工具了。

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

安装方法:

GNU/Linux

apt 安装

Terminal window
1
sudo apt-get install steghide
macOS

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

MacPorts 我的超人 :(

Terminal window
1
sudo port install steghide
Windows

直接下载: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 图像 和拼合功能。

Terminal window
1
convert glance.gif flag.png # 将 gif 转为图像序列

安装方法:

GNU/Linux
Terminal window
1
sudo apt-get install imagemagick
macOS
Terminal window
1
brew install imagemagick
2
# 可能还需要
3
# brew install ghostscript`
Windows

直接下载:http://www.imagemagick.com.cn/download.html

流量分析

Wireshark 没啥好说

比较常用的:

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

2.右键,追踪流。

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

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

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

Crypto

各种加密~

进制转换/编码解码

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

base64 字符串互转

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

任意进制互转

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

ASCII 码文本互转

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

Hex/String 互转

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

Urlcode 编码

1
encodeURIComponent('张麦麦的博客');
2
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

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

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

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

最平凡的使用方法

Terminal window
1
ciphey -t "encrypted_message"

很多解密情况不适用……

RSA 加密

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

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

RSA 加解密文件 openssl

使用 key 解密

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

使用私钥解密

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

从公钥查看 n e

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

RSA综合工具 RSAtool

使用 RSAtool 生成私钥

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

RSA 简单解密

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

1
import gmpy2
2
import libnum
3
4
def decodeRSA(p,q,e,c):
5
d= gmpy2.invert(e,(p-1)*(q-1))
6
m = pow(c,d,p*q)
7
print(hex(m)[2:])
8
return libnum.n2s(int(m)).decode()
9
flag = decodeRSA(p,q,e,c)
10
print(flag)

RSA 共模攻击

适用情况:明文 mm、模数 nn 相同,公钥指数 ee、密文 cc 不同,gcd(e1,e2)=1gcd(e_1,e_2)=1 [4]

1
import libnum
2
import gmpy2
3
4
def common_modulus(n, c1, c2, e1, e2):
5
common_d= libnum.gcd(e1, e2)
6
assert(common_d)
7
_, s1, s2 = gmpy2.gcdext(e1, e2)#扩展欧几里得算法
8
#若s1<0,则c1^s1==(c1^-1)^(-s1),其中c1^-1为c1模n的逆元。
9
if s1 < 0:
10
s1 = -s1
11
c1 = gmpy2.invert(c1, n)
12
if s2 < 0:
13
s2 = -s2
14
c2 = gmpy2.invert(c2, n)
15
m = pow(c1, s1, n)*pow(c2, s2, n)%n
16
# 一些e1 e2不互素的情景,若gcd(e1,e2)=2,可以尝试开2次方
17
if(common_d==2):
18
m = gmpy2.iroot(m,2)[0]
19
flag = libnum.n2s(int(m)).decode()
20
return flag
21
22
flag = common_modulus(n,c1,c2,e1,e2)
23
print(flag)

RSA 质因数分解

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

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

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

栅栏加密

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

栅栏密码到底是啥

我们先看下 “千千秀字”[5] 的说法(事实上,也是大多数网站的说法):

明文:栅栏密码加密规则示例 每组字数:5

按照字数先把明文分成: 栅栏密码加 密规则示例

先取每组第一个字:栅密 再取每组第二个字:栏规 ……

最后得到“栅密栏规密则码示加例”

我们再看一下维基百科的说法[6]

例如我们使用三栏加密:“ WE ARE DISCOVERED. RUN AT ONCE. ” ,结果如下:

1
W . . . E . . . C . . . R . . . U . . . O . . .
2
. E . R . D . S . O . E . E . R . N . T . N . E
3
. . A . . . I . . . V . . . D . . . A . . . C .

如果你熟悉栅栏加密,你会发现:诶?这不是“ W 型 ”栅栏加密吗?

然后我们查看很多在线工具,发现他们的加密结果也确实是这个 W 型 的。也就是,这个 所谓 W 型栅栏加密,很可能才是原版的栅栏加密。虽然说对于竖着排列的所谓栅栏密码有许多介绍,但是大多数解密工具,似乎也都是 W 型的。

那么第一种提到的所谓的栅栏密码到底是啥呢? 他很可能是:Route cipher(姑且翻译为:路由密码吧)的一个变种。或者其他什么。 这里我不对他做太多的考究了。

我简单搜索了一下,基本是06、07年时间节点出现的这种说法。

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

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

常用工具网站

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

未完待续

参考文章