-
-
[原创]2020网鼎杯 白虎组 b64 精析
-
发表于: 2021-6-11 10:02 14401
-
不懂出题的师傅是哪位,但猜测很大可能性不超过25岁。
最近又在搞CTF,但看着余弦等大佬都已转战区块链领域良久,不觉心慌慌,感觉自己再亿次被时代抛弃。
题目很简练,类型:Crypto,最终解出人数是300队以内。
下载打开看是
密文:uLdAuO8duojAFLEKjIgdpfGeZoELjJp9kSieuIsAjJ/LpSXDuCGduouz
泄露的密文:pTjMwJ9WiQHfvC+eFCFKTBpWQtmgjopgqtmPjfKfjSmdFLpeFf/Aj2ud3tN7u2+enC9+nLN8kgdWo29ZnCrOFCDdFCrOFoF=
泄露的明文:ashlkj!@sj1223%^&*Sd4564sd879s5d12f231a46qwjkd12J;DJjl;LjL;KJ8729128713
几乎15分钟内就能看出,“泄露的密文”可能是个类似Base64的东西,把“泄露的明文”转换成base64编码看看:
注意:FoF=和MTM=
与泄露的密文对比后发现最后四位长得很像,猜测最后3位的加密过程肯定是M--->F,T---->o。
初步想法是先把“密文”按照替换法替换成明文(要注意Excel某些时候不区分大小写,不要直接Vlookup):
解释:假如 D2和A:A列的某个项一致,则返回B:B列相应的项
至于1,0,Lookup啥意思,不知道。
明文的前半部分是不是很熟?基本上flag 的base64开头就是ZmxhZ
base64解码:flag{1e3a2。那接下来就很明显了。爆破下面六个字符对应的字母就可以了。
EIGsXz
我们知道base64的字典一般是大小写字母和数字,加号和斜杠组成(共计64个)
如果用python写就是
这个字典里要去掉参考明文的所有字母(这里需要思考一下),原因是:
参考密文当中不包含EIGsXz,假如 EIGsXz作为密文,明文肯定不是参考明文当中的字符。
所以字典64个字符要减掉参考明文中42个字符(注:不可用Excel 的自动去重功能,因为没区分大小写),共计22个。
同时又知道python有个解base64的包。
所以可以直接爆破了(引入个进度条,不然等待很绝望)记得要是
这一串是排列的意思,其实就是A22,6(22个字符中选择6个,有53721360种可能)。这个数字用于设计进度条。
一般盲猜的base64解密,会出一堆乱码字符
所以前面一般加个可打印字符判断,如果是乱码直接下一个尝试了
然后再写个正则验证flag的符合性(根据其他题的flag,格式一般是)。
因为要打出以下这串:
所以加了个代码
跑的效果是这样:
大概5分钟内能跑完。
(共计可能有21个flag)
要解这题门道还是挺多的,以下方面要快速知道并投入使用:
1、 python解base64
2、正则表达式
3、字符串快速转置去重分析
4、进度条设计
5、排列组合知识
6、基本是盲猜,连base64原理是什么都可以不用知道。但知道一下base64原理也挺好。
VLOOKUP函数不能区分大小写,该如何查找匹配?
https://cloud.tencent.com/developer/news/594528
https://github.com/8gg/BlogFile/issues/1
1、深入研究Excel Lookup如何匹配大小写
2、研究 Base64原理
YXNobGtqIUBzajEyMjMlXiYqU2Q0NTY0c2Q4NzlzNWQxMmYyMzFhNDZxd2prZDEySjtESmpsO0xqTDtLSjg3MjkxMjg3MTM
=
YXNobGtqIUBzajEyMjMlXiYqU2Q0NTY0c2Q4NzlzNWQxMmYyMzFhNDZxd2prZDEySjtESmpsO0xqTDtLSjg3MjkxMjg3MTM
=
=
LOOKUP(
1
,
0
/
EXACT(A:A,D2),B:B)
=
LOOKUP(
1
,
0
/
EXACT(A:A,D2),B:B)
import
string
string.letters
+
string.digits
+
'+/'
import
string
string.letters
+
string.digits
+
'+/'
#用未被映射的字符构造字典
newDic
=
''
for
x
in
dic:
if
(x
not
in
b ):
newDic
+
=
x
#用未被映射的字符构造字典
newDic
=
''
for
x
in
dic:
if
(x
not
in
b ):
newDic
+
=
x
import
base64
base64.b64decode(
'ZmxhZ3sxZTNhMm'
)
import
base64
base64.b64decode(
'ZmxhZ3sxZTNhMm'
)
pip install progressbar2。
pip install progressbar2。
bar
=
progressbar.ProgressBar(max_value
=
scipy.special.perm(
len
(newDic),
len
(unknow)))
bar
=
progressbar.ProgressBar(max_value
=
scipy.special.perm(
len
(newDic),
len
(unknow)))
dic1
=
newDic
for
E
in
newDic:
dic2
=
dic1.replace(E,'')
for
G
in
dic2:
dic3
=
dic2.replace(G,'')
for
I
in
dic3:
dic4
=
dic3.replace(I,'')
for
s
in
dic4:
dic5
=
dic4.replace(s,'')
for
X
in
dic5:
dic6
=
dic5.replace(X,'')
for
z
in
dic6:
result
=
'ZmxhZ3sxZTNhMm{E}lN{I}0xYz{G}yLT{E}mNGYtOWIyZ{I}{s}hNGFmYW{X}kZj{G}xZTZ{z}'
.
format
(E
=
E,G
=
G,I
=
I,s
=
s,X
=
X,z
=
z)
# '............. . E .. I .... G ... E ......... .Is..... .X ... G......z'
# ZmxhZ3sxZTNhMm{E}lN{I}0xYz{G}yLT{E}mNGYtOWIyZ{I}{s}hNGFmYW{X}kZj{G}xZTZ{z}
count
+
=
1
#进度条
bar.update(count)
combineAndDecode(result)
dic1
=
newDic
for
E
in
newDic:
dic2
=
dic1.replace(E,'')
for
G
in
dic2:
dic3
=
dic2.replace(G,'')
for
I
in
dic3:
dic4
=
dic3.replace(I,'')
for
s
in
dic4:
dic5
=
dic4.replace(s,'')
for
X
in
dic5:
dic6
=
dic5.replace(X,'')
for
z
in
dic6:
result
=
'ZmxhZ3sxZTNhMm{E}lN{I}0xYz{G}yLT{E}mNGYtOWIyZ{I}{s}hNGFmYW{X}kZj{G}xZTZ{z}'
.
format
(E
=
E,G
=
G,I
=
I,s
=
s,X
=
X,z
=
z)
# '............. . E .. I .... G ... E ......... .Is..... .X ... G......z'
# ZmxhZ3sxZTNhMm{E}lN{I}0xYz{G}yLT{E}mNGYtOWIyZ{I}{s}hNGFmYW{X}kZj{G}xZTZ{z}
count
+
=
1
#进度条
bar.update(count)
combineAndDecode(result)
scipy.special.perm(
len
(newDic),
len
(unknow))
scipy.special.perm(
len
(newDic),
len
(unknow))
flag
=
base64.b64decode(result)
for
x
in
flag:
if
(x
not
in
string.printable):
flag
=
''
break
flag
=
base64.b64decode(result)
for
x
in
flag:
if
(x
not
in
string.printable):
flag
=
''
break
re.findall(r
'flag{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}'
,flag)
re.findall(r
'flag{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}'
,flag)
ZmxhZ3sxZTNhMm{E}lN{I}
0xYz
{G}yLT{E}mNGYtOWIyZ{I}{s}hNGFmYW{X}kZj{G}xZTZ{z}
ZmxhZ3sxZTNhMm{E}lN{I}
0xYz
{G}yLT{E}mNGYtOWIyZ{I}{s}hNGFmYW{X}kZj{G}xZTZ{z}
for
x
in
m:
if
(a.find(x)
=
=
-
1
):
n
+
=
'{'
+
x
+
'}'
unknow
+
=
x
maskM
+
=
x
for
x
in
m:
if
(a.find(x)
=
=
-
1
):
n
+
=
'{'
+
x
+
'}'
unknow
+
=
x
maskM
+
=
x
# -*- coding: utf-8 -*-
import
requests
import
sys
import
string
import
base64
import
re
import
progressbar
import
scipy.special
reload
(sys)
sys.setdefaultencoding(
'utf8'
)
#a(cypher_base64)--->b(plain_base64)
a
=
'pTjMwJ9WiQHfvC+eFCFKTBpWQtmgjopgqtmPjfKfjSmdFLpeFf/Aj2ud3tN7u2+enC9+nLN8kgdWo29ZnCrOFCDdFCrOFoF='
b
=
'YXNobGtqIUBzajEyMjMlXiYqU2Q0NTY0c2Q4NzlzNWQxMmYyMzFhNDZxd2prZDEySjtESmpsO0xqTDtLSjg3MjkxMjg3MTM='
#m(cypher_base64)--->n(target_base64)
m
=
'uLdAuO8duojAFLEKjIgdpfGeZoELjJp9kSieuIsAjJ/LpSXDuCGduouz'
# ZmxhZ3sxZTNhMm.lN.0xYz.yLT.mNGYtOWIyZ..hNGFmYW.kZj.xZTZ.
n
=
''
maskM
=
''
unknow
=
''
dic
=
string.letters
+
string.digits
+
'+'
+
'/'
#用未被映射的字符构造字典
newDic
=
''
for
x
in
dic:
if
(x
not
in
b ):
newDic
+
=
x
print
"newDic:"
+
str
(
len
(newDic))
print
"newDic:"
+
newDic
for
x
in
m:
if
(a.find(x)
=
=
-
1
):
n
+
=
'{'
+
x
+
'}'
unknow
+
=
x
maskM
+
=
x
else
:
n
+
=
b[a.find(x)]
maskM
+
=
'.'
print
m
print
maskM
print
n
#未知字符
unknow
=
"".join(
set
(
list
(unknow)))
def
combineAndDecode(result):
try
:
flag
=
base64.b64decode(result)
#flag='flag{1e3a2de4-1c02-4f4f-9b2d-a4afabdf01e6}'
for
x
in
flag:
if
(x
not
in
string.printable):
flag
=
''
break
if
(
len
(re.findall(r
'flag{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}'
,flag))>
0
):
#print flag
with
open
(
'results.txt'
,
'a+'
) as f:
f.write(result
+
'\n'
)
f.write(flag
+
'\n'
)
#pass
except
Exception as e:
pass
count
=
0
bar
=
progressbar.ProgressBar(max_value
=
scipy.special.perm(
len
(newDic),
len
(unknow)))
dic1
=
newDic
for
E
in
newDic:
dic2
=
dic1.replace(E,'')
for
G
in
dic2:
dic3
=
dic2.replace(G,'')
for
I
in
dic3:
dic4
=
dic3.replace(I,'')
for
s
in
dic4:
dic5
=
dic4.replace(s,'')
for
X
in
dic5:
dic6
=
dic5.replace(X,'')
for
z
in
dic6:
result
=
'ZmxhZ3sxZTNhMm{E}lN{I}0xYz{G}yLT{E}mNGYtOWIyZ{I}{s}hNGFmYW{X}kZj{G}xZTZ{z}'
.
format
(E
=
E,G
=
G,I
=
I,s
=
s,X
=
X,z
=
z)
# '............. . E .. I .... G ... E ......... .Is..... .X ... G......z'
# ZmxhZ3sxZTNhMm{E}lN{I}0xYz{G}yLT{E}mNGYtOWIyZ{I}{s}hNGFmYW{X}kZj{G}xZTZ{z}
count
+
=
1
#进度条
bar.update(count)
combineAndDecode(result)
# -*- coding: utf-8 -*-
import
requests
import
sys
import
string
import
base64
import
re
import
progressbar
import
scipy.special
reload
(sys)
sys.setdefaultencoding(
'utf8'
)
#a(cypher_base64)--->b(plain_base64)
a
=
'pTjMwJ9WiQHfvC+eFCFKTBpWQtmgjopgqtmPjfKfjSmdFLpeFf/Aj2ud3tN7u2+enC9+nLN8kgdWo29ZnCrOFCDdFCrOFoF='
b
=
'YXNobGtqIUBzajEyMjMlXiYqU2Q0NTY0c2Q4NzlzNWQxMmYyMzFhNDZxd2prZDEySjtESmpsO0xqTDtLSjg3MjkxMjg3MTM='
#m(cypher_base64)--->n(target_base64)
m
=
'uLdAuO8duojAFLEKjIgdpfGeZoELjJp9kSieuIsAjJ/LpSXDuCGduouz'
# ZmxhZ3sxZTNhMm.lN.0xYz.yLT.mNGYtOWIyZ..hNGFmYW.kZj.xZTZ.
n
=
''
maskM
=
''
unknow
=
''
dic
=
string.letters
+
string.digits
+
'+'
+
'/'
#用未被映射的字符构造字典
newDic
=
''
for
x
in
dic:
if
(x
not
in
b ):
newDic
+
=
x