题目可以在buuctf下载到
参考文献附件链接:https://pan.baidu.com/s/1RE3fcM7Bl0ZxTFix1t2myA
提取码:iuxq

起因是Root.师傅在群里问了一下这道题,说是跟exif缩略图有关,应该不难,但是解码有点困难。因为正好之前没有研究过这种题型,的确是比较有意思,而且一维码的修复和手动解码我基本从未接触过,网上也没有详细的wp,所以在此记录一下。
下载下来是一张图
delta
delta这个名字学过数学的应该都很敏感,联想到可能是图片里加了什么。

binwalk分析一手,有两张图的样子

引用知乎大神的说法,JPG图片的缩略图存放在图片的EXIF信息中
准确来说,是在Windows里,要显示一个JPG图片的缩略图,系统会先看这张图片的EXIF信息中中有没有缩略图,有就直接拿来用了(并且保存到Thumbs.db缩略图缓存中,下次就直接调用缓存中的缩略图了),没用的话才会根据图片实际图像生成缩略图。也就是说你可以自己用Exifer等EXIF编辑器自己给图片弄一个和实际图像完全不相关的缩略图
https://www.zhihu.com/question/19880552

用工具查看也可以看出图片的exif信息被修改过,不过magicexif这个工具貌似不太支持缩略图导出。试了试exifer也不能正常导出和显示。

根据Root.师傅的指导,我们可以使用exiftools工具(推荐Linux下)进行缩略图提取

exiftool -b -ThumbnailImage delta.jpg > flag.jpg

exiftool -b -ThumbnailImage image.jpg > thumbnail.jpg
Save thumbnail image from image.jpg to a file called thumbnail.jpg.
官方帮助文档

如果你仔细看提取出的缩略图,应该可以发现这一个横条上多了一些信息。

现在我们对这两张图进行范围比较,使用软件Beyond Compare(容差比较的时候也非常好用)

右键选中混合后的图片,然后复制到ps里编辑一手,拉了下曲线,颜色替换,去色等等,使图片清晰一点,然后用仿制图章工具去除了黑色的杂色色块,得到如下图

接下来就是重点部分了,对code128条码的识别(其实要是没看wp,是code128都不知道,难度就更大了)

Code128各编码方式的编码范围

1、Code128A:标准数字和字母,控制符,特殊字符;

2、Code128B:标准数字和字母,小写字母,特殊字符;

3、Code128C/EAN128:[00]-[99]的数字对集合,共100个,即只能表示偶数位长度的数字。

Code128编码规则:

开始位 + [FNC1(为EAN128码时加)] + 数据位 + 检验位 + 结束位

这个比赛的flag格式为CTF{*},所以大概率用的是128B编码

Code128编码表:

ID Code128A Code128B Code128C BandCode
0 SP SP 0 212222
1 ! ! 1 222122
2 2 222221
3 # # 3 121223
4 $ $ 4 121322
5 % % 5 131222
6 & & 6 122213
7 7 122312
8 ( ( 8 132212
9 ) ) 9 221213
10 * * 10 221312
11 + + 11 231212
12 , , 12 112232
13 - - 13 122132
14 . . 14 122231
15 / / 15 113222
16 0 0 16 123122
17 1 1 17 123221
18 2 2 18 223211
19 3 3 19 221132
20 4 4 20 221231
21 5 5 21 213212
22 6 6 22 223112
23 7 7 23 312131
24 8 8 24 311222
25 9 9 25 321122
26 : : 26 321221
27 ; ; 27 312212
28 < < 28 322112
29 = = 29 322211
30 > > 30 212123
31 ? ? 31 212321
32 @ @ 32 232121
33 A A 33 111323
34 B B 34 131123
35 C C 35 131321
36 D D 36 112313
37 E E 37 132113
38 F F 38 132311
39 G G 39 211313
40 H H 40 231113
41 I I 41 231311
42 J J 42 112133
43 K K 43 112331
44 L L 44 132131
45 M M 45 113123
46 N N 46 113321
47 O O 47 133121
48 P P 48 313121
49 Q Q 49 211331
50 R R 50 231131
51 S S 51 213113
52 T T 52 213311
53 U U 53 213131
54 V V 54 311123
55 W W 55 311321
56 X X 56 331121
57 Y Y 57 312113
58 Z Z 58 312311
59 [ [ 59 332111
60 \ \ 60 314111
61 ] ] 61 221411
62 ^ ^ 62 431111
63 _ _ 63 111224
64 NUL ` 64 111422
65 SOH a 65 121124
66 STX b 66 121421
67 ETX c 67 141122
68 EOT d 68 141221
69 ENQ e 69 112214
70 ACK f 70 112412
71 BEL g 71 122114
72 BS h 72 122411
73 HT i 73 142112
74 LF j 74 142211
75 VT k 75 241211
76 FF I 76 221114
77 CR m 77 413111
78 SO n 78 241112
79 SI o 79 134111
80 DLE p 80 111242
81 DC1 q 81 121142
82 DC2 r 82 121241
83 DC3 s 83 114212
84 DC4 t 84 124112
85 NAK u 85 124211
86 SYN v 86 411212
87 ETB w 87 421112
88 CAN x 88 421211
89 EM y 89 212141
90 SUB z 90 214121
91 ESC { 91 412121
92 FS | 92 111143
93 GS } 93 111341
94 RS ~ 94 131141
95 US DEL 95 114113
96 FNC3 FNC3 96 114311
97 FNC2 FNC2 97 411113
98 SHIFT SHIFT 98 411311
99 CODEC CODEC 99 113141
100 CODEB FNC4 CODEB 114131
101 FNC4 CODEA CODEA 311141
102 FNC1 FNC1 FNC1 411131
103 StartA StartA StartA 211412
104 StartB StartB StartB 211214
105 StartC StartC StartC 211232
106 Stop Stop Stop 2331112

尝试使用zxing库进行解码,但是因为太过于“抽象”导致根本扫不出来,只能手工读取,那么要如何读取呢?我琢磨半天都没研究出来,就卡住了

可以参考以下的GB/T 15425-2014 商品条码 128条码国标文档(已放置在开头的附件中,也可在以下网址自行下载)

http://www.eshian.com/standards/36639.html

非常形象生动,使用字符C进行举例。
一个字符会使用11个条、空进行排列,(也就是黑白)第11个空除STOP字符为黑块外,其它字符均为白条。
圈出来的这一行意思是符号字符值35code字符集A\B\C代表的ASCII值均为C,这里条块顺序为1黑3白1黑3白2黑1白,故此C的排列编号为131321(交替读取黑白条块数目,最小为1,最大为4)

还记得前文我们说过code128B的编码规则

开始位 + 数据位 + 检验位 + 结束位

开始位为start,模块数211214

终止位为stop,模块数2331112

全部读取如下(上方为黑色区块的模块数,下方为白色区块的模块数,读取方法为一上一下交替,除终止字符外一组6个模块数)

原图尺寸比较小还请见谅,可以保存下来看
211214 --> start
131321 --> C
213311 --> T
132311 --> F
412121 --> {
413111 --> m
142112 --> i
241112 --> n
142112 --> i
413111 --> m
112214 --> e
122231 --> . (`.`这里有点坑,英文是`.`,中文是`。`)
142211 --> j
111242 --> p
122114 --> g
111341 --> }
121241 --> r
2331112--> stop
#CTF{minime.jpg},忽略那个r

得到flag{minime.jpg}


参考文献:

Code128 编码规则_C/C++_walk_ing的博客-CSDN博客
Code128简介:Code128码于1981年推出,是一种长度可变、连续性的字母数字条码。与其他一C/C++